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"
38 typedef struct thread_routine_call_t {
39 void *(*thread_routine)(void *);
41 } thread_routine_call;
43 static enum DaOptions _sopt = OPT_THREAD;
45 // called when pthread_exit, pthread_cancel is called
46 void _da_cleanup_handler(void *data)
50 DECLARE_COMMON_VARIABLE;
53 PRE_UNCONDITIONAL_BLOCK_BEGIN();
54 APPEND_LOG_BASIC(LC_THREAD);
55 // input,ret,PCAddr,errno,InternalCall,CallerPCAddr
56 log.length += sprintf(log.data + log.length, "`,`,`,0`,0`,1`,0");
57 pSelf = pthread_self();
58 log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
59 pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
60 APPEND_LOG_NULL_CALLSTACK();
61 printLog(&log, MSG_LOG);
62 PRE_UNCONDITIONAL_BLOCK_END();
67 void *_da_ThreadProc(void *params)
70 thread_routine_call *ptrc;
71 ptrc = (thread_routine_call *) params;
74 DECLARE_COMMON_VARIABLE;
76 // send INTERNAL_START log
79 PRE_UNCONDITIONAL_BLOCK_BEGIN();
80 APPEND_LOG_BASIC(LC_THREAD);
81 // input,ret,PCAddr,errno,InternalCall,CallerPCAddr
82 log.length += sprintf(log.data + log.length, "`,`,`,0`,0`,1`,0");
83 pSelf = pthread_self();
84 log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
85 pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_START);
86 APPEND_LOG_NULL_CALLSTACK();
87 printLog(&log, MSG_LOG);
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 // send INTERNAL_STOP log
98 PRE_UNCONDITIONAL_BLOCK_BEGIN();
99 APPEND_LOG_BASIC(LC_THREAD);
100 // input,ret,PCAddr,errno,InternalCall,CallerPCAddr
101 log.length += sprintf(log.data + log.length, "`,`,`,0`,0`,1`,0");
102 pSelf = pthread_self();
103 log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
104 pSelf, THREAD_PTHREAD, THREAD_API_INTERNAL_STOP);
105 APPEND_LOG_NULL_CALLSTACK();
106 printLog(&log, MSG_LOG);
107 PRE_UNCONDITIONAL_BLOCK_END();
113 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
114 void *(*start_routine) (void*), void *arg)
116 static int (*pthread_createp)(pthread_t *thread,
117 const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
119 BEFORE_ORIGINAL_THREAD(pthread_create, LIBPTHREAD);
124 thread_routine_call *ptrc =
125 (thread_routine_call *) malloc(sizeof(thread_routine_call));
126 ptrc->thread_routine = start_routine;
127 ptrc->argument = arg;
130 ret = pthread_createp(thread, attr, _da_ThreadProc, (void *) ptrc);
132 else // when pthread_create is called inside probe so (ex. custom chart, sampling thread)
134 ret = pthread_createp(thread, attr, start_routine, arg);
137 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, *thread, THREAD_API_START,
138 "%p,%p,%p,%p", thread, attr, start_routine, arg);
143 int pthread_join(pthread_t thread, void **retval)
145 static int (*pthread_joinp)(pthread_t thread, void **retval);
147 DECLARE_VARIABLE_STANDARD;
148 GET_REAL_FUNC(pthread_join, LIBPTHREAD);
150 PRE_PROBEBLOCK_BEGIN();
151 // send WAIT_START log
153 APPEND_LOG_BASIC(LC_THREAD);
154 APPEND_LOG_INPUT("%lu,%p", thread, retval);
155 //ret,PCAddr,errno,InternalCall
156 log.length += sprintf(log.data + log.length, "`,`,0`,0`,%d", blockresult);
158 log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d", thread,
159 THREAD_PTHREAD, THREAD_API_WAIT_START);
160 APPEND_LOG_NULL_CALLSTACK();
161 printLog(&log, MSG_LOG);
162 PRE_PROBEBLOCK_END();
164 ret = pthread_joinp(thread, retval);
168 if(postBlockBegin(blockresult)) {
169 setProbePoint(&probeInfo);
171 APPEND_LOG_BASIC(LC_THREAD);
172 APPEND_LOG_INPUT("%lu,%p", thread, retval);
173 APPEND_LOG_RESULT(VT_INT, ret);
176 POST_PROBEBLOCK_MIDDLE_THREAD(thread, THREAD_API_WAIT_END);
177 POST_PROBEBLOCK_CALLSTACK();
178 printLog(&log, MSG_LOG);
185 void pthread_exit(void *retval)
188 static void (*pthread_exitp)(void *retval) __attribute__((noreturn));
190 DECLARE_VARIABLE_STANDARD;
191 GET_REAL_FUNC(pthread_exit, LIBPTHREAD);
193 PRE_PROBEBLOCK_BEGIN();
196 APPEND_LOG_BASIC(LC_THREAD);
197 APPEND_LOG_INPUT("%p", retval);
198 //ret,PCAddr,errno,InternalCall
199 log.length += sprintf(log.data + log.length, "`,`,0`,0`,%d", blockresult);
201 pSelf = pthread_self();
202 log.length += sprintf(log.data + log.length, "`,%lu`,`,%d`,%d",
203 pSelf, THREAD_PTHREAD, THREAD_API_EXIT);
204 APPEND_LOG_NULL_CALLSTACK();
205 printLog(&log, MSG_LOG);
206 PRE_PROBEBLOCK_END();
208 pthread_exitp(retval);
211 int pthread_cancel(pthread_t thread)
213 static int (*pthread_cancelp)(pthread_t thread);
215 BEFORE_ORIGINAL_THREAD(pthread_cancel, LIBPTHREAD);
217 ret = pthread_cancelp(thread);
219 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_STOP, "%lu", thread);
224 int pthread_detach(pthread_t thread)
226 static int (*pthread_detachp)(pthread_t thread);
228 BEFORE_ORIGINAL_THREAD(pthread_detach, LIBPTHREAD);
230 ret = pthread_detachp(thread);
232 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, "%lu", thread);
237 pthread_t pthread_self(void)
240 static pthread_t (*pthread_selfp)(void);
242 BEFORE_ORIGINAL_THREAD(pthread_self, LIBPTHREAD);
244 ret_pthr = pthread_selfp();
247 if(postBlockBegin(blockresult)) {
249 APPEND_LOG_BASIC(LC_THREAD);
250 log.length += sprintf(log.data + log.length, "`,");
251 APPEND_LOG_RESULT(VT_ULONG, ret_pthr);
254 POST_PROBEBLOCK_MIDDLE_THREAD(ret_pthr, THREAD_API_OTHER);
255 POST_PROBEBLOCK_CALLSTACK();
256 printLog(&log, MSG_LOG);
263 int pthread_equal(pthread_t t1, pthread_t t2)
265 static int (*pthread_equalp)(pthread_t t1, pthread_t t2);
267 BEFORE_ORIGINAL_THREAD(pthread_equal, LIBPTHREAD);
269 ret = pthread_equalp(t1, t2);
271 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, t1, THREAD_API_OTHER, "%lu,%lu", t1, t2);
276 int pthread_setcancelstate(int state, int *oldstate)
279 static int (*pthread_setcancelstatep)(int state, int *oldstate);
281 BEFORE_ORIGINAL_THREAD(pthread_setcancelstate, LIBPTHREAD);
283 pSelf = pthread_self();
284 ret = pthread_setcancelstatep(state, oldstate);
286 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, pSelf, THREAD_API_OTHER,
287 "%d,%p", state, oldstate);
292 int pthread_setcanceltype(int type, int *oldtype)
295 static int (*pthread_setcanceltypep)(int type, int *oldtype);
297 BEFORE_ORIGINAL_THREAD(pthread_setcanceltype, LIBPTHREAD);
299 pSelf = pthread_self();
300 ret = pthread_setcanceltypep(type, oldtype);
302 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, pSelf, THREAD_API_OTHER,
303 "%d,%p", type, oldtype);
308 int pthread_attr_init(pthread_attr_t *attr)
310 pthread_t thread = 0;
311 static int (*pthread_attr_initp)(pthread_attr_t *attr);
313 BEFORE_ORIGINAL_THREAD(pthread_attr_init, LIBPTHREAD);
315 ret = pthread_attr_initp(attr);
317 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, "%p", attr);
322 int pthread_attr_destroy(pthread_attr_t *attr)
324 pthread_t thread = 0;
325 static int (*pthread_attr_destroyp)(pthread_attr_t *attr);
327 BEFORE_ORIGINAL_THREAD(pthread_attr_destroy, LIBPTHREAD);
329 ret = pthread_attr_destroyp(attr);
331 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER, "%p", attr);
336 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
338 pthread_t thread = 0;
339 static int (*pthread_attr_getdetachstatep)(const pthread_attr_t *attr,
342 BEFORE_ORIGINAL_THREAD(pthread_attr_getdetachstate, LIBPTHREAD);
344 ret = pthread_attr_getdetachstatep(attr, detachstate);
346 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
347 "%p,%p", attr, detachstate);
352 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
354 pthread_t thread = 0;
355 static int (*pthread_attr_setdetachstatep)(pthread_attr_t *attr,
358 BEFORE_ORIGINAL_THREAD(pthread_attr_setdetachstate, LIBPTHREAD);
360 ret = pthread_attr_setdetachstatep(attr, detachstate);
362 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
363 "%p,%d", attr, detachstate);
368 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
370 pthread_t thread = 0;
371 static int (*pthread_attr_getstacksizep)(const pthread_attr_t *attr,
374 BEFORE_ORIGINAL_THREAD(pthread_attr_getstacksize, LIBPTHREAD);
376 ret = pthread_attr_getstacksizep(attr, stacksize);
378 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
379 "%p,%p", attr, stacksize);
384 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
386 pthread_t thread = 0;
387 static int (*pthread_attr_setstacksizep)(pthread_attr_t *attr,
390 BEFORE_ORIGINAL_THREAD(pthread_attr_setstacksize, LIBPTHREAD);
392 ret = pthread_attr_setstacksizep(attr, stacksize);
394 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
395 "%p,%u", attr, stacksize);
400 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
402 pthread_t thread = 0;
403 static int (*pthread_attr_getstackaddrp)(const pthread_attr_t *attr,
406 BEFORE_ORIGINAL_THREAD(pthread_attr_getstackaddr, LIBPTHREAD);
408 ret = pthread_attr_getstackaddrp(attr, stackaddr);
410 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
411 "%p,%p", attr, stackaddr);
416 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
418 pthread_t thread = 0;
419 static int (*pthread_attr_setstackaddrp)(pthread_attr_t *attr,
422 BEFORE_ORIGINAL_THREAD(pthread_attr_setstackaddr, LIBPTHREAD);
424 ret = pthread_attr_setstackaddrp(attr, stackaddr);
426 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
427 "%p,%p", attr, stackaddr);
432 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
434 pthread_t thread = 0;
435 static int (*pthread_attr_getinheritschedp)(const pthread_attr_t *attr,
438 BEFORE_ORIGINAL_THREAD(pthread_attr_getinheritsched, LIBPTHREAD);
440 ret = pthread_attr_getinheritschedp(attr, inheritsched);
442 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
443 "%p,%p", attr, inheritsched);
448 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
450 pthread_t thread = 0;
451 static int (*pthread_attr_setinheritschedp)(pthread_attr_t *attr,
454 BEFORE_ORIGINAL_THREAD(pthread_attr_setinheritsched, LIBPTHREAD);
456 ret = pthread_attr_setinheritschedp(attr, inheritsched);
458 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
459 "%p,%d", attr, inheritsched);
464 int pthread_attr_getschedparam(const pthread_attr_t *attr,
465 struct sched_param *param)
467 pthread_t thread = 0;
468 static int (*pthread_attr_getschedparamp)(const pthread_attr_t *attr,
469 struct sched_param *param);
471 BEFORE_ORIGINAL_THREAD(pthread_attr_getschedparam, LIBPTHREAD);
473 ret = pthread_attr_getschedparamp(attr, param);
475 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
476 "%p,%p", attr, param);
481 int pthread_attr_setschedparam(pthread_attr_t *attr,
482 const struct sched_param *param)
484 pthread_t thread = 0;
485 static int (*pthread_attr_setschedparamp)(pthread_attr_t *attr,
486 const struct sched_param *param);
488 BEFORE_ORIGINAL_THREAD(pthread_attr_setschedparam, LIBPTHREAD);
490 ret = pthread_attr_setschedparamp(attr, param);
492 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
493 "%p,%p", attr, param);
498 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
500 pthread_t thread = 0;
501 static int (*pthread_attr_getschedpolicyp)(const pthread_attr_t *attr,
504 BEFORE_ORIGINAL_THREAD(pthread_attr_getschedpolicy, LIBPTHREAD);
506 ret = pthread_attr_getschedpolicyp(attr, policy);
508 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
509 "%p,%p", attr, policy);
514 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
516 pthread_t thread = 0;
517 static int (*pthread_attr_setschedpolicyp)(pthread_attr_t *attr,
520 BEFORE_ORIGINAL_THREAD(pthread_attr_setschedpolicy, LIBPTHREAD);
522 ret = pthread_attr_setschedpolicyp(attr, policy);
524 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
525 "%p,%d", attr, policy);
530 int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
532 pthread_t thread = 0;
533 static int (*pthread_attr_getguardsizep)(const pthread_attr_t *attr,
536 BEFORE_ORIGINAL_THREAD(pthread_attr_getguardsize, LIBPTHREAD);
538 ret = pthread_attr_getguardsizep(attr, guardsize);
540 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
541 "%p,%p", attr, guardsize);
546 int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
548 pthread_t thread = 0;
549 static int (*pthread_attr_setguardsizep)(pthread_attr_t *attr,
552 BEFORE_ORIGINAL_THREAD(pthread_attr_setguardsize, LIBPTHREAD);
554 ret = pthread_attr_setguardsizep(attr, guardsize);
556 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
557 "%p,%u", attr, guardsize);
562 int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
564 pthread_t thread = 0;
565 static int (*pthread_attr_getscopep)(const pthread_attr_t *attr,
566 int *contentionscope);
568 BEFORE_ORIGINAL_THREAD(pthread_attr_getscope, LIBPTHREAD);
570 ret = pthread_attr_getscopep(attr, contentionscope);
572 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
573 "%p,%p", attr, contentionscope);
578 int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
580 pthread_t thread = 0;
581 static int (*pthread_attr_setscopep)(pthread_attr_t *attr,
582 int contentionscope);
584 BEFORE_ORIGINAL_THREAD(pthread_attr_setscope, LIBPTHREAD);
586 ret = pthread_attr_setscopep(attr, contentionscope);
588 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
589 "%p,%d", attr, contentionscope);
594 int pthread_attr_getstack(const pthread_attr_t *attr,
595 void **stackaddr, size_t *stacksize)
597 pthread_t thread = 0;
598 static int (*pthread_attr_getstackp)(const pthread_attr_t *attr,
599 void **stackaddr, size_t *stacksize);
601 BEFORE_ORIGINAL_THREAD(pthread_attr_getstack, LIBPTHREAD);
603 ret = pthread_attr_getstackp(attr, stackaddr, stacksize);
605 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
606 "%p,%p,%p", attr, stackaddr, stacksize);
611 int pthread_attr_setstack(pthread_attr_t *attr,
612 void *stackaddr, size_t stacksize)
614 pthread_t thread = 0;
615 static int (*pthread_attr_setstackp)(pthread_attr_t *attr,
616 void *stackaddr, size_t stacksize);
618 BEFORE_ORIGINAL_THREAD(pthread_attr_setstack, LIBPTHREAD);
620 ret = pthread_attr_setstackp(attr, stackaddr, stacksize);
622 AFTER_ORIGINAL_THREAD_RET(VT_INT, ret, thread, THREAD_API_OTHER,
623 "%p,%p,%u", attr, stackaddr, stacksize);
629 void pthread_testcancel(void);
631 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
632 int pthread_key_delete(pthread_key_t key);
634 int pthread_getconcurrency(void);
635 int pthread_setconcurrency(int new_level);
636 int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id);
637 int pthread_getschedparam(pthread_t thread, int *policy,
638 struct sched_param *param);
639 int pthread_setschedparam(pthread_t thread, int policy,
640 const struct sched_param *param);
641 int pthread_setschedprio(pthread_t thread, int prio);
642 void *pthread_getspecific(pthread_key_t key);
643 int pthread_setspecific(pthread_key_t key, const void *value);
645 int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
647 int pthread_atfork(void (*prepare)(void), void (*parent)(void),
648 void (*child)(void));