static int sys_thread_create (struct sys_thread *td, const int is_affin) { #ifndef _WIN32 pthread_attr_t attr; int res; if ((res = pthread_attr_init(&attr))) goto err; if ((res = pthread_attr_setstacksize(&attr, td->vmtd->stack_size))) { pthread_attr_destroy(&attr); goto err; } #ifdef USE_MACH_AFFIN if (is_affin) { res = pthread_create_suspended_np(&td->tid, &attr, (thread_func_t) thread_start, td); if (!res) { mach_port_t mt = pthread_mach_thread_np(td->tid); affin_cpu_set(mt, td->vmtd->cpu); thread_resume(mt); } } else #endif res = pthread_create(&td->tid, &attr, (thread_func_t) thread_start, td); pthread_attr_destroy(&attr); if (!res) { #if defined(USE_PTHREAD_AFFIN) if (is_affin) affin_cpu_set(td->tid, td->vmtd->cpu); #else (void) is_affin; #endif return 0; } err: errno = res; #else unsigned int tid; const uintptr_t hThr = _beginthreadex(NULL, (unsigned int) td->vmtd->stack_size, (thread_func_t) thread_start, td, 0, &tid); (void) is_affin; if (hThr) { td->tid = (HANDLE) hThr; if (is_WinNT && td->vmtd->cpu) affin_cpu_set(td->tid, td->vmtd->cpu); return 0; } #endif return -1; }
int create_bound_thread(pthread_t *tid, int id, void *(*func)(void *), void *arg) { int numcores, pid, rc; numcores = num_phys_cores(); pid = id % numcores; if ((id < 0)) return -1; #ifdef __APPLE__ // Apple bind code thread_affinity_policy_data_t affinityinfo; rc = pthread_create_suspended_np(tid, NULL, func, arg);// TODO: verify value of arg is correct for OSX if (rc != 0) { perror("pthread_create_suspended_np"); return -1; } affinityinfo.affinity_tag = pid+2; // FIXME: confirm +2 rc = thread_policy_set(pthread_mach_thread_np(*tid), THREAD_AFFINITY_POLICY, (int *)&affinityinfo, THREAD_AFFINITY_POLICY_COUNT); if (rc != KERN_SUCCESS) { perror("thread_policy_set"); return -1; } thread_resume(pthread_mach_thread_np(*tid)); #else // Linux bind code struct linux_thread_init_arg *lnxargs; lnxargs = (linux_thread_init_arg *)malloc(sizeof(linux_thread_init_arg));// FIXME: memory leak... lnxargs->func = func; lnxargs->args = arg; lnxargs->proc = pid; rc = pthread_create(tid, NULL, linux_thread_init, lnxargs); if (rc != 0) { perror("pthread_create"); return -1; } #endif return 0; }