From 895efd9edc7f20e6d7e7599949e5a4e987a3ff7f Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 7 Jun 1996 13:54:23 +0000 Subject: key destructor is now run at correct point in pthread_exit() sequence and should be correct for other apis as well. missing page numbers added on some references. initial attempt at sig_procmask() and pthread_sigmask(). --- cpukit/posix/src/key.c | 4 +- cpukit/posix/src/psignal.c | 142 +++++++++++++++++++++++++++++++++------------ cpukit/posix/src/pthread.c | 131 +++++++++++++++++++++-------------------- 3 files changed, 173 insertions(+), 104 deletions(-) (limited to 'cpukit') diff --git a/cpukit/posix/src/key.c b/cpukit/posix/src/key.c index 5a6cc4b4f3..bb46d995a2 100644 --- a/cpukit/posix/src/key.c +++ b/cpukit/posix/src/key.c @@ -204,8 +204,6 @@ int pthread_key_delete( * * NOTE: This is the routine executed when a thread exits to * run through all the keys and do the destructor action. - * - * XXX: This needs to be hooked to the thread exitting -- SOMEHOW. */ void _POSIX_Keys_Run_destructors( @@ -252,6 +250,8 @@ void _POSIX_Keys_Run_destructors( /* * The standard allows one to not do this and thus go into an infinite * loop. It seems rude to unnecessarily lock up a system. + * + * Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99. */ if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS ) diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c index b0c79b9589..7988e800e5 100644 --- a/cpukit/posix/src/psignal.c +++ b/cpukit/posix/src/psignal.c @@ -8,40 +8,36 @@ #include #include +#include +#include /* - * Currently only 20 signals numbered 1-20 are defined + * Currently 32 signals numbered 1-32 are defined */ -#define SIGNAL_ALL_MASK 0x000fffff +#define SIGNAL_EMPTY_MASK 0x00000000 +#define SIGNAL_ALL_MASK 0xffffffff #define signo_to_mask( _sig ) (1 << ((_sig) - 1)) #define is_valid_signo( _sig ) \ ((signo_to_mask(_sig) & SIGNAL_ALL_MASK) != 0 ) -/* - * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 +/*** PROCESS WIDE STUFF ****/ + +sigset_t _POSIX_signals_Blocked = SIGNAL_EMPTY_MASK; +sigset_t _POSIX_signals_Pending = SIGNAL_EMPTY_MASK; + +struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ]; + +/*PAGE * - * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS. + * _POSIX_signals_Manager_Initialization */ -int kill( - pid_t pid, - int sig -) +void _POSIX_signals_Manager_Initialization( void ) { - /* - * Only supported for the "calling process" (i.e. this node). - */ - - assert( pid == getpid() ); - - /* SIGABRT comes from abort via assert */ - if ( sig == SIGABRT ) { - exit( 1 ); - } - return POSIX_NOT_IMPLEMENTED(); + /* XXX install default actions for all vectors */ } /* @@ -52,7 +48,8 @@ int sigemptyset( sigset_t *set ) { - assert( set ); /* no word from posix, solaris returns EFAULT */ + if ( !set ) + set_errno_and_return_minus_one( EFAULT ); *set = 0; return 0; @@ -66,7 +63,8 @@ int sigfillset( sigset_t *set ) { - assert( set ); + if ( !set ) + set_errno_and_return_minus_one( EFAULT ); *set = SIGNAL_ALL_MASK; return 0; @@ -81,12 +79,11 @@ int sigaddset( int signo ) { - assert( set ); + if ( !set ) + set_errno_and_return_minus_one( EFAULT ); - if ( !is_valid_signo(signo) ) { - errno = EINVAL; - return -1; - } + if ( !is_valid_signo(signo) ) + set_errno_and_return_minus_one( EINVAL ); *set |= signo_to_mask(signo); return 0; @@ -101,12 +98,11 @@ int sigdelset( int signo ) { - assert( set ); + if ( !set ) + set_errno_and_return_minus_one( EFAULT ); - if ( !is_valid_signo(signo) ) { - errno = EINVAL; - return -1; - } + if ( !is_valid_signo(signo) ) + set_errno_and_return_minus_one( EINVAL ); *set &= ~signo_to_mask(signo); return 0; @@ -121,12 +117,11 @@ int sigismember( int signo ) { - assert( set ); + if ( !set ) + set_errno_and_return_minus_one( EFAULT ); - if ( !is_valid_signo(signo) ) { - errno = EINVAL; - return -1; - } + if ( !is_valid_signo(signo) ) + set_errno_and_return_minus_one( EINVAL ); if ( *set & signo_to_mask(signo) ) return 1; @@ -144,6 +139,19 @@ int sigaction( struct sigaction *oact ) { + if ( !act ) + set_errno_and_return_minus_one( EFAULT ); + + if ( !is_valid_signo(sig) ) + set_errno_and_return_minus_one( EINVAL ); + + if ( oact ) + *oact = _POSIX_signals_Vectors[ sig ]; + + /* XXX need to interpret some stuff here */ + + _POSIX_signals_Vectors[ sig ] = *act; + return POSIX_NOT_IMPLEMENTED(); } @@ -151,6 +159,7 @@ int sigaction( * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 * * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). + * */ int sigprocmask( @@ -159,7 +168,11 @@ int sigprocmask( sigset_t *oset ) { - return POSIX_NOT_IMPLEMENTED(); + /* + * P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask. + */ + + return pthread_sigmask( how, set, oset ); } /* @@ -174,6 +187,35 @@ int pthread_sigmask( sigset_t *oset ) { + POSIX_API_Control *api; + + if ( !set && !oset ) + set_errno_and_return_minus_one( EFAULT ); + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + if ( oset ) + *oset = api->signals_blocked; + + if ( !set ) + set_errno_and_return_minus_one( EFAULT ); + + switch ( how ) { + case SIG_BLOCK: + api->signals_blocked |= *set; + break; + case SIG_UNBLOCK: + api->signals_blocked &= ~*set; + break; + case SIG_SETMASK: + api->signals_blocked = *set; + break; + default: + set_errno_and_return_minus_one( EINVAL ); + } + + /* XXX evaluate the new set */ + return POSIX_NOT_IMPLEMENTED(); } @@ -255,6 +297,30 @@ int sigqueue( return POSIX_NOT_IMPLEMENTED(); } +/* + * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 + * + * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS. + */ + +int kill( + pid_t pid, + int sig +) +{ + /* + * Only supported for the "calling process" (i.e. this node). + */ + + assert( pid == getpid() ); + + /* SIGABRT comes from abort via assert */ + if ( sig == SIGABRT ) { + exit( 1 ); + } + return POSIX_NOT_IMPLEMENTED(); +} + /* * 3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43 */ diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index be39656e42..484b93e847 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /*PAGE @@ -82,10 +83,10 @@ void _POSIX_Threads_Sporadic_budget_callout( { POSIX_API_Control *api; - /* XXX really should be based on MAX_U32 */ - api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + /* XXX really should be based on MAX_U32 */ + the_thread->cpu_time_budget = 0xFFFFFFFF; _Thread_Change_priority( @@ -115,16 +116,35 @@ boolean _POSIX_Threads_Create_extension( created->API_Extensions[ THREAD_API_POSIX ] = api; - /* XXX something should go here */ + api->Attributes = _POSIX_Threads_Default_attributes; + api->detachstate = _POSIX_Threads_Default_attributes.detachstate; + api->schedpolicy = _POSIX_Threads_Default_attributes.schedpolicy; + api->schedparam = _POSIX_Threads_Default_attributes.schedparam; + api->schedparam.sched_priority = + _POSIX_Priority_From_core( created->current_priority ); + + _Thread_queue_Initialize( + &api->Join_List, + OBJECTS_NO_CLASS, /* only used for proxy operations */ + THREAD_QUEUE_DISCIPLINE_FIFO, + STATES_WAITING_FOR_JOIN_AT_EXIT, + NULL, /* no extract proxy handler */ + 0 + ); + + _Watchdog_Initialize( + &api->Sporadic_timer, + _POSIX_Threads_Sporadic_budget_TSR, + created->Object.id, + created + ); return TRUE; } - + /*PAGE * * _POSIX_Threads_Delete_extension - * - * XXX */ User_extensions_routine _POSIX_Threads_Delete_extension( @@ -132,11 +152,31 @@ User_extensions_routine _POSIX_Threads_Delete_extension( Thread_Control *deleted ) { + Thread_Control *the_thread; + POSIX_API_Control *api; + void **value_ptr; + (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_POSIX ] ); deleted->API_Extensions[ THREAD_API_POSIX ] = NULL; - /* XXX run _POSIX_Keys_Run_destructors here? */ + /* XXX run cancellation handlers */ + + _POSIX_Keys_Run_destructors( deleted ); + + /* + * Wakeup all the tasks which joined with this one + */ + + api = deleted->API_Extensions[ THREAD_API_POSIX ]; + + value_ptr = (void **) deleted->Wait.return_argument; + + while ( (the_thread = _Thread_queue_Dequeue( &api->Join_List )) ) + *(void **)the_thread->Wait.return_argument = value_ptr; + + if ( api->schedpolicy == SCHED_SPORADIC ) + (void) _Watchdog_Remove( &api->Sporadic_timer ); } /*PAGE @@ -754,7 +794,7 @@ int pthread_create( #endif /* - * P1003.1c/D10, p. 121. + * P1003.1c/Draft 10, p. 121. * * If inheritsched is set to PTHREAD_INHERIT_SCHED, then this thread * inherits scheduling attributes from the creating thread. If it is @@ -894,15 +934,6 @@ int pthread_create( api->schedpolicy = schedpolicy; api->schedparam = schedparam; - _Thread_queue_Initialize( - &api->Join_List, - OBJECTS_NO_CLASS, /* only used for proxy operations */ - THREAD_QUEUE_DISCIPLINE_FIFO, - 0, /* XXX join blocking state */ - NULL, /* no extract proxy handler */ - 0 - ); - /* * POSIX threads are allocated and started in one operation. */ @@ -916,13 +947,6 @@ int pthread_create( ); if ( schedpolicy == SCHED_SPORADIC ) { - _Watchdog_Initialize( - &api->Sporadic_timer, - _POSIX_Threads_Sporadic_budget_TSR, - the_thread->Object.id, - the_thread - ); - _Watchdog_Insert_ticks( &api->Sporadic_timer, _POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period ) @@ -977,14 +1001,19 @@ int pthread_join( return EINVAL; } + if ( _Thread_Is_executing( the_thread ) ) { + _Thread_Enable_dispatch(); + return EDEADLK; + } + /* * Put ourself on the threads join list */ - /* XXX is this right? */ - _Thread_Executing->Wait.return_argument = (unsigned32 *) value_ptr; + _Thread_queue_Enter_critical_section( &api->Join_List ); + _Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT ); _Thread_Enable_dispatch(); @@ -1026,45 +1055,29 @@ int pthread_detach( /*PAGE * - * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150 + * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150 + * + * NOTE: Key destructors are executed in the POSIX api delete extension. */ void pthread_exit( void *value_ptr ) { - register Thread_Control *executing; - register Thread_Control *the_thread; - POSIX_API_Control *api; - - executing = _Thread_Executing; - _Thread_Disable_dispatch(); - _Thread_Close( &_POSIX_Threads_Information, executing ); + _Thread_Executing->Wait.return_argument = (unsigned32 *)value_ptr; - /* - * Wakeup all the tasks which joined with this one - */ - - api = executing->API_Extensions[ THREAD_API_POSIX ]; - - while ( (the_thread = _Thread_queue_Dequeue( &api->Join_List )) ) - *(void **)the_thread->Wait.return_argument = value_ptr; - - if ( api->schedpolicy == SCHED_SPORADIC ) - (void) _Watchdog_Remove( &api->Sporadic_timer ); - - /* XXX run _POSIX_Keys_Run_destructors here? */ + _Thread_Close( &_POSIX_Threads_Information, _Thread_Executing ); - _POSIX_Threads_Free( executing ); + _POSIX_Threads_Free( _Thread_Executing ); _Thread_Enable_dispatch(); } /*PAGE * - * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX + * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. 152 */ pthread_t pthread_self( void ) @@ -1138,7 +1151,7 @@ int pthread_equal( /*PAGE * - * 16.1.8 Dynamic Package Initialization + * 16.1.8 Dynamic Package Initialization, P1003.1c/Draft 10, p. 154 */ int pthread_once( @@ -1146,25 +1159,15 @@ int pthread_once( void (*init_routine)(void) ) { - /* XXX: Should we implement this routine this way or make it a full */ - /* XXX: fledged object? */ - if ( !once_control || !init_routine ) return EINVAL; _Thread_Disable_dispatch(); - if ( !once_control->is_initialized ) { - + if ( !once_control->init_executed ) { once_control->is_initialized = TRUE; once_control->init_executed = TRUE; (*init_routine)(); - - } if ( !once_control->init_executed ) { - - once_control->init_executed = TRUE; - (*init_routine)(); - } _Thread_Enable_dispatch(); @@ -1173,7 +1176,7 @@ int pthread_once( /*PAGE * - * 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58 + * 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/Draft 8, p. 58 */ int pthread_getcpuclockid( @@ -1186,7 +1189,7 @@ int pthread_getcpuclockid( /*PAGE * - * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59 + * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59 */ int pthread_attr_setcputime( @@ -1210,7 +1213,7 @@ int pthread_attr_setcputime( /*PAGE * - * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59 + * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59 */ int pthread_attr_getcputime( -- cgit v1.2.3