4 * Copyright 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
8 * Woojin Jung <woojin2.jung@samsung.com>
9 * Jaewon Lim <jaewon81.lim@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
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)
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.
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
34 #include "probeinfo.h"
36 #include "da_thread.h"
40 typedef struct thread_routine_call_t {
41 void *(*thread_routine)(void *);
43 } thread_routine_call;
45 static enum DaOptions _sopt = OPT_THREAD;
47 // called when pthread_exit, pthread_cancel is called
48 void _da_cleanup_handler(void *data)
52 probeInfo_t probeInfo;
54 PRE_UNCONDITIONAL_BLOCK_BEGIN();
56 pSelf = pthread_self();
59 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", data);
60 PACK_COMMON_END(0, 0, 1);
61 PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
64 PRE_UNCONDITIONAL_BLOCK_END();
69 void *_da_ThreadProc(void *params)
72 thread_routine_call *ptrc;
73 ptrc = (thread_routine_call *) params;
76 probeInfo_t probeInfo;
78 PRE_UNCONDITIONAL_BLOCK_BEGIN();
80 pSelf = pthread_self();
83 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", params);
84 PACK_COMMON_END(0, 0, 1);
85 PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_START);
88 PRE_UNCONDITIONAL_BLOCK_END();
90 pthread_cleanup_push(_da_cleanup_handler, NULL);
91 // call user-defined thread routine
92 ret = ptrc->thread_routine(ptrc->argument);
93 pthread_cleanup_pop(0);
95 PRE_UNCONDITIONAL_BLOCK_BEGIN();
97 pSelf = pthread_self();
100 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", params);
101 PACK_COMMON_END(ret, 0, 1);
102 PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
105 PRE_UNCONDITIONAL_BLOCK_END();
111 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
112 void *(*start_routine) (void*), void *arg)
114 static int (*pthread_createp)(pthread_t *thread,
115 const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
117 BEFORE_ORIGINAL_THREAD(pthread_create, LIBPTHREAD);
122 thread_routine_call *ptrc =
123 (thread_routine_call *) malloc(sizeof(thread_routine_call));
124 ptrc->thread_routine = start_routine;
125 ptrc->argument = arg;
128 ret = pthread_createp(thread, attr, _da_ThreadProc, (void *) ptrc);
130 else // when pthread_create is called inside probe so (ex. custom chart, sampling thread)
132 ret = pthread_createp(thread, attr, start_routine, arg);
135 AFTER_PACK_ORIGINAL_THREAD(ret, *thread, THREAD_API_START,
136 "pppp", thread, attr, start_routine, arg);
141 int pthread_join(pthread_t thread, void **retval)
143 static int (*pthread_joinp)(pthread_t thread, void **retval);
145 DECLARE_VARIABLE_STANDARD;
146 GET_REAL_FUNC(pthread_join, LIBPTHREAD);
148 PRE_PROBEBLOCK_BEGIN();
151 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "xp", thread, retval);
152 PACK_COMMON_END(0, 0, blockresult);
153 PACK_THREAD(thread, THREAD_PTHREAD, THREAD_API_WAIT_START);
156 PRE_PROBEBLOCK_END();
158 ret = pthread_joinp(thread, retval);
162 if(postBlockBegin(blockresult)) {
163 setProbePoint(&probeInfo);
166 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "xp", thread, retval);
167 PACK_COMMON_END(ret, errno, blockresult);
168 PACK_THREAD(thread, THREAD_PTHREAD, THREAD_API_WAIT_END);
177 void pthread_exit(void *retval)
180 static void (*pthread_exitp)(void *retval) __attribute__((noreturn));
182 DECLARE_VARIABLE_STANDARD;
183 GET_REAL_FUNC(pthread_exit, LIBPTHREAD);
185 PRE_PROBEBLOCK_BEGIN();
187 pSelf = pthread_self();
190 PACK_COMMON_BEGIN(MSG_PROBE_THREAD, LC_THREAD, "p", retval);
191 PACK_COMMON_END(0, 0, blockresult);
192 PACK_THREAD(pSelf, THREAD_PTHREAD, THREAD_API_EXIT);
195 PRE_PROBEBLOCK_END();
197 pthread_exitp(retval);
200 int pthread_cancel(pthread_t thread)
202 static int (*pthread_cancelp)(pthread_t thread);
204 BEFORE_ORIGINAL_THREAD(pthread_cancel, LIBPTHREAD);
206 ret = pthread_cancelp(thread);
208 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_STOP, "x", thread);
213 int pthread_detach(pthread_t thread)
215 static int (*pthread_detachp)(pthread_t thread);
217 BEFORE_ORIGINAL_THREAD(pthread_detach, LIBPTHREAD);
219 ret = pthread_detachp(thread);
221 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, "x", thread);
226 pthread_t pthread_self(void)
229 static pthread_t (*pthread_selfp)(void);
231 BEFORE_ORIGINAL_THREAD(pthread_self, LIBPTHREAD);
233 ret_pthr = pthread_selfp();
236 if(postBlockBegin(blockresult)) {
238 AFTER_PACK_ORIGINAL_THREAD(ret_pthr, ret_pthr, THREAD_API_OTHER, "", 0);
246 int pthread_equal(pthread_t t1, pthread_t t2)
248 static int (*pthread_equalp)(pthread_t t1, pthread_t t2);
250 BEFORE_ORIGINAL_THREAD(pthread_equal, LIBPTHREAD);
252 ret = pthread_equalp(t1, t2);
254 AFTER_PACK_ORIGINAL_THREAD(ret, t1, THREAD_API_OTHER, "xx", t1, t2);
259 int pthread_setcancelstate(int state, int *oldstate)
262 static int (*pthread_setcancelstatep)(int state, int *oldstate);
264 BEFORE_ORIGINAL_THREAD(pthread_setcancelstate, LIBPTHREAD);
266 pSelf = pthread_self();
267 ret = pthread_setcancelstatep(state, oldstate);
269 AFTER_PACK_ORIGINAL_THREAD(ret, pSelf, THREAD_API_OTHER,
270 "dp", state, oldstate);
275 int pthread_setcanceltype(int type, int *oldtype)
278 static int (*pthread_setcanceltypep)(int type, int *oldtype);
280 BEFORE_ORIGINAL_THREAD(pthread_setcanceltype, LIBPTHREAD);
282 pSelf = pthread_self();
283 ret = pthread_setcanceltypep(type, oldtype);
285 AFTER_PACK_ORIGINAL_THREAD(ret, pSelf, THREAD_API_OTHER,
286 "dp", type, oldtype);
291 int pthread_attr_init(pthread_attr_t *attr)
293 pthread_t thread = 0;
294 static int (*pthread_attr_initp)(pthread_attr_t *attr);
296 BEFORE_ORIGINAL_THREAD(pthread_attr_init, LIBPTHREAD);
298 ret = pthread_attr_initp(attr);
300 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, "p", attr);
305 int pthread_attr_destroy(pthread_attr_t *attr)
307 pthread_t thread = 0;
308 static int (*pthread_attr_destroyp)(pthread_attr_t *attr);
310 BEFORE_ORIGINAL_THREAD(pthread_attr_destroy, LIBPTHREAD);
312 ret = pthread_attr_destroyp(attr);
314 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER, "p", attr);
319 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
321 pthread_t thread = 0;
322 static int (*pthread_attr_getdetachstatep)(const pthread_attr_t *attr,
325 BEFORE_ORIGINAL_THREAD(pthread_attr_getdetachstate, LIBPTHREAD);
327 ret = pthread_attr_getdetachstatep(attr, detachstate);
329 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
330 "pp", attr, detachstate);
335 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
337 pthread_t thread = 0;
338 static int (*pthread_attr_setdetachstatep)(pthread_attr_t *attr,
341 BEFORE_ORIGINAL_THREAD(pthread_attr_setdetachstate, LIBPTHREAD);
343 ret = pthread_attr_setdetachstatep(attr, detachstate);
345 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
346 "pd", attr, detachstate);
351 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
353 pthread_t thread = 0;
354 static int (*pthread_attr_getstacksizep)(const pthread_attr_t *attr,
357 BEFORE_ORIGINAL_THREAD(pthread_attr_getstacksize, LIBPTHREAD);
359 ret = pthread_attr_getstacksizep(attr, stacksize);
361 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
362 "pp", attr, stacksize);
367 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
369 pthread_t thread = 0;
370 static int (*pthread_attr_setstacksizep)(pthread_attr_t *attr,
373 BEFORE_ORIGINAL_THREAD(pthread_attr_setstacksize, LIBPTHREAD);
375 ret = pthread_attr_setstacksizep(attr, stacksize);
377 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
378 "px", attr, stacksize);
383 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
385 pthread_t thread = 0;
386 static int (*pthread_attr_getstackaddrp)(const pthread_attr_t *attr,
389 BEFORE_ORIGINAL_THREAD(pthread_attr_getstackaddr, LIBPTHREAD);
391 ret = pthread_attr_getstackaddrp(attr, stackaddr);
393 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
394 "pp", attr, stackaddr);
399 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
401 pthread_t thread = 0;
402 static int (*pthread_attr_setstackaddrp)(pthread_attr_t *attr,
405 BEFORE_ORIGINAL_THREAD(pthread_attr_setstackaddr, LIBPTHREAD);
407 ret = pthread_attr_setstackaddrp(attr, stackaddr);
409 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
410 "pp", attr, stackaddr);
415 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
417 pthread_t thread = 0;
418 static int (*pthread_attr_getinheritschedp)(const pthread_attr_t *attr,
421 BEFORE_ORIGINAL_THREAD(pthread_attr_getinheritsched, LIBPTHREAD);
423 ret = pthread_attr_getinheritschedp(attr, inheritsched);
425 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
426 "pp", attr, inheritsched);
431 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
433 pthread_t thread = 0;
434 static int (*pthread_attr_setinheritschedp)(pthread_attr_t *attr,
437 BEFORE_ORIGINAL_THREAD(pthread_attr_setinheritsched, LIBPTHREAD);
439 ret = pthread_attr_setinheritschedp(attr, inheritsched);
441 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
442 "pd", attr, inheritsched);
447 int pthread_attr_getschedparam(const pthread_attr_t *attr,
448 struct sched_param *param)
450 pthread_t thread = 0;
451 static int (*pthread_attr_getschedparamp)(const pthread_attr_t *attr,
452 struct sched_param *param);
454 BEFORE_ORIGINAL_THREAD(pthread_attr_getschedparam, LIBPTHREAD);
456 ret = pthread_attr_getschedparamp(attr, param);
458 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
464 int pthread_attr_setschedparam(pthread_attr_t *attr,
465 const struct sched_param *param)
467 pthread_t thread = 0;
468 static int (*pthread_attr_setschedparamp)(pthread_attr_t *attr,
469 const struct sched_param *param);
471 BEFORE_ORIGINAL_THREAD(pthread_attr_setschedparam, LIBPTHREAD);
473 ret = pthread_attr_setschedparamp(attr, param);
475 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
481 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
483 pthread_t thread = 0;
484 static int (*pthread_attr_getschedpolicyp)(const pthread_attr_t *attr,
487 BEFORE_ORIGINAL_THREAD(pthread_attr_getschedpolicy, LIBPTHREAD);
489 ret = pthread_attr_getschedpolicyp(attr, policy);
491 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
497 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
499 pthread_t thread = 0;
500 static int (*pthread_attr_setschedpolicyp)(pthread_attr_t *attr,
503 BEFORE_ORIGINAL_THREAD(pthread_attr_setschedpolicy, LIBPTHREAD);
505 ret = pthread_attr_setschedpolicyp(attr, policy);
507 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
513 int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
515 pthread_t thread = 0;
516 static int (*pthread_attr_getguardsizep)(const pthread_attr_t *attr,
519 BEFORE_ORIGINAL_THREAD(pthread_attr_getguardsize, LIBPTHREAD);
521 ret = pthread_attr_getguardsizep(attr, guardsize);
523 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
524 "pp", attr, guardsize);
529 int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
531 pthread_t thread = 0;
532 static int (*pthread_attr_setguardsizep)(pthread_attr_t *attr,
535 BEFORE_ORIGINAL_THREAD(pthread_attr_setguardsize, LIBPTHREAD);
537 ret = pthread_attr_setguardsizep(attr, guardsize);
539 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
540 "px", attr, guardsize);
545 int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
547 pthread_t thread = 0;
548 static int (*pthread_attr_getscopep)(const pthread_attr_t *attr,
549 int *contentionscope);
551 BEFORE_ORIGINAL_THREAD(pthread_attr_getscope, LIBPTHREAD);
553 ret = pthread_attr_getscopep(attr, contentionscope);
555 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
556 "pp", attr, contentionscope);
561 int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
563 pthread_t thread = 0;
564 static int (*pthread_attr_setscopep)(pthread_attr_t *attr,
565 int contentionscope);
567 BEFORE_ORIGINAL_THREAD(pthread_attr_setscope, LIBPTHREAD);
569 ret = pthread_attr_setscopep(attr, contentionscope);
571 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
572 "pd", attr, contentionscope);
577 int pthread_attr_getstack(const pthread_attr_t *attr,
578 void **stackaddr, size_t *stacksize)
580 pthread_t thread = 0;
581 static int (*pthread_attr_getstackp)(const pthread_attr_t *attr,
582 void **stackaddr, size_t *stacksize);
584 BEFORE_ORIGINAL_THREAD(pthread_attr_getstack, LIBPTHREAD);
586 ret = pthread_attr_getstackp(attr, stackaddr, stacksize);
588 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
589 "ppp", attr, stackaddr, stacksize);
594 int pthread_attr_setstack(pthread_attr_t *attr,
595 void *stackaddr, size_t stacksize)
597 pthread_t thread = 0;
598 static int (*pthread_attr_setstackp)(pthread_attr_t *attr,
599 void *stackaddr, size_t stacksize);
601 BEFORE_ORIGINAL_THREAD(pthread_attr_setstack, LIBPTHREAD);
603 ret = pthread_attr_setstackp(attr, stackaddr, stacksize);
605 AFTER_PACK_ORIGINAL_THREAD(ret, thread, THREAD_API_OTHER,
606 "ppx", attr, stackaddr, stacksize);
612 void pthread_testcancel(void);
614 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
615 int pthread_key_delete(pthread_key_t key);
617 int pthread_getconcurrency(void);
618 int pthread_setconcurrency(int new_level);
619 int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id);
620 int pthread_getschedparam(pthread_t thread, int *policy,
621 struct sched_param *param);
622 int pthread_setschedparam(pthread_t thread, int policy,
623 const struct sched_param *param);
624 int pthread_setschedprio(pthread_t thread, int prio);
625 void *pthread_getspecific(pthread_key_t key);
626 int pthread_setspecific(pthread_key_t key, const void *value);
628 int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
630 int pthread_atfork(void (*prepare)(void), void (*parent)(void),
631 void (*child)(void));