| // Linux NPTL 2.3.2 | 
 | complex list_head { | 
 | 	'X'	0	next; | 
 | 	'X'	4	prev; | 
 | }; | 
 | complex nptl_pthread { | 
 | 	'X'	0	loopback; | 
 | 	'X'	0x48	tid; | 
 | }; | 
 |  | 
 | // cannot be done at load time -- need shared library symbols | 
 | defn guessnptl() { | 
 | 	if var("nptl_version") then { | 
 | 		pthreadlibrary = "nptl"; | 
 | 		isnptl = 1; | 
 | 	} else { | 
 | 		pthreadlibrary = "linuxclone"; | 
 | 		isnptl = 0; | 
 | 	} | 
 | } | 
 |  | 
 | defn pthread2tid(p) { | 
 | 	guessnptl(); | 
 | 	if p == 0 then | 
 | 		return 0; | 
 | 	if isnptl then { | 
 | 		complex nptl_pthread p; | 
 | 		if p.loopback != p then | 
 | 			error("bad pthread "+itoa(p, "%x")); | 
 | 		return p.tid; | 
 | 	}else { | 
 | 		return p\X; | 
 | 	} | 
 | } | 
 |  | 
 | defn pthreadlist() { | 
 | 	local all, p, n, l; | 
 |  | 
 | 	if isnptl then { | 
 | 		all = {}; | 
 | 		l = (list_head)stack_used; | 
 | 		l = (list_head)l.next; | 
 | 		while l != stack_used do { | 
 | 			p = l - *_thread_db_pthread_list; | 
 | 			all = append all, p; | 
 | 			l = (list_head)l.next; | 
 | 		} | 
 | 	} else { | 
 | 		all = {}; | 
 | 	} | 
 | 	return all; | 
 | } | 
 | 		 |