int __wrap_pthread_create(pthread_t* thread, const pthread_attr_t* attr, void *(*start_routine) (void *), void* arg) { int ret = __real_pthread_create(thread, attr, HPHP::start_routine_wrapper, arg); log_pthread_event(HPHP::PTHREAD_CREATE, thread, start_routine); return ret; }
int sc_tecreate(void (*entry) (void *), int tid, int prio, int mode, u_long ustacksz, u_long sstacksz __attribute__ ((unused)), char *paddr, u_long psize, int *errp) { struct vrtx_task_iargs iargs; struct sched_param param; pthread_attr_t thattr; int err, policy; pthread_t thid; /* Migrate this thread to the Linux domain since we are about to issue a series of regular kernel syscalls in order to create the new Linux thread, which in turn will be mapped to a VRTX shadow. */ XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN); iargs.tid = tid; iargs.prio = prio; iargs.mode = mode; iargs.entry = entry; iargs.param = paddr; __real_sem_init(&iargs.sync, 0, 0); pthread_attr_init(&thattr); ustacksz = xeno_stacksize(ustacksz); pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED); policy = vrtx_task_set_posix_priority(prio, ¶m); pthread_attr_setschedparam(&thattr, ¶m); pthread_attr_setschedpolicy(&thattr, policy); pthread_attr_setstacksize(&thattr, ustacksz); pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED); err = __real_pthread_create(&thid, &thattr, &vrtx_task_trampoline, &iargs); if (err) { *errp = err; __real_sem_destroy(&iargs.sync); return -1; } while (__real_sem_wait(&iargs.sync) && errno == EINTR) ; __real_sem_destroy(&iargs.sync); return iargs.tid; }
int __wrap_pthread_create(pthread_t* thread, const pthread_attr_t* attr, void *(*start_routine) (void *), void* arg) { auto info = new HPHP::PthreadInfo(start_routine, arg); int ret = __real_pthread_create(thread, attr, HPHP::start_routine_wrapper, info); { HPHP::Lock lock(HPHP::threadMap_lock); auto res = HPHP::threadMap.emplace(*thread, info); if (!res.second) { HPHP::Logger::Error("pthread_create: thread already exists"); } } return ret; }