Split most of POSIX Threads Manager into multiple files.

This commit is contained in:
Joel Sherrill
1999-01-25 23:20:52 +00:00
parent 535db3ae0c
commit 03598b162e
61 changed files with 2709 additions and 1915 deletions

View File

@@ -15,7 +15,21 @@ ENOSYS_C_PIECES=\
execl execle execlp execv execve execvp fork \
pthreadatfork wait waitpid
C_PIECES= adasupp cond getpid key mutex pthread psignal sched time \
PTHREAD_PIECES=\
pthread pthreadsetcputime pthreadgetcputime pthreadgetcpuclockid \
pthreadonce pthreadequal pthreadself pthreadexit pthreaddetach \
pthreadjoin pthreadcreate \
pthreadattrsetdetachstate pthreadattrgetdetachstate \
pthreadattrgetstackaddr pthreadattrsetstackaddr \
pthreadattrgetstacksize pthreadattrsetstacksize \
pthreadattrinit pthreadattrdestroy \
pthreadsetschedparam pthreadgetschedparam \
pthreadattrsetschedparam pthreadattrgetschedparam \
pthreadattrgetschedpolicy pthreadattrsetschedpolicy \
pthreadattrgetinheritsched pthreadattrsetinheritsched \
pthreadattrgetscope pthreadattrsetscope
C_PIECES= adasupp cond getpid key mutex $(PTHREAD_PIECES) psignal sched time \
types unistd $(ENOSYS_C_PIECES)
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)

View File

@@ -354,960 +354,3 @@ void _POSIX_Threads_Manager_initialization(
*/
}
/*PAGE
*
* 3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
*
* RTEMS does not support processes, so we fall under this and do not
* provide this routine:
*
* "Either the implementation shall support the pthread_atfork() function
* as described above or the pthread_atfork() funciton shall not be
* provided."
*/
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_setscope(
pthread_attr_t *attr,
int contentionscope
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( contentionscope ) {
case PTHREAD_SCOPE_PROCESS:
attr->contentionscope = contentionscope;
return 0;
case PTHREAD_SCOPE_SYSTEM:
return ENOTSUP;
default:
return EINVAL;
}
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_getscope(
const pthread_attr_t *attr,
int *contentionscope
)
{
if ( !attr || !attr->is_initialized || !contentionscope )
return EINVAL;
*contentionscope = attr->contentionscope;
return 0;
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_setinheritsched(
pthread_attr_t *attr,
int inheritsched
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( inheritsched ) {
case PTHREAD_INHERIT_SCHED:
case PTHREAD_EXPLICIT_SCHED:
attr->inheritsched = inheritsched;
return 0;
default:
return ENOTSUP;
}
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_getinheritsched(
const pthread_attr_t *attr,
int *inheritsched
)
{
if ( !attr || !attr->is_initialized || !inheritsched )
return EINVAL;
*inheritsched = attr->inheritsched;
return 0;
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_setschedpolicy(
pthread_attr_t *attr,
int policy
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( policy ) {
case SCHED_OTHER:
case SCHED_FIFO:
case SCHED_RR:
case SCHED_SPORADIC:
attr->schedpolicy = policy;
return 0;
default:
return ENOTSUP;
}
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_getschedpolicy(
const pthread_attr_t *attr,
int *policy
)
{
if ( !attr || !attr->is_initialized || !policy )
return EINVAL;
*policy = attr->schedpolicy;
return 0;
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_setschedparam(
pthread_attr_t *attr,
const struct sched_param *param
)
{
if ( !attr || !attr->is_initialized || !param )
return EINVAL;
attr->schedparam = *param;
return 0;
}
/*PAGE
*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*/
int pthread_attr_getschedparam(
const pthread_attr_t *attr,
struct sched_param *param
)
{
if ( !attr || !attr->is_initialized || !param )
return EINVAL;
*param = attr->schedparam;
return 0;
}
/*PAGE
*
* 13.5.2 Dynamic Thread Scheduling Parameters Access,
* P1003.1c/Draft 10, p. 124
*/
int pthread_getschedparam(
pthread_t thread,
int *policy,
struct sched_param *param
)
{
Objects_Locations location;
POSIX_API_Control *api;
register Thread_Control *the_thread;
if ( !policy || !param )
return EINVAL;
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
*policy = api->schedpolicy;
*param = api->schedparam;
param->sched_priority =
_POSIX_Priority_From_core( the_thread->current_priority );
_Thread_Enable_dispatch();
return 0;
}
return POSIX_BOTTOM_REACHED();
}
/*PAGE
*
* 13.5.2 Dynamic Thread Scheduling Parameters Access,
* P1003.1c/Draft 10, p. 124
*/
int pthread_setschedparam(
pthread_t thread,
int policy,
struct sched_param *param
)
{
register Thread_Control *the_thread;
POSIX_API_Control *api;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
Objects_Locations location;
/*
* Check all the parameters
*/
if ( !param )
return EINVAL;
if ( !_POSIX_Priority_Is_valid( param->sched_priority ) )
return EINVAL;
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
budget_callout = NULL;
switch ( policy ) {
case SCHED_OTHER:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
break;
case SCHED_FIFO:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
break;
case SCHED_RR:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
break;
case SCHED_SPORADIC:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
budget_callout = _POSIX_Threads_Sporadic_budget_callout;
if ( _POSIX_Timespec_to_interval( &param->ss_replenish_period ) <
_POSIX_Timespec_to_interval( &param->ss_initial_budget ) )
return EINVAL;
if ( !_POSIX_Priority_Is_valid( param->ss_low_priority ) )
return EINVAL;
break;
default:
return EINVAL;
}
/*
* Actually change the scheduling policy and parameters
*/
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( api->schedpolicy == SCHED_SPORADIC )
(void) _Watchdog_Remove( &api->Sporadic_timer );
api->schedpolicy = policy;
api->schedparam = *param;
the_thread->budget_algorithm = budget_algorithm;
the_thread->budget_callout = budget_callout;
switch ( api->schedpolicy ) {
case SCHED_OTHER:
case SCHED_FIFO:
case SCHED_RR:
the_thread->cpu_time_budget = _Thread_Ticks_per_timeslice;
the_thread->real_priority =
_POSIX_Priority_To_core( api->schedparam.sched_priority );
_Thread_Change_priority(
the_thread,
the_thread->real_priority,
TRUE
);
break;
case SCHED_SPORADIC:
api->ss_high_priority = api->schedparam.sched_priority;
_POSIX_Threads_Sporadic_budget_TSR( 0, the_thread );
break;
}
_Thread_Enable_dispatch();
return 0;
}
return POSIX_BOTTOM_REACHED();
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_init(
pthread_attr_t *attr
)
{
if ( !attr )
return EINVAL;
*attr = _POSIX_Threads_Default_attributes;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_destroy(
pthread_attr_t *attr
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
attr->is_initialized = FALSE;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_getstacksize(
const pthread_attr_t *attr,
size_t *stacksize
)
{
if ( !attr || !attr->is_initialized || !stacksize )
return EINVAL;
*stacksize = attr->stacksize;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_setstacksize(
pthread_attr_t *attr,
size_t stacksize
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
if (stacksize < PTHREAD_MINIMUM_STACK_SIZE)
attr->stacksize = PTHREAD_MINIMUM_STACK_SIZE;
else
attr->stacksize = stacksize;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_getstackaddr(
const pthread_attr_t *attr,
void **stackaddr
)
{
if ( !attr || !attr->is_initialized || !stackaddr )
return EINVAL;
*stackaddr = attr->stackaddr;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_setstackaddr(
pthread_attr_t *attr,
void *stackaddr
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
attr->stackaddr = stackaddr;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_getdetachstate(
const pthread_attr_t *attr,
int *detachstate
)
{
if ( !attr || !attr->is_initialized || !detachstate )
return EINVAL;
*detachstate = attr->detachstate;
return 0;
}
/*PAGE
*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*/
int pthread_attr_setdetachstate(
pthread_attr_t *attr,
int detachstate
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( detachstate ) {
case PTHREAD_CREATE_DETACHED:
case PTHREAD_CREATE_JOINABLE:
attr->detachstate = detachstate;
return 0;
default:
return EINVAL;
}
}
/*PAGE
*
* 16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
*/
int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)( void * ),
void *arg
)
{
const pthread_attr_t *the_attr;
Priority_Control core_priority;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
boolean is_fp;
boolean status;
Thread_Control *the_thread;
char *default_name = "psx";
POSIX_API_Control *api;
int schedpolicy = SCHED_RR;
struct sched_param schedparam;
the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
if ( !the_attr->is_initialized )
return EINVAL;
/*
* Core Thread Initialize insures we get the minimum amount of
* stack space if it is allowed to allocate it itself.
*/
if ( the_attr->stackaddr && !_Stack_Is_enough( the_attr->stacksize ) )
return EINVAL;
#if 0
int cputime_clock_allowed; /* see time.h */
POSIX_NOT_IMPLEMENTED();
#endif
/*
* 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
* PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the
* attributes structure.
*/
switch ( the_attr->inheritsched ) {
case PTHREAD_INHERIT_SCHED:
api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
schedpolicy = api->schedpolicy;
schedparam = api->schedparam;
break;
case PTHREAD_EXPLICIT_SCHED:
schedpolicy = the_attr->schedpolicy;
schedparam = the_attr->schedparam;
break;
default:
return EINVAL;
}
/*
* Check the contentionscope since rtems only supports PROCESS wide
* contention (i.e. no system wide contention).
*/
if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS )
return ENOTSUP;
/*
* Interpret the scheduling parameters.
*/
if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) )
return EINVAL;
core_priority = _POSIX_Priority_To_core( schedparam.sched_priority );
/*
* Set the core scheduling policy information.
*/
budget_callout = NULL;
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
switch ( schedpolicy ) {
case SCHED_OTHER:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
break;
case SCHED_FIFO:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
break;
case SCHED_RR:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
break;
case SCHED_SPORADIC:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
budget_callout = _POSIX_Threads_Sporadic_budget_callout;
if ( _POSIX_Timespec_to_interval( &schedparam.ss_replenish_period ) <
_POSIX_Timespec_to_interval( &schedparam.ss_initial_budget ) )
return EINVAL;
if ( !_POSIX_Priority_Is_valid( schedparam.ss_low_priority ) )
return EINVAL;
break;
default:
return EINVAL;
}
/*
* Currently all POSIX threads are floating point if the hardware
* supports it.
*/
is_fp = CPU_HARDWARE_FP;
/*
* Disable dispatch for protection
*/
_Thread_Disable_dispatch();
/*
* Allocate the thread control block.
*
* NOTE: Global threads are not currently supported.
*/
the_thread = _POSIX_Threads_Allocate();
if ( !the_thread ) {
_Thread_Enable_dispatch();
return EAGAIN;
}
/*
* Initialize the core thread for this task.
*/
status = _Thread_Initialize(
&_POSIX_Threads_Information,
the_thread,
the_attr->stackaddr,
the_attr->stacksize,
is_fp,
core_priority,
TRUE, /* preemptible */
budget_algorithm,
budget_callout,
0, /* isr level */
&default_name /* posix threads don't have a name */
);
if ( !status ) {
_POSIX_Threads_Free( the_thread );
_Thread_Enable_dispatch();
return EAGAIN;
}
/*
* finish initializing the per API structure
*/
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
api->Attributes = *the_attr;
api->detachstate = the_attr->detachstate;
api->schedpolicy = schedpolicy;
api->schedparam = schedparam;
/*
* This insures we evaluate the process-wide signals pending when we
* first run.
*
* NOTE: Since the thread starts with all unblocked, this is necessary.
*/
the_thread->do_post_task_switch_extension = TRUE;
/*
* POSIX threads are allocated and started in one operation.
*/
status = _Thread_Start(
the_thread,
THREAD_START_POINTER,
start_routine,
arg,
0 /* unused */
);
if ( schedpolicy == SCHED_SPORADIC ) {
_Watchdog_Insert_ticks(
&api->Sporadic_timer,
_POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period )
);
}
/*
* _Thread_Start only fails if the thread was in the incorrect state
*/
if ( !status ) {
_POSIX_Threads_Free( the_thread );
_Thread_Enable_dispatch();
return EINVAL;
}
/*
* Return the id and indicate we successfully created the thread
*/
*thread = the_thread->Object.id;
_Thread_Enable_dispatch();
return 0;
}
/*PAGE
*
* 16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147
*/
int pthread_join(
pthread_t thread,
void **value_ptr
)
{
register Thread_Control *the_thread;
POSIX_API_Control *api;
Objects_Locations location;
void *return_pointer;
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( api->detachstate == PTHREAD_CREATE_DETACHED ) {
_Thread_Enable_dispatch();
return EINVAL;
}
if ( _Thread_Is_executing( the_thread ) ) {
_Thread_Enable_dispatch();
return EDEADLK;
}
/*
* Put ourself on the threads join list
*/
_Thread_Executing->Wait.return_argument = (unsigned32 *) &return_pointer;
_Thread_queue_Enter_critical_section( &api->Join_List );
_Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT );
_Thread_Enable_dispatch();
if ( value_ptr )
*value_ptr = return_pointer;
return 0;
}
return POSIX_BOTTOM_REACHED();
}
/*PAGE
*
* 16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149
*/
int pthread_detach(
pthread_t thread
)
{
register Thread_Control *the_thread;
POSIX_API_Control *api;
Objects_Locations location;
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
api->detachstate = PTHREAD_CREATE_DETACHED;
_Thread_Enable_dispatch();
return 0;
}
return POSIX_BOTTOM_REACHED();
}
/*PAGE
*
* 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
)
{
Objects_Information *the_information;
the_information = _Objects_Get_information( _Thread_Executing->Object.id );
_Thread_Disable_dispatch();
_Thread_Executing->Wait.return_argument = (unsigned32 *)value_ptr;
_Thread_Close( the_information, _Thread_Executing );
_POSIX_Threads_Free( _Thread_Executing );
_Thread_Enable_dispatch();
}
/*PAGE
*
* 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. 152
*/
pthread_t pthread_self( void )
{
return _Thread_Executing->Object.id;
}
/*PAGE
*
* 16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153
*
* NOTE: POSIX does not define the behavior when either thread id is invalid.
*/
int pthread_equal(
pthread_t t1,
pthread_t t2
)
{
/*
* If the system is configured for debug, then we will do everything we
* can to insure that both ids are valid. Otherwise, we will do the
* cheapest possible thing to determine if they are equal.
*/
#ifndef RTEMS_DEBUG
return _Objects_Are_ids_equal( t1, t2 );
#else
int status;
Objects_Locations location;
/*
* By default this is not a match.
*/
status = 0;
/*
* Validate the first id and return 0 if it is not valid
*/
(void) _POSIX_Threads_Get( t1, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
break;
case OBJECTS_LOCAL:
/*
* Validate the second id and return 0 if it is not valid
*/
(void) _POSIX_Threads_Get( t2, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
break;
case OBJECTS_LOCAL:
status = _Objects_Are_ids_equal( t1, t2 );
break;
}
_Thread_Unnest_dispatch();
break;
}
_Thread_Enable_dispatch();
return status;
#endif
}
/*PAGE
*
* 16.1.8 Dynamic Package Initialization, P1003.1c/Draft 10, p. 154
*/
int pthread_once(
pthread_once_t *once_control,
void (*init_routine)(void)
)
{
if ( !once_control || !init_routine )
return EINVAL;
_Thread_Disable_dispatch();
if ( !once_control->init_executed ) {
once_control->is_initialized = TRUE;
once_control->init_executed = TRUE;
(*init_routine)();
}
_Thread_Enable_dispatch();
return 0;
}
/*PAGE
*
* 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/Draft 8, p. 58
*/
int pthread_getcpuclockid(
pthread_t pid,
clockid_t *clock_id
)
{
return POSIX_NOT_IMPLEMENTED();
}
/*PAGE
*
* 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59
*/
int pthread_attr_setcputime(
pthread_attr_t *attr,
int clock_allowed
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( clock_allowed ) {
case CLOCK_ENABLED:
case CLOCK_DISABLED:
attr->cputime_clock_allowed = clock_allowed;
return 0;
default:
return EINVAL;
}
}
/*PAGE
*
* 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59
*/
int pthread_attr_getcputime(
pthread_attr_t *attr,
int *clock_allowed
)
{
if ( !attr || !attr->is_initialized || !clock_allowed )
return EINVAL;
*clock_allowed = attr->cputime_clock_allowed;
return 0;
}

View File

@@ -1,6 +1,15 @@
/*
* pthread_atfork() - POSIX 1003.1b 3.1.3
*
* 3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
*
* RTEMS does not support processes, so we fall under this and do not
* provide this routine:
*
* "Either the implementation shall support the pthread_atfork() function
* as described above or the pthread_atfork() funciton shall not be
* provided."
*
* $Id$
*/

View File

@@ -0,0 +1,30 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
int pthread_attr_destroy(
pthread_attr_t *attr
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
attr->is_initialized = FALSE;
return 0;
}

View File

@@ -0,0 +1,30 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getdetachstate(
const pthread_attr_t *attr,
int *detachstate
)
{
if ( !attr || !attr->is_initialized || !detachstate )
return EINVAL;
*detachstate = attr->detachstate;
return 0;
}

View File

@@ -0,0 +1,30 @@
/*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getinheritsched(
const pthread_attr_t *attr,
int *inheritsched
)
{
if ( !attr || !attr->is_initialized || !inheritsched )
return EINVAL;
*inheritsched = attr->inheritsched;
return 0;
}

View File

@@ -0,0 +1,29 @@
/*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getschedparam(
const pthread_attr_t *attr,
struct sched_param *param
)
{
if ( !attr || !attr->is_initialized || !param )
return EINVAL;
*param = attr->schedparam;
return 0;
}

View File

@@ -0,0 +1,30 @@
/*
* 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getschedpolicy(
const pthread_attr_t *attr,
int *policy
)
{
if ( !attr || !attr->is_initialized || !policy )
return EINVAL;
*policy = attr->schedpolicy;
return 0;
}

View File

@@ -0,0 +1,29 @@
/*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getscope(
const pthread_attr_t *attr,
int *contentionscope
)
{
if ( !attr || !attr->is_initialized || !contentionscope )
return EINVAL;
*contentionscope = attr->contentionscope;
return 0;
}

View File

@@ -0,0 +1,29 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getstackaddr(
const pthread_attr_t *attr,
void **stackaddr
)
{
if ( !attr || !attr->is_initialized || !stackaddr )
return EINVAL;
*stackaddr = attr->stackaddr;
return 0;
}

View File

@@ -0,0 +1,29 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getstacksize(
const pthread_attr_t *attr,
size_t *stacksize
)
{
if ( !attr || !attr->is_initialized || !stacksize )
return EINVAL;
*stacksize = attr->stacksize;
return 0;
}

View File

@@ -0,0 +1,31 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
int pthread_attr_init(
pthread_attr_t *attr
)
{
if ( !attr )
return EINVAL;
*attr = _POSIX_Threads_Default_attributes;
return 0;
}

View File

@@ -0,0 +1,36 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_setdetachstate(
pthread_attr_t *attr,
int detachstate
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( detachstate ) {
case PTHREAD_CREATE_DETACHED:
case PTHREAD_CREATE_JOINABLE:
attr->detachstate = detachstate;
return 0;
default:
return EINVAL;
}
}

View File

@@ -0,0 +1,39 @@
/*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
int pthread_attr_setinheritsched(
pthread_attr_t *attr,
int inheritsched
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( inheritsched ) {
case PTHREAD_INHERIT_SCHED:
case PTHREAD_EXPLICIT_SCHED:
attr->inheritsched = inheritsched;
return 0;
default:
return ENOTSUP;
}
}

View File

@@ -0,0 +1,29 @@
/*
* 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_setschedparam(
pthread_attr_t *attr,
const struct sched_param *param
)
{
if ( !attr || !attr->is_initialized || !param )
return EINVAL;
attr->schedparam = *param;
return 0;
}

View File

@@ -0,0 +1,41 @@
/*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
int pthread_attr_setschedpolicy(
pthread_attr_t *attr,
int policy
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( policy ) {
case SCHED_OTHER:
case SCHED_FIFO:
case SCHED_RR:
case SCHED_SPORADIC:
attr->schedpolicy = policy;
return 0;
default:
return ENOTSUP;
}
}

View File

@@ -0,0 +1,41 @@
/*
* 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
int pthread_attr_setscope(
pthread_attr_t *attr,
int contentionscope
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( contentionscope ) {
case PTHREAD_SCOPE_PROCESS:
attr->contentionscope = contentionscope;
return 0;
case PTHREAD_SCOPE_SYSTEM:
return ENOTSUP;
default:
return EINVAL;
}
}

View File

@@ -0,0 +1,29 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_setstackaddr(
pthread_attr_t *attr,
void *stackaddr
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
attr->stackaddr = stackaddr;
return 0;
}

View File

@@ -0,0 +1,34 @@
/*
* 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
int pthread_attr_setstacksize(
pthread_attr_t *attr,
size_t stacksize
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
if (stacksize < PTHREAD_MINIMUM_STACK_SIZE)
attr->stacksize = PTHREAD_MINIMUM_STACK_SIZE;
else
attr->stacksize = stacksize;
return 0;
}

View File

@@ -0,0 +1,250 @@
/*
* 16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
#include <rtems/posix/pthread.h>
#include <rtems/posix/priority.h>
#include <rtems/posix/time.h>
int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)( void * ),
void *arg
)
{
const pthread_attr_t *the_attr;
Priority_Control core_priority;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
boolean is_fp;
boolean status;
Thread_Control *the_thread;
char *default_name = "psx";
POSIX_API_Control *api;
int schedpolicy = SCHED_RR;
struct sched_param schedparam;
the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
if ( !the_attr->is_initialized )
return EINVAL;
/*
* Core Thread Initialize insures we get the minimum amount of
* stack space if it is allowed to allocate it itself.
*/
if ( the_attr->stackaddr && !_Stack_Is_enough( the_attr->stacksize ) )
return EINVAL;
#if 0
int cputime_clock_allowed; /* see time.h */
POSIX_NOT_IMPLEMENTED();
#endif
/*
* 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
* PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the
* attributes structure.
*/
switch ( the_attr->inheritsched ) {
case PTHREAD_INHERIT_SCHED:
api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
schedpolicy = api->schedpolicy;
schedparam = api->schedparam;
break;
case PTHREAD_EXPLICIT_SCHED:
schedpolicy = the_attr->schedpolicy;
schedparam = the_attr->schedparam;
break;
default:
return EINVAL;
}
/*
* Check the contentionscope since rtems only supports PROCESS wide
* contention (i.e. no system wide contention).
*/
if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS )
return ENOTSUP;
/*
* Interpret the scheduling parameters.
*/
if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) )
return EINVAL;
core_priority = _POSIX_Priority_To_core( schedparam.sched_priority );
/*
* Set the core scheduling policy information.
*/
budget_callout = NULL;
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
switch ( schedpolicy ) {
case SCHED_OTHER:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
break;
case SCHED_FIFO:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
break;
case SCHED_RR:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
break;
case SCHED_SPORADIC:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
budget_callout = _POSIX_Threads_Sporadic_budget_callout;
if ( _POSIX_Timespec_to_interval( &schedparam.ss_replenish_period ) <
_POSIX_Timespec_to_interval( &schedparam.ss_initial_budget ) )
return EINVAL;
if ( !_POSIX_Priority_Is_valid( schedparam.ss_low_priority ) )
return EINVAL;
break;
default:
return EINVAL;
}
/*
* Currently all POSIX threads are floating point if the hardware
* supports it.
*/
is_fp = CPU_HARDWARE_FP;
/*
* Disable dispatch for protection
*/
_Thread_Disable_dispatch();
/*
* Allocate the thread control block.
*
* NOTE: Global threads are not currently supported.
*/
the_thread = _POSIX_Threads_Allocate();
if ( !the_thread ) {
_Thread_Enable_dispatch();
return EAGAIN;
}
/*
* Initialize the core thread for this task.
*/
status = _Thread_Initialize(
&_POSIX_Threads_Information,
the_thread,
the_attr->stackaddr,
the_attr->stacksize,
is_fp,
core_priority,
TRUE, /* preemptible */
budget_algorithm,
budget_callout,
0, /* isr level */
&default_name /* posix threads don't have a name */
);
if ( !status ) {
_POSIX_Threads_Free( the_thread );
_Thread_Enable_dispatch();
return EAGAIN;
}
/*
* finish initializing the per API structure
*/
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
api->Attributes = *the_attr;
api->detachstate = the_attr->detachstate;
api->schedpolicy = schedpolicy;
api->schedparam = schedparam;
/*
* This insures we evaluate the process-wide signals pending when we
* first run.
*
* NOTE: Since the thread starts with all unblocked, this is necessary.
*/
the_thread->do_post_task_switch_extension = TRUE;
/*
* POSIX threads are allocated and started in one operation.
*/
status = _Thread_Start(
the_thread,
THREAD_START_POINTER,
start_routine,
arg,
0 /* unused */
);
if ( schedpolicy == SCHED_SPORADIC ) {
_Watchdog_Insert_ticks(
&api->Sporadic_timer,
_POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period )
);
}
/*
* _Thread_Start only fails if the thread was in the incorrect state
*/
if ( !status ) {
_POSIX_Threads_Free( the_thread );
_Thread_Enable_dispatch();
return EINVAL;
}
/*
* Return the id and indicate we successfully created the thread
*/
*thread = the_thread->Object.id;
_Thread_Enable_dispatch();
return 0;
}

View File

@@ -0,0 +1,46 @@
/*
* 16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
#include <rtems/posix/pthread.h>
int pthread_detach(
pthread_t thread
)
{
register Thread_Control *the_thread;
POSIX_API_Control *api;
Objects_Locations location;
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
api->detachstate = PTHREAD_CREATE_DETACHED;
_Thread_Enable_dispatch();
return 0;
}
return POSIX_BOTTOM_REACHED();
}

View File

@@ -0,0 +1,79 @@
/*
* 16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153
*
* NOTE: POSIX does not define the behavior when either thread id is invalid.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
int pthread_equal(
pthread_t t1,
pthread_t t2
)
{
/*
* If the system is configured for debug, then we will do everything we
* can to insure that both ids are valid. Otherwise, we will do the
* cheapest possible thing to determine if they are equal.
*/
#ifndef RTEMS_DEBUG
return _Objects_Are_ids_equal( t1, t2 );
#else
int status;
Objects_Locations location;
/*
* By default this is not a match.
*/
status = 0;
/*
* Validate the first id and return 0 if it is not valid
*/
(void) _POSIX_Threads_Get( t1, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
break;
case OBJECTS_LOCAL:
/*
* Validate the second id and return 0 if it is not valid
*/
(void) _POSIX_Threads_Get( t2, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
break;
case OBJECTS_LOCAL:
status = _Objects_Are_ids_equal( t1, t2 );
break;
}
_Thread_Unnest_dispatch();
break;
}
_Thread_Enable_dispatch();
return status;
#endif
}

View File

@@ -0,0 +1,43 @@
/*
* 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150
*
* NOTE: Key destructors are executed in the POSIX api delete extension.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
#include <rtems/posix/pthread.h>
void pthread_exit(
void *value_ptr
)
{
Objects_Information *the_information;
the_information = _Objects_Get_information( _Thread_Executing->Object.id );
_Thread_Disable_dispatch();
_Thread_Executing->Wait.return_argument = (unsigned32 *)value_ptr;
_Thread_Close( the_information, _Thread_Executing );
_POSIX_Threads_Free( _Thread_Executing );
_Thread_Enable_dispatch();
}

View File

@@ -0,0 +1,25 @@
/*
* 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/Draft 8, p. 58
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_getcpuclockid(
pthread_t pid,
clockid_t *clock_id
)
{
return POSIX_NOT_IMPLEMENTED();
}

View File

@@ -0,0 +1,29 @@
/*
* 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_getcputime(
pthread_attr_t *attr,
int *clock_allowed
)
{
if ( !attr || !attr->is_initialized || !clock_allowed )
return EINVAL;
*clock_allowed = attr->cputime_clock_allowed;
return 0;
}

View File

@@ -0,0 +1,53 @@
/*
* 13.5.2 Dynamic Thread Scheduling Parameters Access,
* P1003.1c/Draft 10, p. 124
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
int pthread_getschedparam(
pthread_t thread,
int *policy,
struct sched_param *param
)
{
Objects_Locations location;
POSIX_API_Control *api;
register Thread_Control *the_thread;
if ( !policy || !param )
return EINVAL;
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
*policy = api->schedpolicy;
*param = api->schedparam;
param->sched_priority =
_POSIX_Priority_From_core( the_thread->current_priority );
_Thread_Enable_dispatch();
return 0;
}
return POSIX_BOTTOM_REACHED();
}

View File

@@ -0,0 +1,70 @@
/*
* 16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
#include <rtems/posix/pthread.h>
int pthread_join(
pthread_t thread,
void **value_ptr
)
{
register Thread_Control *the_thread;
POSIX_API_Control *api;
Objects_Locations location;
void *return_pointer;
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( api->detachstate == PTHREAD_CREATE_DETACHED ) {
_Thread_Enable_dispatch();
return EINVAL;
}
if ( _Thread_Is_executing( the_thread ) ) {
_Thread_Enable_dispatch();
return EDEADLK;
}
/*
* Put ourself on the threads join list
*/
_Thread_Executing->Wait.return_argument = (unsigned32 *) &return_pointer;
_Thread_queue_Enter_critical_section( &api->Join_List );
_Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT );
_Thread_Enable_dispatch();
if ( value_ptr )
*value_ptr = return_pointer;
return 0;
}
return POSIX_BOTTOM_REACHED();
}

View File

@@ -0,0 +1,40 @@
/*
* 16.1.8 Dynamic Package Initialization, P1003.1c/Draft 10, p. 154
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
int pthread_once(
pthread_once_t *once_control,
void (*init_routine)(void)
)
{
if ( !once_control || !init_routine )
return EINVAL;
_Thread_Disable_dispatch();
if ( !once_control->init_executed ) {
once_control->is_initialized = TRUE;
once_control->init_executed = TRUE;
(*init_routine)();
}
_Thread_Enable_dispatch();
return 0;
}

View File

@@ -0,0 +1,25 @@
/*
* 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. 152
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/score/thread.h>
pthread_t pthread_self( void )
{
return _Thread_Executing->Object.id;
}

View File

@@ -0,0 +1,36 @@
/*
* 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
int pthread_attr_setcputime(
pthread_attr_t *attr,
int clock_allowed
)
{
if ( !attr || !attr->is_initialized )
return EINVAL;
switch ( clock_allowed ) {
case CLOCK_ENABLED:
case CLOCK_DISABLED:
attr->cputime_clock_allowed = clock_allowed;
return 0;
default:
return EINVAL;
}
}

View File

@@ -0,0 +1,126 @@
/*
* 13.5.2 Dynamic Thread Scheduling Parameters Access,
* P1003.1c/Draft 10, p. 124
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <pthread.h>
#include <errno.h>
#include <rtems/system.h>
#include <rtems/posix/pthread.h>
#include <rtems/posix/priority.h>
#include <rtems/posix/time.h>
int pthread_setschedparam(
pthread_t thread,
int policy,
struct sched_param *param
)
{
register Thread_Control *the_thread;
POSIX_API_Control *api;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
Objects_Locations location;
/*
* Check all the parameters
*/
if ( !param )
return EINVAL;
if ( !_POSIX_Priority_Is_valid( param->sched_priority ) )
return EINVAL;
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
budget_callout = NULL;
switch ( policy ) {
case SCHED_OTHER:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
break;
case SCHED_FIFO:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
break;
case SCHED_RR:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
break;
case SCHED_SPORADIC:
budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
budget_callout = _POSIX_Threads_Sporadic_budget_callout;
if ( _POSIX_Timespec_to_interval( &param->ss_replenish_period ) <
_POSIX_Timespec_to_interval( &param->ss_initial_budget ) )
return EINVAL;
if ( !_POSIX_Priority_Is_valid( param->ss_low_priority ) )
return EINVAL;
break;
default:
return EINVAL;
}
/*
* Actually change the scheduling policy and parameters
*/
the_thread = _POSIX_Threads_Get( thread, &location );
switch ( location ) {
case OBJECTS_ERROR:
case OBJECTS_REMOTE:
return ESRCH;
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( api->schedpolicy == SCHED_SPORADIC )
(void) _Watchdog_Remove( &api->Sporadic_timer );
api->schedpolicy = policy;
api->schedparam = *param;
the_thread->budget_algorithm = budget_algorithm;
the_thread->budget_callout = budget_callout;
switch ( api->schedpolicy ) {
case SCHED_OTHER:
case SCHED_FIFO:
case SCHED_RR:
the_thread->cpu_time_budget = _Thread_Ticks_per_timeslice;
the_thread->real_priority =
_POSIX_Priority_To_core( api->schedparam.sched_priority );
_Thread_Change_priority(
the_thread,
the_thread->real_priority,
TRUE
);
break;
case SCHED_SPORADIC:
api->ss_high_priority = api->schedparam.sched_priority;
_POSIX_Threads_Sporadic_budget_TSR( 0, the_thread );
break;
}
_Thread_Enable_dispatch();
return 0;
}
return POSIX_BOTTOM_REACHED();
}