/* システムコールの呼び出し */ static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p) { switch (type) { /* kz_run() */ case KZ_SYSCALL_TYPE_RUN: p->un.run.ret = thread_run(p->un.run.func, p->un.run.name, p->un.run.priority, p->un.run.stacksize, p->un.run.argc, p->un.run.argv); break; /* kz_exit() */ case KZ_SYSCALL_TYPE_EXIT: thread_exit(); break; /* kz_wait() */ case KZ_SYSCALL_TYPE_WAIT: p->un.wait.ret = thread_wait(); break; /* kz_sleep() */ case KZ_SYSCALL_TYPE_SLEEP: p->un.sleep.ret = thread_sleep(); break; /* kz_wakeup() */ case KZ_SYSCALL_TYPE_WAKEUP: p->un.wakeup.ret = thread_wakeup(p->un.wakeup.id); break; /* kz_getid() */ case KZ_SYSCALL_TYPE_GETID: p->un.getid.ret = thread_getid(); break; /* kz_chpri() */ case KZ_SYSCALL_TYPE_CHPRI: p->un.chpri.ret = thread_chpri(p->un.chpri.priority); break; /* kz_kmalloc() */ case KZ_SYSCALL_TYPE_KMALLOC: p->un.kmalloc.ret = thread_kmalloc(p->un.kmalloc.size); break; /* kz_kmfree() */ case KZ_SYSCALL_TYPE_KMFREE: p->un.kmfree.ret = thread_kmfree(p->un.kmfree.p); break; default: break; } }
/* ------------------------------------------------------------------- * Signal handler sets the sInterupted flag, so the object can * respond appropriately.. [static] * ------------------------------------------------------------------- */ void Sig_Interupt( int inSigno ) { #ifdef HAVE_THREAD // We try to not allow a single interrupt handled by multiple threads // to completely kill the app so we save off the first thread ID // then that is the only thread that can supply the next interrupt if ( thread_equalid( sThread, thread_zeroid() ) ) { sThread = thread_getid(); } else if ( thread_equalid( sThread, thread_getid() ) ) { sig_exit( inSigno ); } // global variable used by threads to see if they were interrupted sInterupted = 1; // with threads, stop waiting for non-terminating threads // (ie Listener Thread) thread_release_nonterm( 1 ); #else // without threads, just exit quietly, same as sig_exit() sig_exit( inSigno ); #endif /* HAVE_THREAD */ } // end Sig_Interupt
static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p) { /* システム・コールの実行中にcurrentが書き換わるので注意 */ switch (type) { case KZ_SYSCALL_TYPE_RUN: /* kz_run() */ p->un.run.ret = thread_run(p->un.run.func, p->un.run.name, p->un.run.priority, p->un.run.stacksize, p->un.run.argc, p->un.run.argv); break; case KZ_SYSCALL_TYPE_EXIT: /* kz_exit() */ /* TCBが消去されるので,戻り値を書き込んではいけない */ thread_exit(); break; case KZ_SYSCALL_TYPE_WAIT: /* kz_wait() */ p->un.wait.ret = thread_wait(); break; case KZ_SYSCALL_TYPE_SLEEP: /* kz_sleep() */ p->un.sleep.ret = thread_sleep(); break; case KZ_SYSCALL_TYPE_WAKEUP: /* kz_wakeup() */ p->un.wakeup.ret = thread_wakeup(p->un.wakeup.id); break; case KZ_SYSCALL_TYPE_GETID: /* kz_getid() */ p->un.getid.ret = thread_getid(); break; case KZ_SYSCALL_TYPE_CHPRI: /* kz_chpri() */ p->un.chpri.ret = thread_chpri(p->un.chpri.priority); break; case KZ_SYSCALL_TYPE_KMALLOC: /* kz_kmalloc() */ p->un.kmalloc.ret = thread_kmalloc(p->un.kmalloc.size); break; case KZ_SYSCALL_TYPE_KMFREE: /* kz_kmfree() */ p->un.kmfree.ret = thread_kmfree(p->un.kmfree.p); break; case KZ_SYSCALL_TYPE_SEND: /* kz_send() */ p->un.send.ret = thread_send(p->un.send.id, p->un.send.size, p->un.send.p); break; case KZ_SYSCALL_TYPE_RECV: /* kz_recv() */ p->un.recv.ret = thread_recv(p->un.recv.id, p->un.recv.sizep, p->un.recv.pp); break; case KZ_SYSCALL_TYPE_SETINTR: /* kz_setintr() */ p->un.setintr.ret = thread_setintr(p->un.setintr.type, p->un.setintr.handler); break; default: break; } }
static int vmthread_new (lua_State *L, struct sys_vmthread **vmtdp) { struct sys_vmthread *vmtd; lua_pushthread(L); vmtd = lua_newuserdata(L, sizeof(struct sys_vmthread)); memset(vmtd, 0, sizeof(struct sys_vmthread)); vmtd->td.L = L; vmtd->td.tid = thread_getid(); vmtd->td.vmtd = vmtd; /* vm-mutex destructor */ lua_pushlightuserdata(L, &g_TLSIndex); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, -1); lua_setmetatable(L, -3); lua_pushlightuserdata(L, vmtd); lua_pushvalue(L, -3); /* thread_udata */ lua_rawset(L, -3); lua_pop(L, 1); if (thread_event_new(&vmtd->bufev)) return -1; #ifndef _WIN32 vmtd->td.mutex = &vmtd->vmmutex; if (thread_critsect_new(vmtd->td.mutex)) { thread_event_del(&vmtd->bufev); return -1; } #else if (thread_critsect_new(&vmtd->bufcs)) { thread_event_del(&vmtd->bufev); return -1; } vmtd->td.mutex = CreateMutex(NULL, FALSE, NULL); if (!vmtd->td.mutex) { thread_event_del(&vmtd->bufev); thread_critsect_del(&vmtd->bufcs); return -1; } #endif *vmtdp = vmtd; return 0; }
/* ------------------------------------------------------------------- * Stop the specified object's thread execution (if any) immediately. * Decrements thread count and resets the thread ID. * ------------------------------------------------------------------- */ void thread_stop( struct thread_Settings* thread ) { #ifdef HAVE_THREAD // Make sure we have been started if ( ! thread_equalid( thread->mTID, thread_zeroid() ) ) { // decrement thread count Condition_Lock( thread_sNum_cond ); IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Decrementing thread count from %d to %d.\r\n", thread_sNum, (thread_sNum - 1) ) ); thread_sNum--; IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Signaling thread_sNum_cond condition.\r\n" ) ); Condition_Signal( &thread_sNum_cond ); Condition_Unlock( thread_sNum_cond ); // use exit() if called from within this thread // use cancel() if called from a different thread if ( thread_equalid( thread_getid(), thread->mTID ) ) { // Destroy the object Settings_Destroy( thread ); // Exit #if defined( HAVE_POSIX_THREAD ) IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Exiting %s thread.\r\n", thread_names[thread->mThreadMode] ) ); pthread_exit( NULL ); #elif defined( HAVE_WIN32_THREAD ) IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Exiting %s thread.\r\n", thread_names[thread->mThreadMode] ) ); CloseHandle( thread->mHandle ); ExitThread( 0 ); #endif /* HAVE_POSIX_THREAD */ } else { // Cancel #if defined( HAVE_POSIX_THREAD ) // Cray J90 doesn't have pthread_cancel; Iperf works okay without #ifdef HAVE_PTHREAD_CANCEL IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Canceling %s thread.\r\n", thread_names[thread->mThreadMode] ) ); pthread_cancel( thread->mTID ); #endif /* HAVE_PTHREAD_CANCEL */ #elif defined(HAVE_WIN32_THREAD) // this is a somewhat dangerous function; it's not // suggested to Stop() threads a lot. IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Terminating %s thread.\r\n", thread_names[thread->mThreadMode] ) ); TerminateThread( thread->mHandle, 0 ); #endif /* HAVE_POSIX_THREAD */ // Destroy the object only after killing the thread Settings_Destroy( thread ); } } #endif /* HAVE_THREAD */ } // end thread_stop
/* ------------------------------------------------------------------- * Stop the specified object's thread execution (if any) immediately. * Decrements thread count and resets the thread ID. * ------------------------------------------------------------------- */ void thread_stop( struct thread_Settings* thread ) { #ifdef HAVE_THREAD // Make sure we have been started if ( ! thread_equalid( thread->mTID, thread_zeroid() ) ) { // decrement thread count Condition_Lock( thread_sNum_cond ); thread_sNum--; Condition_Signal( &thread_sNum_cond ); Condition_Unlock( thread_sNum_cond ); // use exit() if called from within this thread // use cancel() if called from a different thread if ( thread_equalid( thread_getid(), thread->mTID ) ) { // Destroy the object Settings_Destroy( thread ); // Exit #if defined( HAVE_POSIX_THREAD ) pthread_exit( NULL ); #else // Win32 CloseHandle( thread->mHandle ); ExitThread( 0 ); #endif } else { // Cancel #if defined( HAVE_POSIX_THREAD ) // Cray J90 doesn't have pthread_cancel; Iperf works okay without #ifdef HAVE_PTHREAD_CANCEL pthread_cancel( thread->mTID ); #endif #else // Win32 // this is a somewhat dangerous function; it's not // suggested to Stop() threads a lot. TerminateThread( thread->mHandle, 0 ); #endif // Destroy the object only after killing the thread Settings_Destroy( thread ); } } #endif } // end Stop
struct sys_thread * sys_new_thread (struct sys_thread *td) { lua_State *L = td->L; lua_State *NL; struct sys_thread *ntd; NL = lua_newthread(L); if (!NL) return NULL; ntd = lua_newuserdata(L, sizeof(struct sys_thread)); memset(ntd, 0, sizeof(struct sys_thread)); ntd->mutex = td->mutex; ntd->L = NL; ntd->vmtd = td->vmtd; ntd->tid = thread_getid(); thread_settable(L, NL, ntd->tid); /* save thread to avoid GC */ return ntd; }
DWORD WINAPI #else void* #endif /* HAVE_WIN32_THREAD */ thread_run_wrapper( void* paramPtr ) { struct thread_Settings* thread = (struct thread_Settings*) paramPtr; IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE | IPERF_DBG_STATE, ( "%s thread is now running. ID is %lu.\r\n", thread_names[thread->mThreadMode], (long unsigned) thread_getid() ) ); // which type of object are we switch ( thread->mThreadMode ) { case kMode_Server: { /* Spawn a Server thread with these settings */ server_spawn( thread ); } break; case kMode_Client: { /* Spawn a Client thread with these settings */ client_spawn( thread ); } break; case kMode_Reporter: { /* Spawn a Reporter thread with these settings */ reporter_spawn( thread ); } break; case kMode_Listener: { // Increment the non-terminating thread count thread_register_nonterm(); /* Spawn a Listener thread with these settings */ listener_spawn( thread ); // Decrement the non-terminating thread count thread_unregister_nonterm(); } break; default: { FAIL(1, ( "Unknown Thread Type!\r\n" ), thread); } break; } #ifdef HAVE_POSIX_THREAD // detach Thread. If someone already joined it will not do anything // If noone has then it will free resources upon return from this // function (Run_Wrapper) IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Detaching %s thread.\r\n", thread_names[thread->mThreadMode] ) ); pthread_detach(thread->mTID); #endif /* HAVE_POSIX_THREAD */ // decrement thread count and send condition signal Condition_Lock( thread_sNum_cond ); IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Decrementing thread count from %d to %d.\r\n", thread_sNum, (thread_sNum - 1) ) ); thread_sNum--; IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Signaling thread_sNum_cond condition.\r\n" ) ); Condition_Signal( &thread_sNum_cond ); Condition_Unlock( thread_sNum_cond ); // Check if we need to start up a thread after executing this one if ( thread->runNext != NULL ) { thread_start( thread->runNext ); } // Destroy this thread object Settings_Destroy( thread ); return 0; } // end thread_run_wrapper