4 * Copyright 2000 - 2013 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>
11 * Anastasia Lyupa <a.lyupa@samsung.com>
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)
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.
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
29 * - Samsung RnD Institute Russia
36 #include "probeinfo.h"
38 #include "da_thread.h"
41 #include "real_functions.h"
43 typedef struct thread_routine_call_t {
44 void *(*thread_routine)(void *);
46 } thread_routine_call;
48 static enum DaOptions _sopt = OPT_THREAD;
50 // called when pthread_exit, pthread_cancel is called
51 void _da_cleanup_handler(void *data)
55 probeInfo_t probeInfo;
57 // unlock socket mutex to prevent deadlock
58 // in case of cancellation happened while log sending
59 real_pthread_mutex_unlock(&(gTraceInfo.socket.sockMutex));
61 PRE_UNCONDITIONAL_BLOCK_BEGIN();
63 pSelf = pthread_self();
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);
73 PRE_UNCONDITIONAL_BLOCK_END();
78 void *_da_ThreadProc(void *params)
81 thread_routine_call *ptrc;
82 ptrc = (thread_routine_call *) params;
85 int new_state = PTHREAD_CANCEL_DISABLE;
87 probeInfo_t probeInfo;
89 // disable cancellation to prevent deadlock
90 real_pthread_setcancelstate(new_state, &old_state);
92 PRE_UNCONDITIONAL_BLOCK_BEGIN();
94 pSelf = pthread_self();
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);
104 PRE_UNCONDITIONAL_BLOCK_END();
106 // restore cancellation state
107 real_pthread_setcancelstate(old_state, NULL);
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);
114 // disable cancellation to prevent deadlock
115 real_pthread_setcancelstate(new_state, &old_state);
117 PRE_UNCONDITIONAL_BLOCK_BEGIN();
119 pSelf = pthread_self();
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);
129 PRE_UNCONDITIONAL_BLOCK_END();
135 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
136 void *(*start_routine) (void*), void *arg)
138 static int (*pthread_createp)(pthread_t *thread,
139 const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
141 BEFORE_ORIGINAL_THREAD(pthread_create, LIBPTHREAD);
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;
152 ret = pthread_createp(thread, attr, _da_ThreadProc, (void *) ptrc);
154 else // when pthread_create is called inside probe so (ex. custom chart, sampling thread)
156 ret = pthread_createp(thread, attr, start_routine, arg);
159 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_create,
160 'd', ret, *thread, THREAD_API_START,
162 voidp_to_uint64(thread),
163 voidp_to_uint64(attr),
164 voidp_to_uint64(start_routine),
165 voidp_to_uint64(arg));
170 int pthread_join(pthread_t thread, void **retval)
172 static int (*pthread_joinp)(pthread_t thread, void **retval);
174 DECLARE_VARIABLE_STANDARD;
175 GET_REAL_FUNC(pthread_join, LIBPTHREAD);
177 PRE_PROBEBLOCK_BEGIN();
180 PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
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);
187 PRE_PROBEBLOCK_END();
189 ret = pthread_joinp(thread, retval);
193 if(postBlockBegin(blockresult)) {
194 setProbePoint(&probeInfo);
197 PACK_COMMON_BEGIN(MSG_PROBE_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);
209 errno = (newerrno != 0) ? newerrno : olderrno;
214 void pthread_exit(void *retval)
217 static void (*pthread_exitp)(void *retval) __attribute__((noreturn));
219 DECLARE_VARIABLE_STANDARD;
220 GET_REAL_FUNC(pthread_exit, LIBPTHREAD);
222 PRE_PROBEBLOCK_BEGIN();
224 pSelf = pthread_self();
227 PACK_COMMON_BEGIN(MSG_PROBE_THREAD,
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);
234 PRE_PROBEBLOCK_END();
236 errno = (newerrno != 0) ? newerrno : olderrno;
238 pthread_exitp(retval);
242 int pthread_cancel(pthread_t thread)
244 static int (*pthread_cancelp)(pthread_t thread);
246 BEFORE_ORIGINAL_THREAD(pthread_cancel, LIBPTHREAD);
248 ret = pthread_cancelp(thread);
250 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_cancel,
251 'd', ret, thread, THREAD_API_STOP, "x",
257 int pthread_detach(pthread_t thread)
259 static int (*pthread_detachp)(pthread_t thread);
261 BEFORE_ORIGINAL_THREAD(pthread_detach, LIBPTHREAD);
263 ret = pthread_detachp(thread);
265 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_detach,
266 'd', ret, thread, THREAD_API_OTHER, "x",
272 pthread_t pthread_self(void)
275 static pthread_t (*pthread_selfp)(void);
277 BEFORE_ORIGINAL_THREAD(pthread_self, LIBPTHREAD);
279 ret_pthr = pthread_selfp();
283 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_self,
284 'p', ret_pthr, ret_pthr, THREAD_API_OTHER, "", 0);
289 int pthread_equal(pthread_t t1, pthread_t t2)
291 static int (*pthread_equalp)(pthread_t t1, pthread_t t2);
293 BEFORE_ORIGINAL_THREAD(pthread_equal, LIBPTHREAD);
295 ret = pthread_equalp(t1, t2);
297 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_equal,
298 'd', ret, t1, THREAD_API_OTHER, "xx",
299 (uint64_t)(t1), (uint64_t)(t2));
304 int real_pthread_setcancelstate(int state, int *oldstate)
306 static int (*pthread_setcancelstatep)(int state, int *oldstate);
308 GET_REAL_FUNC(pthread_setcancelstate, LIBPTHREAD);
310 return pthread_setcancelstatep(state, oldstate);
313 int pthread_setcancelstate(int state, int *oldstate)
316 static int (*pthread_setcancelstatep)(int state, int *oldstate);
318 BEFORE_ORIGINAL_THREAD(pthread_setcancelstate, LIBPTHREAD);
320 pSelf = pthread_self();
321 ret = pthread_setcancelstatep(state, oldstate);
323 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_setcancelstate,
324 'd', ret, pSelf, THREAD_API_OTHER,
325 "dp", state, voidp_to_uint64(oldstate));
330 int pthread_setcanceltype(int type, int *oldtype)
333 static int (*pthread_setcanceltypep)(int type, int *oldtype);
335 BEFORE_ORIGINAL_THREAD(pthread_setcanceltype, LIBPTHREAD);
337 pSelf = pthread_self();
338 ret = pthread_setcanceltypep(type, oldtype);
340 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_setcanceltype,
341 'd', ret, pSelf, THREAD_API_OTHER,
342 "dp", type, voidp_to_uint64(oldtype));
347 int pthread_attr_init(pthread_attr_t *attr)
349 pthread_t thread = 0;
350 static int (*pthread_attr_initp)(pthread_attr_t *attr);
352 BEFORE_ORIGINAL_THREAD(pthread_attr_init, LIBPTHREAD);
354 ret = pthread_attr_initp(attr);
356 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_init,
357 'd', ret, thread, THREAD_API_OTHER, "p",
358 voidp_to_uint64(attr));
363 int pthread_attr_destroy(pthread_attr_t *attr)
365 pthread_t thread = 0;
366 static int (*pthread_attr_destroyp)(pthread_attr_t *attr);
368 BEFORE_ORIGINAL_THREAD(pthread_attr_destroy, LIBPTHREAD);
370 ret = pthread_attr_destroyp(attr);
372 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_destroy,
373 'd', ret, thread, THREAD_API_OTHER, "p",
374 voidp_to_uint64(attr));
379 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
381 pthread_t thread = 0;
382 static int (*pthread_attr_getdetachstatep)(const pthread_attr_t *attr,
385 BEFORE_ORIGINAL_THREAD(pthread_attr_getdetachstate, LIBPTHREAD);
387 ret = pthread_attr_getdetachstatep(attr, detachstate);
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));
397 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
399 pthread_t thread = 0;
400 static int (*pthread_attr_setdetachstatep)(pthread_attr_t *attr,
403 BEFORE_ORIGINAL_THREAD(pthread_attr_setdetachstate, LIBPTHREAD);
405 ret = pthread_attr_setdetachstatep(attr, detachstate);
407 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setdetachstate,
408 'd', ret, thread, THREAD_API_OTHER,
409 "pd", voidp_to_uint64(attr),
415 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
417 pthread_t thread = 0;
418 static int (*pthread_attr_getstacksizep)(const pthread_attr_t *attr,
421 BEFORE_ORIGINAL_THREAD(pthread_attr_getstacksize, LIBPTHREAD);
423 ret = pthread_attr_getstacksizep(attr, stacksize);
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));
433 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
435 pthread_t thread = 0;
436 static int (*pthread_attr_setstacksizep)(pthread_attr_t *attr,
439 BEFORE_ORIGINAL_THREAD(pthread_attr_setstacksize, LIBPTHREAD);
441 ret = pthread_attr_setstacksizep(attr, stacksize);
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));
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
459 * happens on pthread-2.18 (target TV emul), not happens on pthread-2.13
461 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
463 pthread_t thread = 0;
464 static int (*pthread_attr_getstackaddrp)(const pthread_attr_t *attr,
467 BEFORE_ORIGINAL_THREAD(pthread_attr_getstackaddr, LIBPTHREAD);
469 ret = pthread_attr_getstackaddrp(attr, stackaddr);
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));
479 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
481 pthread_t thread = 0;
482 static int (*pthread_attr_setstackaddrp)(pthread_attr_t *attr,
485 BEFORE_ORIGINAL_THREAD(pthread_attr_setstackaddr, LIBPTHREAD);
487 ret = pthread_attr_setstackaddrp(attr, stackaddr);
489 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setstackaddr,
490 'd', ret, thread, THREAD_API_OTHER,
492 voidp_to_uint64(attr),
493 voidp_to_uint64(stackaddr));
499 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
501 pthread_t thread = 0;
502 static int (*pthread_attr_getinheritschedp)(const pthread_attr_t *attr,
505 BEFORE_ORIGINAL_THREAD(pthread_attr_getinheritsched, LIBPTHREAD);
507 ret = pthread_attr_getinheritschedp(attr, inheritsched);
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));
517 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
519 pthread_t thread = 0;
520 static int (*pthread_attr_setinheritschedp)(pthread_attr_t *attr,
523 BEFORE_ORIGINAL_THREAD(pthread_attr_setinheritsched, LIBPTHREAD);
525 ret = pthread_attr_setinheritschedp(attr, inheritsched);
527 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setinheritsched,
528 'd', ret, thread, THREAD_API_OTHER,
529 "pd", voidp_to_uint64(attr),
535 int pthread_attr_getschedparam(const pthread_attr_t *attr,
536 struct sched_param *param)
538 pthread_t thread = 0;
539 static int (*pthread_attr_getschedparamp)(const pthread_attr_t *attr,
540 struct sched_param *param);
542 BEFORE_ORIGINAL_THREAD(pthread_attr_getschedparam, LIBPTHREAD);
544 ret = pthread_attr_getschedparamp(attr, param);
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));
554 int pthread_attr_setschedparam(pthread_attr_t *attr,
555 const struct sched_param *param)
557 pthread_t thread = 0;
558 static int (*pthread_attr_setschedparamp)(pthread_attr_t *attr,
559 const struct sched_param *param);
561 BEFORE_ORIGINAL_THREAD(pthread_attr_setschedparam, LIBPTHREAD);
563 ret = pthread_attr_setschedparamp(attr, param);
565 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setschedparam,
566 'd', ret, thread, THREAD_API_OTHER,
568 voidp_to_uint64(attr),
569 voidp_to_uint64(param));
574 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
576 pthread_t thread = 0;
577 static int (*pthread_attr_getschedpolicyp)(const pthread_attr_t *attr,
580 BEFORE_ORIGINAL_THREAD(pthread_attr_getschedpolicy, LIBPTHREAD);
582 ret = pthread_attr_getschedpolicyp(attr, policy);
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));
592 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
594 pthread_t thread = 0;
595 static int (*pthread_attr_setschedpolicyp)(pthread_attr_t *attr,
598 BEFORE_ORIGINAL_THREAD(pthread_attr_setschedpolicy, LIBPTHREAD);
600 ret = pthread_attr_setschedpolicyp(attr, policy);
602 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setschedpolicy,
603 'd', ret, thread, THREAD_API_OTHER,
604 "pd", voidp_to_uint64(attr),
610 int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
612 pthread_t thread = 0;
613 static int (*pthread_attr_getguardsizep)(const pthread_attr_t *attr,
616 BEFORE_ORIGINAL_THREAD(pthread_attr_getguardsize, LIBPTHREAD);
618 ret = pthread_attr_getguardsizep(attr, guardsize);
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));
628 int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
630 pthread_t thread = 0;
631 static int (*pthread_attr_setguardsizep)(pthread_attr_t *attr,
634 BEFORE_ORIGINAL_THREAD(pthread_attr_setguardsize, LIBPTHREAD);
636 ret = pthread_attr_setguardsizep(attr, guardsize);
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));
646 int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
648 pthread_t thread = 0;
649 static int (*pthread_attr_getscopep)(const pthread_attr_t *attr,
650 int *contentionscope);
652 BEFORE_ORIGINAL_THREAD(pthread_attr_getscope, LIBPTHREAD);
654 ret = pthread_attr_getscopep(attr, contentionscope);
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));
664 int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
666 pthread_t thread = 0;
667 static int (*pthread_attr_setscopep)(pthread_attr_t *attr,
668 int contentionscope);
670 BEFORE_ORIGINAL_THREAD(pthread_attr_setscope, LIBPTHREAD);
672 ret = pthread_attr_setscopep(attr, contentionscope);
674 AFTER_PACK_ORIGINAL_THREAD(API_ID_pthread_attr_setscope,
675 'd', ret, thread, THREAD_API_OTHER,
676 "pd", voidp_to_uint64(attr), contentionscope);
681 int pthread_attr_getstack(const pthread_attr_t *attr,
682 void **stackaddr, size_t *stacksize)
684 pthread_t thread = 0;
685 static int (*pthread_attr_getstackp)(const pthread_attr_t *attr,
686 void **stackaddr, size_t *stacksize);
688 BEFORE_ORIGINAL_THREAD(pthread_attr_getstack, LIBPTHREAD);
690 ret = pthread_attr_getstackp(attr, stackaddr, stacksize);
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));
701 int pthread_attr_setstack(pthread_attr_t *attr,
702 void *stackaddr, size_t stacksize)
704 pthread_t thread = 0;
705 static int (*pthread_attr_setstackp)(pthread_attr_t *attr,
706 void *stackaddr, size_t stacksize);
708 BEFORE_ORIGINAL_THREAD(pthread_attr_setstack, LIBPTHREAD);
710 ret = pthread_attr_setstackp(attr, stackaddr, stacksize);
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));
722 void pthread_testcancel(void);
724 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
725 int pthread_key_delete(pthread_key_t key);
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);
738 int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
740 int pthread_atfork(void (*prepare)(void), void (*parent)(void),
741 void (*child)(void));