source: rtems/cpukit/posix/src/pthreadcreate.c @ 860c34e

4.104.114.95
Last change on this file since 860c34e was 412dbff6, checked in by Joel Sherrill <joel.sherrill@…>, on 04/05/07 at 21:17:27

2007-04-05 Joel Sherrill <joel@…>

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