source: rtems/cpukit/posix/src/pthreadcreate.c @ 17508d02

4.104.114.84.95
Last change on this file since 17508d02 was 17508d02, checked in by Joel Sherrill <joel.sherrill@…>, on 07/26/00 at 19:26:28

Port of RTEMS to the Texas Instruments C3x/C4x DSP families including
a BSP (c4xsim) supporting the simulator included with gdb. This port
was done by Joel Sherrill and Jennifer Averett of OAR Corporation.
Also included with this port is a space/time optimization to eliminate
FP context switch management on CPUs without hardware or software FP.

An issue with this port was that sizeof(unsigned32) = sizeof(unsigned8)
on this CPU. This required addressing alignment checks and assumptions
as well as fixing code that assumed sizeof(unsigned32) == 4.

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.OARcorp.com/rtems/license.html.
10 *
11 *  $Id$
12 */
13
14#include <pthread.h>
15#include <errno.h>
16
17#include <rtems/system.h>
18#include <rtems/score/thread.h>
19#include <rtems/posix/pthread.h>
20#include <rtems/posix/priority.h>
21#include <rtems/posix/time.h>
22
23int pthread_create(
24  pthread_t              *thread,
25  const pthread_attr_t   *attr,
26  void                 *(*start_routine)( void * ),
27  void                   *arg
28)
29{
30  const pthread_attr_t               *the_attr;
31  Priority_Control                    core_priority;
32  Thread_CPU_budget_algorithms        budget_algorithm;
33  Thread_CPU_budget_algorithm_callout budget_callout;
34  boolean                             is_fp;
35  boolean                             status;
36  Thread_Control                     *the_thread;
37  POSIX_API_Control                  *api;
38  int                                 schedpolicy = SCHED_RR;
39  struct sched_param                  schedparam;
40
41  the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
42
43  if ( !the_attr->is_initialized )
44    return EINVAL;
45
46  /*
47   *  Core Thread Initialize insures we get the minimum amount of
48   *  stack space if it is allowed to allocate it itself.
49   */
50
51  if ( the_attr->stackaddr && !_Stack_Is_enough( the_attr->stacksize ) )
52    return EINVAL;
53
54#if 0
55  int  cputime_clock_allowed;  /* see time.h */
56  POSIX_NOT_IMPLEMENTED();
57#endif
58
59  /*
60   *  P1003.1c/Draft 10, p. 121.
61   *
62   *  If inheritsched is set to PTHREAD_INHERIT_SCHED, then this thread
63   *  inherits scheduling attributes from the creating thread.   If it is
64   *  PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the
65   *  attributes structure.
66   */
67
68  switch ( the_attr->inheritsched ) {
69    case PTHREAD_INHERIT_SCHED:
70      api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
71      schedpolicy = api->schedpolicy;
72      schedparam  = api->schedparam;
73      break;
74
75    case PTHREAD_EXPLICIT_SCHED:
76      schedpolicy = the_attr->schedpolicy;
77      schedparam  = the_attr->schedparam;
78      break;
79
80    default:
81      return EINVAL;
82  }
83
84  /*
85   *  Check the contentionscope since rtems only supports PROCESS wide
86   *  contention (i.e. no system wide contention).
87   */
88
89  if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS )
90    return ENOTSUP;
91
92  /*
93   *  Interpret the scheduling parameters.
94   */
95
96  if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) )
97    return EINVAL;
98 
99  core_priority = _POSIX_Priority_To_core( schedparam.sched_priority );
100 
101  /*
102   *  Set the core scheduling policy information.
103   */
104
105  budget_callout = NULL;
106  budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
107
108  switch ( schedpolicy ) {
109    case SCHED_OTHER:
110      budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;
111      break;
112     
113    case SCHED_FIFO:
114      budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
115      break;
116
117    case SCHED_RR:
118      budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE;
119      break;
120
121    case SCHED_SPORADIC:
122      budget_algorithm  = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
123      budget_callout = _POSIX_Threads_Sporadic_budget_callout;
124 
125      if ( _POSIX_Timespec_to_interval( &schedparam.ss_replenish_period ) <
126           _POSIX_Timespec_to_interval( &schedparam.ss_initial_budget ) )
127        return EINVAL;
128
129      if ( !_POSIX_Priority_Is_valid( schedparam.ss_low_priority ) )
130        return EINVAL;
131
132      break;
133
134    default:
135      return EINVAL;
136  }
137
138  /*
139   *  Currently all POSIX threads are floating point if the hardware
140   *  supports it.
141   */
142
143
144#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
145  is_fp = TRUE;
146#else
147  is_fp = FALSE;
148#endif
149
150  /*
151   *  Disable dispatch for protection
152   */
153 
154  _Thread_Disable_dispatch();
155 
156  /*
157   *  Allocate the thread control block.
158   *
159   *  NOTE:  Global threads are not currently supported.
160   */
161
162  the_thread = _POSIX_Threads_Allocate();
163
164  if ( !the_thread ) {
165    _Thread_Enable_dispatch();
166    return EAGAIN;
167  }
168
169  /*
170   *  Initialize the core thread for this task.
171   */
172 
173  status = _Thread_Initialize(
174    &_POSIX_Threads_Information,
175    the_thread,
176    the_attr->stackaddr,
177    the_attr->stacksize,
178    is_fp,
179    core_priority,
180    TRUE,                 /* preemptible */
181    budget_algorithm,
182    budget_callout,
183    0,                    /* isr level */
184    NULL                  /* posix threads don't have a name */
185  );
186 
187  if ( !status ) {
188    _POSIX_Threads_Free( the_thread );
189    _Thread_Enable_dispatch();
190    return EAGAIN;
191  }
192
193  /*
194   *  finish initializing the per API structure
195   */
196
197 
198  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
199
200  api->Attributes  = *the_attr;
201  api->detachstate = the_attr->detachstate;
202  api->schedpolicy = schedpolicy;
203  api->schedparam  = schedparam;
204
205  /*
206   *  This insures we evaluate the process-wide signals pending when we
207   *  first run.
208   *
209   *  NOTE:  Since the thread starts with all unblocked, this is necessary.
210   */
211
212  the_thread->do_post_task_switch_extension = TRUE;
213
214  /*
215   *  POSIX threads are allocated and started in one operation.
216   */
217
218  status = _Thread_Start(
219    the_thread,
220    THREAD_START_POINTER,
221    start_routine,
222    arg,
223    0                     /* unused */
224  );
225
226  if ( schedpolicy == SCHED_SPORADIC ) {
227    _Watchdog_Insert_ticks(
228      &api->Sporadic_timer,
229      _POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period )
230    );
231  }
232
233  /*
234   *  _Thread_Start only fails if the thread was in the incorrect state
235   */
236
237  if ( !status ) {
238    _POSIX_Threads_Free( the_thread );
239    _Thread_Enable_dispatch();
240    return EINVAL;
241  }
242
243  /*
244   *  Return the id and indicate we successfully created the thread
245   */
246
247  *thread = the_thread->Object.id;
248
249 _Thread_Enable_dispatch();
250
251 return 0;
252}
253
Note: See TracBrowser for help on using the repository browser.