47066d90cfc570ff54cb53f61467d3a896af519d
[platform/core/system/swap-probe.git] / probe_thread / libdathread.c
1 /*
2  *  DA probe
3  *
4  * Copyright 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Woojin Jung <woojin2.jung@samsung.com>
9  * Jaewon Lim <jaewon81.lim@samsung.com>
10  * Juyoung Kim <j0.kim@samsung.com>
11  *
12  * This library is free software; you can redistribute it and/or modify it under
13  * the terms of the GNU Lesser General Public License as published by the
14  * Free Software Foundation; either version 2.1 of the License, or (at your option)
15  * any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
18  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this library; if not, write to the Free Software Foundation, Inc., 51
24  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  *
29  */
30
31 #include <pthread.h>
32 #include <errno.h>
33 #include "daprobe.h"
34 #include "probeinfo.h"
35 #include "dahelper.h"
36 #include "da_thread.h"
37
38 #include "binproto.h"
39
40 typedef struct thread_routine_call_t {
41         void *(*thread_routine)(void *);
42         void *argument;
43 } thread_routine_call;
44
45 static enum DaOptions _sopt = OPT_THREAD;
46
47 // called when pthread_exit, pthread_cancel is called
48 void _da_cleanup_handler(void *data)
49 {
50         pthread_t pSelf;
51
52         probeInfo_t     probeInfo; log_t log;
53         INIT_LOG;
54         
55         PRE_UNCONDITIONAL_BLOCK_BEGIN();
56         APPEND_LOG_BASIC(LC_THREAD);
57         // input,ret,PCAddr,errno,InternalCall,CallerPCAddr
58         log.length += sprintf(log.data + log.length, "`,`,`,0`,0`,1`,0");
59         pSelf = pthread_self();
60         log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
61                         pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
62         APPEND_LOG_NULL_CALLSTACK();
63         printLog(&log, MSG_LOG);
64         
65         PREPARE_LOCAL_BUF();
66         PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", data);
67         PACK_COMMON_END(0, 0, 1);
68         PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
69         FLUSH_LOCAL_BUF();
70         
71         PRE_UNCONDITIONAL_BLOCK_END();
72
73         return;
74 }
75
76 void *_da_ThreadProc(void *params)
77 {
78         void *ret;
79         thread_routine_call *ptrc;
80         ptrc = (thread_routine_call *) params;
81         pthread_t pSelf;
82
83         probeInfo_t     probeInfo; log_t log;
84
85         // send INTERNAL_START log
86         INIT_LOG;
87
88         PRE_UNCONDITIONAL_BLOCK_BEGIN();
89         APPEND_LOG_BASIC(LC_THREAD);
90         // input,ret,PCAddr,errno,InternalCall,CallerPCAddr
91         log.length += sprintf(log.data + log.length, "`,`,`,0`,0`,1`,0");
92         pSelf = pthread_self();
93         log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
94                         pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_START);
95         APPEND_LOG_NULL_CALLSTACK();
96         printLog(&log, MSG_LOG);
97         
98         PREPARE_LOCAL_BUF();
99         PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", params);
100         PACK_COMMON_END(0, 0, 1);
101         PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_START);
102         FLUSH_LOCAL_BUF();
103         
104         PRE_UNCONDITIONAL_BLOCK_END();
105
106         pthread_cleanup_push(_da_cleanup_handler, NULL);
107         // call user-defined thread routine
108         ret = ptrc->thread_routine(ptrc->argument);
109         pthread_cleanup_pop(0);
110
111         // send INTERNAL_STOP log
112         INIT_LOG;
113
114         PRE_UNCONDITIONAL_BLOCK_BEGIN();
115         APPEND_LOG_BASIC(LC_THREAD);
116         // input,ret,PCAddr,errno,InternalCall,CallerPCAddr
117         log.length += sprintf(log.data + log.length, "`,`,`,0`,0`,1`,0");
118         pSelf = pthread_self();
119         log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
120                         pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
121         APPEND_LOG_NULL_CALLSTACK();
122         printLog(&log, MSG_LOG);
123         
124         PREPARE_LOCAL_BUF();
125         PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", params);
126         PACK_COMMON_END(ret, 0, 1);
127         PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
128         FLUSH_LOCAL_BUF();
129         
130         PRE_UNCONDITIONAL_BLOCK_END();
131         
132         free(ptrc);
133         return ret;
134 }
135
136 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
137                 void *(*start_routine) (void*), void *arg)
138 {
139         static int (*pthread_createp)(pthread_t *thread,
140                         const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
141
142         BEFORE_ORIGINAL_THREAD(pthread_create, LIBPTHREAD);
143
144         if(blockresult)
145         {
146                 probeBlockStart();      
147                 thread_routine_call *ptrc = 
148                         (thread_routine_call *) malloc(sizeof(thread_routine_call));
149                 ptrc->thread_routine = start_routine;
150                 ptrc->argument = arg;
151                 probeBlockEnd();
152
153                 ret = pthread_createp(thread, attr, _da_ThreadProc, (void *) ptrc);
154         }
155         else // when pthread_create is called inside probe so (ex. custom chart, sampling thread)
156         {
157                 ret = pthread_createp(thread, attr, start_routine, arg);
158         }
159
160         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, *thread, THREAD_API_START, 
161                         "%p,%p,%p,%p", thread, attr, start_routine, arg);
162
163         AFTER_PACK_ORIGINAL_THREAD(ret, *thread, THREAD_API_START, 
164                         "pppp", thread, attr, start_routine, arg);
165
166         return ret;
167 }
168
169 int pthread_join(pthread_t thread, void **retval)
170 {
171         static int (*pthread_joinp)(pthread_t thread, void **retval);
172
173         DECLARE_VARIABLE_STANDARD; log_t log;
174         GET_REAL_FUNC(pthread_join, LIBPTHREAD);
175
176         PRE_PROBEBLOCK_BEGIN();
177         // send WAIT_START log
178         INIT_LOG;
179         APPEND_LOG_BASIC(LC_THREAD);
180         APPEND_LOG_INPUT("%lu,%p", thread, retval);
181         //ret,PCAddr,errno,InternalCall
182         log.length += sprintf(log.data + log.length, "`,`,0`,0`,%d", blockresult);
183         APPEND_LOG_CALLER();
184         log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d", thread, 
185                         THREAD_PTHREAD, THREAD_API_WAIT_START);
186         APPEND_LOG_NULL_CALLSTACK();
187         printLog(&log, MSG_LOG);
188         
189         PREPARE_LOCAL_BUF();
190         PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "xp", thread, retval);
191         PACK_COMMON_END(0, 0, blockresult);
192         PACK_THREAD(thread, THREAD_PTHREAD, THREAD_API_WAIT_START);
193         FLUSH_LOCAL_BUF();
194         
195         PRE_PROBEBLOCK_END();
196
197         ret = pthread_joinp(thread, retval);
198
199         // send WAIT_END log
200         newerrno = errno;
201         if(postBlockBegin(blockresult)) {
202                 setProbePoint(&probeInfo);
203                 INIT_LOG;
204                 APPEND_LOG_BASIC(LC_THREAD);
205                 APPEND_LOG_INPUT("%lu,%p", thread, retval);
206                 APPEND_LOG_RESULT(VT_INT, ret);
207                 APPEND_LOG_CALLER();
208
209                 POST_PROBEBLOCK_MIDDLE_THREAD(thread, THREAD_API_WAIT_END);
210                 POST_PROBEBLOCK_CALLSTACK();
211                 printLog(&log, MSG_LOG);
212                 
213                 PREPARE_LOCAL_BUF();
214                 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "xp", thread, retval);
215                 PACK_COMMON_END(ret, errno, blockresult);
216                 PACK_THREAD(thread, THREAD_PTHREAD, THREAD_API_WAIT_END);
217                 FLUSH_LOCAL_BUF();
218         
219                 postBlockEnd();
220         }
221         
222         return ret;     
223 }
224
225 void pthread_exit(void *retval)
226 {
227         pthread_t pSelf;
228         static void (*pthread_exitp)(void *retval) __attribute__((noreturn));
229
230         DECLARE_VARIABLE_STANDARD; log_t log;
231         GET_REAL_FUNC(pthread_exit, LIBPTHREAD);
232
233         PRE_PROBEBLOCK_BEGIN();
234         newerrno = 0;
235         INIT_LOG;
236         APPEND_LOG_BASIC(LC_THREAD);
237         APPEND_LOG_INPUT("%p", retval);
238         //ret,PCAddr,errno,InternalCall
239         log.length += sprintf(log.data + log.length, "`,`,0`,0`,%d", blockresult);
240         APPEND_LOG_CALLER();
241         pSelf = pthread_self();
242         log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
243                         pSelf, THREAD_PTHREAD, THREAD_API_EXIT);
244         APPEND_LOG_NULL_CALLSTACK();
245         printLog(&log, MSG_LOG);
246         
247         PREPARE_LOCAL_BUF();
248         PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", retval);
249         PACK_COMMON_END(0, 0, blockresult);
250         PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_EXIT);
251         FLUSH_LOCAL_BUF();
252         
253         PRE_PROBEBLOCK_END();
254
255         pthread_exitp(retval);
256 }
257
258 int pthread_cancel(pthread_t thread)
259 {
260         static int (*pthread_cancelp)(pthread_t thread);
261
262         BEFORE_ORIGINAL_THREAD(pthread_cancel, LIBPTHREAD);
263
264         ret = pthread_cancelp(thread);
265         
266         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_STOP, "%lu", thread);
267
268         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_STOP, "x", thread);
269
270         return ret;
271 }
272
273 int pthread_detach(pthread_t thread)
274 {
275         static int (*pthread_detachp)(pthread_t thread);
276
277         BEFORE_ORIGINAL_THREAD(pthread_detach, LIBPTHREAD);
278
279         ret = pthread_detachp(thread);
280         
281         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, "%lu", thread);
282
283         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, "x", thread);
284
285         return ret;
286 }
287
288 pthread_t pthread_self(void)
289 {
290         pthread_t ret_pthr;
291         static pthread_t (*pthread_selfp)(void);
292
293         BEFORE_ORIGINAL_THREAD(pthread_self, LIBPTHREAD);
294
295         ret_pthr = pthread_selfp();
296         
297         newerrno = errno;
298         if(postBlockBegin(blockresult)) {
299                 INIT_LOG;
300                 APPEND_LOG_BASIC(LC_THREAD);
301                 log.length += sprintf(log.data + log.length, "`,");
302                 APPEND_LOG_RESULT(VT_ULONG, ret_pthr);
303                 APPEND_LOG_CALLER();
304
305                 POST_PROBEBLOCK_MIDDLE_THREAD(ret_pthr, THREAD_API_OTHER);
306                 POST_PROBEBLOCK_CALLSTACK();
307                 printLog(&log, MSG_LOG);
308
309                 AFTER_PACK_ORIGINAL_THREAD(ret_pthr, ret_pthr, THREAD_API_OTHER, "", 0);
310
311                 postBlockEnd();
312         }
313
314         return ret_pthr;
315 }
316
317 int pthread_equal(pthread_t t1, pthread_t t2)
318 {
319         static int (*pthread_equalp)(pthread_t t1, pthread_t t2);
320
321         BEFORE_ORIGINAL_THREAD(pthread_equal, LIBPTHREAD);
322
323         ret = pthread_equalp(t1, t2);
324         
325         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, t1, THREAD_API_OTHER, "%lu,%lu", t1, t2);
326
327         AFTER_PACK_ORIGINAL_THREAD(ret, t1, THREAD_API_OTHER, "xx", t1, t2);
328
329         return ret;
330 }
331
332 int pthread_setcancelstate(int state, int *oldstate)
333 {
334         pthread_t pSelf;
335         static int (*pthread_setcancelstatep)(int state, int *oldstate);
336
337         BEFORE_ORIGINAL_THREAD(pthread_setcancelstate, LIBPTHREAD);
338
339         pSelf = pthread_self();
340         ret = pthread_setcancelstatep(state, oldstate);
341
342         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, pSelf, THREAD_API_OTHER, 
343                         "%d,%p", state, oldstate);
344
345         AFTER_PACK_ORIGINAL_THREAD(ret, pSelf, THREAD_API_OTHER, 
346                         "dp", state, oldstate);
347
348         return ret;
349 }
350
351 int pthread_setcanceltype(int type, int *oldtype)
352 {
353         pthread_t pSelf;
354         static int (*pthread_setcanceltypep)(int type, int *oldtype);
355
356         BEFORE_ORIGINAL_THREAD(pthread_setcanceltype, LIBPTHREAD);
357
358         pSelf = pthread_self();
359         ret = pthread_setcanceltypep(type, oldtype);
360
361         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, pSelf, THREAD_API_OTHER, 
362                         "%d,%p", type, oldtype);
363
364         AFTER_PACK_ORIGINAL_THREAD(ret, pSelf, THREAD_API_OTHER, 
365                         "dp", type, oldtype);
366
367         return ret;
368 }
369
370 int pthread_attr_init(pthread_attr_t *attr)
371 {
372         pthread_t thread = 0;
373         static int (*pthread_attr_initp)(pthread_attr_t *attr);
374
375         BEFORE_ORIGINAL_THREAD(pthread_attr_init, LIBPTHREAD);
376
377         ret = pthread_attr_initp(attr);
378
379         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, "%p", attr);
380
381         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, "p", attr);
382
383         return ret;
384 }
385
386 int pthread_attr_destroy(pthread_attr_t *attr) 
387 {
388         pthread_t thread = 0;
389         static int (*pthread_attr_destroyp)(pthread_attr_t *attr);
390
391         BEFORE_ORIGINAL_THREAD(pthread_attr_destroy, LIBPTHREAD);
392
393         ret = pthread_attr_destroyp(attr);
394
395         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, "%p", attr);
396
397         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, "p", attr);
398
399         return ret;
400 }
401
402 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
403 {
404         pthread_t thread = 0;
405         static int (*pthread_attr_getdetachstatep)(const pthread_attr_t *attr,
406                         int *detachstate);
407
408         BEFORE_ORIGINAL_THREAD(pthread_attr_getdetachstate, LIBPTHREAD);
409
410         ret = pthread_attr_getdetachstatep(attr, detachstate);
411
412         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
413                         "%p,%p", attr, detachstate);
414
415         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
416                         "pp", attr, detachstate);
417
418         return ret;
419 }
420
421 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
422 {
423         pthread_t thread = 0;
424         static int (*pthread_attr_setdetachstatep)(pthread_attr_t *attr, 
425                         int detachstate);
426
427         BEFORE_ORIGINAL_THREAD(pthread_attr_setdetachstate, LIBPTHREAD);
428
429         ret = pthread_attr_setdetachstatep(attr, detachstate);
430
431         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
432                         "%p,%d", attr, detachstate);
433
434         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
435                         "pd", attr, detachstate);
436
437         return ret;
438 }
439
440 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
441 {
442         pthread_t thread = 0;
443         static int (*pthread_attr_getstacksizep)(const pthread_attr_t *attr,
444                         size_t *stacksize);
445
446         BEFORE_ORIGINAL_THREAD(pthread_attr_getstacksize, LIBPTHREAD);
447
448         ret = pthread_attr_getstacksizep(attr, stacksize);
449
450         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
451                         "%p,%p", attr, stacksize);
452
453         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
454                         "pp", attr, stacksize);
455
456         return ret;
457 }
458
459 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
460 {
461         pthread_t thread = 0;
462         static int (*pthread_attr_setstacksizep)(pthread_attr_t *attr, 
463                         size_t stacksize);
464
465         BEFORE_ORIGINAL_THREAD(pthread_attr_setstacksize, LIBPTHREAD);
466
467         ret = pthread_attr_setstacksizep(attr, stacksize);
468
469         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
470                         "%p,%u", attr, stacksize);
471
472         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
473                         "px", attr, stacksize);
474
475         return ret;
476 }
477
478 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
479 {
480         pthread_t thread = 0;
481         static int (*pthread_attr_getstackaddrp)(const pthread_attr_t *attr,
482                         void **stackaddr);
483
484         BEFORE_ORIGINAL_THREAD(pthread_attr_getstackaddr, LIBPTHREAD);
485
486         ret = pthread_attr_getstackaddrp(attr, stackaddr);
487
488         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
489                         "%p,%p", attr, stackaddr);
490
491         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
492                         "pp", attr, stackaddr);
493
494         return ret;
495 }
496
497 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
498 {
499         pthread_t thread = 0;
500         static int (*pthread_attr_setstackaddrp)(pthread_attr_t *attr, 
501                         void *stackaddr);
502
503         BEFORE_ORIGINAL_THREAD(pthread_attr_setstackaddr, LIBPTHREAD);
504
505         ret = pthread_attr_setstackaddrp(attr, stackaddr);
506
507         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
508                         "%p,%p", attr, stackaddr);
509
510         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
511                         "pp", attr, stackaddr);
512
513         return ret;
514 }
515
516 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
517 {
518         pthread_t thread = 0;
519         static int (*pthread_attr_getinheritschedp)(const pthread_attr_t *attr,
520                         int *inheritsched);
521
522         BEFORE_ORIGINAL_THREAD(pthread_attr_getinheritsched, LIBPTHREAD);
523
524         ret = pthread_attr_getinheritschedp(attr, inheritsched);
525
526         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
527                         "%p,%p", attr, inheritsched);
528
529         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
530                         "pp", attr, inheritsched);
531
532         return ret;
533 }
534
535 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
536 {
537         pthread_t thread = 0;
538         static int (*pthread_attr_setinheritschedp)(pthread_attr_t *attr, 
539                         int inheritsched);
540
541         BEFORE_ORIGINAL_THREAD(pthread_attr_setinheritsched, LIBPTHREAD);
542
543         ret = pthread_attr_setinheritschedp(attr, inheritsched);
544
545         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
546                         "%p,%d", attr, inheritsched);
547
548         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
549                         "pd", attr, inheritsched);
550
551         return ret;
552 }
553
554 int pthread_attr_getschedparam(const pthread_attr_t *attr,
555                 struct sched_param *param)
556 {
557         pthread_t thread = 0;
558         static int (*pthread_attr_getschedparamp)(const pthread_attr_t *attr,
559                         struct sched_param *param);
560
561         BEFORE_ORIGINAL_THREAD(pthread_attr_getschedparam, LIBPTHREAD);
562
563         ret = pthread_attr_getschedparamp(attr, param);
564
565         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
566                         "%p,%p", attr, param);
567
568         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
569                         "pp", attr, param);
570
571         return ret;
572 }
573
574 int pthread_attr_setschedparam(pthread_attr_t *attr, 
575                 const struct sched_param *param)
576 {
577         pthread_t thread = 0;
578         static int (*pthread_attr_setschedparamp)(pthread_attr_t *attr,
579                         const struct sched_param *param);
580
581         BEFORE_ORIGINAL_THREAD(pthread_attr_setschedparam, LIBPTHREAD);
582
583         ret = pthread_attr_setschedparamp(attr, param);
584
585         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
586                         "%p,%p", attr, param);
587
588         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
589                         "pp", attr, param);
590
591         return ret;
592 }
593
594 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
595 {
596         pthread_t thread = 0;
597         static int (*pthread_attr_getschedpolicyp)(const pthread_attr_t *attr,
598                         int *policy);
599
600         BEFORE_ORIGINAL_THREAD(pthread_attr_getschedpolicy, LIBPTHREAD);
601
602         ret = pthread_attr_getschedpolicyp(attr, policy);
603
604         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
605                         "%p,%p", attr, policy);
606
607         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
608                         "pp", attr, policy);
609
610         return ret;
611 }
612
613 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
614 {
615         pthread_t thread = 0;
616         static int (*pthread_attr_setschedpolicyp)(pthread_attr_t *attr, 
617                         int policy);
618
619         BEFORE_ORIGINAL_THREAD(pthread_attr_setschedpolicy, LIBPTHREAD);
620
621         ret = pthread_attr_setschedpolicyp(attr, policy);
622
623         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
624                         "%p,%d", attr, policy);
625
626         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
627                         "pd", attr, policy);
628
629         return ret;
630 }
631
632 int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
633 {
634         pthread_t thread = 0;
635         static int (*pthread_attr_getguardsizep)(const pthread_attr_t *attr,
636                         size_t *guardsize);
637
638         BEFORE_ORIGINAL_THREAD(pthread_attr_getguardsize, LIBPTHREAD);
639
640         ret = pthread_attr_getguardsizep(attr, guardsize);
641
642         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
643                         "%p,%p", attr, guardsize);
644
645         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
646                         "pp", attr, guardsize);
647
648         return ret;
649 }
650
651 int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
652 {
653         pthread_t thread = 0;
654         static int (*pthread_attr_setguardsizep)(pthread_attr_t *attr, 
655                         size_t guardsize);
656
657         BEFORE_ORIGINAL_THREAD(pthread_attr_setguardsize, LIBPTHREAD);
658
659         ret = pthread_attr_setguardsizep(attr, guardsize);
660
661         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
662                         "%p,%u", attr, guardsize);
663
664         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
665                         "px", attr, guardsize);
666
667         return ret;
668 }
669
670 int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
671 {
672         pthread_t thread = 0;
673         static int (*pthread_attr_getscopep)(const pthread_attr_t *attr,
674                         int *contentionscope);
675
676         BEFORE_ORIGINAL_THREAD(pthread_attr_getscope, LIBPTHREAD);
677
678         ret = pthread_attr_getscopep(attr, contentionscope);
679
680         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
681                         "%p,%p", attr, contentionscope);
682
683         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
684                         "pp", attr, contentionscope);
685
686         return ret;
687 }
688
689 int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
690 {
691         pthread_t thread = 0;
692         static int (*pthread_attr_setscopep)(pthread_attr_t *attr, 
693                         int contentionscope);
694
695         BEFORE_ORIGINAL_THREAD(pthread_attr_setscope, LIBPTHREAD);
696
697         ret = pthread_attr_setscopep(attr, contentionscope);
698
699         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
700                         "%p,%d", attr, contentionscope);
701
702         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
703                         "pd", attr, contentionscope);
704
705         return ret;
706 }
707
708 int pthread_attr_getstack(const pthread_attr_t *attr, 
709                 void **stackaddr, size_t *stacksize)
710 {
711         pthread_t thread = 0;
712         static int (*pthread_attr_getstackp)(const pthread_attr_t *attr,
713                         void **stackaddr, size_t *stacksize);
714
715         BEFORE_ORIGINAL_THREAD(pthread_attr_getstack, LIBPTHREAD);
716
717         ret = pthread_attr_getstackp(attr, stackaddr, stacksize);
718
719         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
720                         "%p,%p,%p", attr, stackaddr, stacksize);
721
722         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
723                         "ppp", attr, stackaddr, stacksize);
724
725         return ret;
726 }
727
728 int pthread_attr_setstack(pthread_attr_t *attr,
729                 void *stackaddr, size_t stacksize)
730 {
731         pthread_t thread = 0;
732         static int (*pthread_attr_setstackp)(pthread_attr_t *attr,
733                         void *stackaddr, size_t stacksize);
734
735         BEFORE_ORIGINAL_THREAD(pthread_attr_setstack, LIBPTHREAD);
736
737         ret = pthread_attr_setstackp(attr, stackaddr, stacksize);
738
739         AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, 
740                         "%p,%p,%u", attr, stackaddr, stacksize);
741
742         AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, 
743                         "ppx", attr, stackaddr, stacksize);
744
745         return ret;
746 }
747
748 /*
749 void pthread_testcancel(void);
750
751 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
752 int pthread_key_delete(pthread_key_t key);
753
754 int pthread_getconcurrency(void);
755 int pthread_setconcurrency(int new_level);
756 int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id);
757 int pthread_getschedparam(pthread_t thread, int *policy,
758                 struct sched_param *param);
759 int pthread_setschedparam(pthread_t thread, int policy,
760                 const struct sched_param *param);
761 int pthread_setschedprio(pthread_t thread, int prio);
762 void *pthread_getspecific(pthread_key_t key);
763 int pthread_setspecific(pthread_key_t key, const void *value);
764
765 int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
766
767 int pthread_atfork(void (*prepare)(void), void (*parent)(void),
768                 void (*child)(void));
769 */
770