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