mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-21 04:14:26 +08:00
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:
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user