/* ------------------------------------------------------------------- * 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
/* ------------------------------------------------------------------- * 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
/* ------------------------------------------------------------------- * Start the specified object's thread execution. Increments thread * count, spawns new thread, and stores thread ID. * ------------------------------------------------------------------- */ void thread_start( struct thread_Settings* thread ) { // Make sure this object has not been started already if ( thread_equalid( thread->mTID, thread_zeroid() ) ) { // Check if we need to start another thread before this one if ( thread->runNow != NULL ) { thread_start( thread->runNow ); } // increment thread count Condition_Lock( thread_sNum_cond ); thread_sNum++; Condition_Unlock( thread_sNum_cond ); #if defined( HAVE_POSIX_THREAD ) // pthreads -- spawn new thread if ( pthread_create( &thread->mTID, NULL, thread_run_wrapper, thread ) != 0 ) { WARN( 1, "pthread_create" ); // decrement thread count Condition_Lock( thread_sNum_cond ); thread_sNum--; Condition_Unlock( thread_sNum_cond ); } #elif defined( HAVE_WIN32_THREAD ) // Win32 threads -- spawn new thread // Win32 has a thread handle in addition to the thread ID thread->mHandle = CreateThread( NULL, 0, thread_run_wrapper, thread, 0, &thread->mTID ); if ( thread->mHandle == NULL ) { WARN( 1, "CreateThread" ); // decrement thread count Condition_Lock( thread_sNum_cond ); thread_sNum--; Condition_Unlock( thread_sNum_cond ); } #else // single-threaded -- call Run_Wrapper in this thread thread_run_wrapper( thread ); #endif } } // end thread_start
/* ------------------------------------------------------------------- * Start the specified object's thread execution. Increments thread * count, spawns new thread, and stores thread ID. * ------------------------------------------------------------------- */ void thread_start( struct thread_Settings* thread ) { // Make sure this object has not been started already if ( thread_equalid( thread->mTID, thread_zeroid() ) ) { // Check if we need to start another thread before this one if ( thread->runNow != NULL ) { thread_start( thread->runNow ); } // increment thread count Condition_Lock( thread_sNum_cond ); IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Incrementing thread count from %d to %d.\r\n", thread_sNum, (thread_sNum + 1) ) ); thread_sNum++; Condition_Unlock( thread_sNum_cond ); IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE | IPERF_DBG_STATE, ( "Spawning %s thread.\r\n", thread_names[thread->mThreadMode] ) ); #if defined( HAVE_POSIX_THREAD ) // pthreads -- spawn new thread if ( pthread_create( &thread->mTID, NULL, thread_run_wrapper, thread ) != 0 ) { WARN( 1, ( "pthread_create failed!\r\n" ) ); // 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--; Condition_Unlock( thread_sNum_cond ); } #elif defined( HAVE_WIN32_THREAD ) // Win32 threads -- spawn new thread // Win32 has a thread handle in addition to the thread ID thread->mHandle = CreateThread( NULL, 0, thread_run_wrapper, thread, 0, &thread->mTID ); if ( thread->mHandle == NULL ) { WARN( 1, ( "CreateThread failed!\r\n" ) ); // 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--; Condition_Unlock( thread_sNum_cond ); } #else // single-threaded -- call Run_Wrapper in this thread thread_run_wrapper( thread ); #endif /* HAVE_POSIX_THREAD */ } } // end thread_start