source: rtems/cpukit/posix/src/pthreadcreate.c @ 811fae1

4.104.114.84.95
Last change on this file since 811fae1 was 03598b1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/25/99 at 23:20:52

Split most of POSIX Threads Manager into multiple files.

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