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().
This commit is contained in:
Joel Sherrill
1996-06-07 13:54:23 +00:00
parent fce2e9dab3
commit 895efd9edc
6 changed files with 346 additions and 208 deletions

View File

@@ -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 )

View File

@@ -8,40 +8,36 @@
#include <rtems/system.h>
#include <rtems/score/thread.h>
#include <rtems/posix/seterr.h>
#include <rtems/posix/threadsup.h>
/*
* 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
*/

View File

@@ -16,6 +16,7 @@
#include <rtems/posix/pthread.h>
#include <rtems/posix/priority.h>
#include <rtems/posix/config.h>
#include <rtems/posix/key.h>
#include <rtems/posix/time.h>
/*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
*/
_Thread_Close( &_POSIX_Threads_Information, _Thread_Executing );
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? */
_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(