DirectThread * direct_thread_self( void ) { DirectThread *thread; direct_once( &thread_init_once, init_once ); thread = pthread_getspecific( thread_key ); // D_MAGIC_ASSERT_IF( thread, DirectThread ); /* Support this function for non-direct threads. */ if (!thread) { // D_DEBUG_AT( Direct_Thread, " -> attaching unknown thread %d\n", direct_gettid() ); thread = direct_calloc( 1, sizeof(DirectThread) ); if (!thread) { D_OOM(); return NULL; } thread->handle.thread = pthread_self(); thread->tid = direct_gettid(); D_MAGIC_SET( thread, DirectThread ); pthread_setspecific( thread_key, thread ); } return thread; }
DirectThread * direct_thread_self( void ) { DirectThread *thread; direct_once( &thread_init_once, init_once ); thread = pthread_getspecific( thread_key ); D_MAGIC_ASSERT_IF( thread, DirectThread ); return thread; }
void direct_thread_set_name( const char *name ) { char *copy; DirectThread *thread; D_DEBUG_AT( Direct_Thread, "%s( '%s' )\n", __FUNCTION__, name ); direct_once( &thread_init_once, init_once ); thread = pthread_getspecific( thread_key ); /* Support this function for non-direct threads. */ if (!thread) { D_DEBUG_AT( Direct_Thread, " -> attaching unknown thread %d\n", direct_gettid() ); thread = D_CALLOC( 1, sizeof(DirectThread) ); if (!thread) { D_OOM(); return; } thread->handle.thread = pthread_self(); thread->tid = direct_gettid(); D_MAGIC_SET( thread, DirectThread ); pthread_setspecific( thread_key, thread ); } else D_DEBUG_AT( Direct_Thread, " -> was '%s' (%d)\n", thread->name, direct_gettid() ); /* Duplicate string. */ copy = D_STRDUP( name ); if (!copy) { D_OOM(); return; } /* Free old string. */ if (thread->name) D_FREE( thread->name ); /* Keep the copy. */ thread->name = copy; }
const char * direct_thread_self_name( void ) { DirectThread *thread; direct_once( &thread_init_once, init_once ); thread = pthread_getspecific( thread_key ); /* * This function is called by debugging functions, e.g. debug messages, assertions etc. * Therefore no assertions are made here, because they would loop forever if they fail. */ return thread ? thread->name : NULL; }
DirectResult direct_thread_init( DirectThread *thread ) { pthread_attr_t attr; struct sched_param param; int policy; int priority; direct_once( &thread_init_once, init_once ); /* Initialize scheduling and other parameters. */ pthread_attr_init( &attr ); #ifdef PTHREAD_EXPLICIT_SCHED pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); #endif /* Select scheduler. */ switch (direct_config->thread_scheduler) { case DCTS_FIFO: policy = SCHED_FIFO; break; case DCTS_RR: policy = SCHED_RR; break; default: policy = SCHED_OTHER; break; } if (pthread_attr_setschedpolicy( &attr, policy )) D_PERROR( "Direct/Thread: Could not set scheduling policy to %s!\n", direct_thread_policy_name(policy) ); /* Read (back) value. */ pthread_attr_getschedpolicy( &attr, &policy ); /* Select priority. */ switch (thread->type) { case DTT_CLEANUP: case DTT_INPUT: case DTT_OUTPUT: case DTT_MESSAGING: case DTT_CRITICAL: priority = thread->type * direct_config->thread_priority_scale / 100; break; default: priority = direct_config->thread_priority; break; } D_DEBUG_AT( Direct_ThreadInit, " -> %s (%d) [%d;%d]\n", direct_thread_policy_name(policy), priority, sched_get_priority_min( policy ), sched_get_priority_max( policy ) ); if (priority < sched_get_priority_min( policy )) priority = sched_get_priority_min( policy ); if (priority > sched_get_priority_max( policy )) priority = sched_get_priority_max( policy ); param.sched_priority = priority; if (pthread_attr_setschedparam( &attr, ¶m )) D_PERROR( "Direct/Thread: Could not set scheduling priority to %d!\n", priority ); /* Select stack size? */ if (direct_config->thread_stack_size > 0) { if (pthread_attr_setstacksize( &attr, direct_config->thread_stack_size )) D_PERROR( "Direct/Thread: Could not set stack size to %d!\n", direct_config->thread_stack_size ); } if (pthread_create( &thread->handle.thread, &attr, direct_thread_main, thread )) return errno2result( errno ); pthread_attr_destroy( &attr ); /* Read (back) value. */ pthread_getattr_np( thread->handle.thread, &attr ); pthread_attr_getstacksize( &attr, &thread->stack_size ); pthread_attr_getschedparam( &attr, ¶m ); thread->priority = param.sched_priority; pthread_attr_destroy( &attr ); return DR_OK; }