From 03598b162e66b6f3df8d9ed55ac18865c5ad2a22 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 25 Jan 1999 23:20:52 +0000 Subject: Split most of POSIX Threads Manager into multiple files. --- cpukit/posix/src/pthreadcreate.c | 250 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 cpukit/posix/src/pthreadcreate.c (limited to 'cpukit/posix/src/pthreadcreate.c') diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c new file mode 100644 index 0000000000..acbcbfc6cc --- /dev/null +++ b/cpukit/posix/src/pthreadcreate.c @@ -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 +#include + +#include +#include +#include +#include +#include + +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; +} + -- cgit v1.2.3