|  | // 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; | 
|  | } | 
|  |  |