source: rtems/cpukit/posix/src/pthreadcreate.c @ 05c1886

4.104.115
Last change on this file since 05c1886 was 1de949a8, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/30/09 at 15:49:52

Whitespace removal.

  • Property mode set to 100644
File size: 5.9 KB
RevLine 
[03598b1]1/*
2 *  16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
[412dbff6]3 */
4
[5088d97]5/*  COPYRIGHT (c) 1989-2008.
[03598b1]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
[8e36f29]10 *  http://www.rtems.com/license/LICENSE.
[03598b1]11 *
12 *  $Id$
13 */
14
[f42b726]15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
[03598b1]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>
[5088d97]27#include <rtems/score/apimutex.h>
[03598b1]28
[ecf0f4c]29static inline size_t _POSIX_Threads_Ensure_minimum_stack (
30  size_t size
31)
32{
33  if ( size >= PTHREAD_MINIMUM_STACK_SIZE )
34    return size;
35  return PTHREAD_MINIMUM_STACK_SIZE;
36}
37
38
[03598b1]39int pthread_create(
40  pthread_t              *thread,
41  const pthread_attr_t   *attr,
42  void                 *(*start_routine)( void * ),
43  void                   *arg
44)
45{
46  const pthread_attr_t               *the_attr;
47  Priority_Control                    core_priority;
48  Thread_CPU_budget_algorithms        budget_algorithm;
49  Thread_CPU_budget_algorithm_callout budget_callout;
[f8437c8]50  bool                                is_fp;
51  bool                                status;
[03598b1]52  Thread_Control                     *the_thread;
53  POSIX_API_Control                  *api;
54  int                                 schedpolicy = SCHED_RR;
55  struct sched_param                  schedparam;
[ce19f1fa]56  Objects_Name                        name;
[2212a2ad]57  int                                 rc;
[03598b1]58
[e889a857]59  if ( !start_routine )
60    return EFAULT;
61
[03598b1]62  the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
63
64  if ( !the_attr->is_initialized )
65    return EINVAL;
66
67  /*
[ecf0f4c]68   *  Core Thread Initialize ensures we get the minimum amount of
[03598b1]69   *  stack space if it is allowed to allocate it itself.
[ecf0f4c]70   *
71   *  NOTE: If the user provides the stack we will let it drop below
72   *        twice the minimum.
[03598b1]73   */
[ecf0f4c]74  if ( the_attr->stackaddr && !_Stack_Is_enough(the_attr->stacksize) )
[03598b1]75    return EINVAL;
76
[2212a2ad]77  #if 0
78    int  cputime_clock_allowed;  /* see time.h */
79    rtems_set_errno_and_return_minus_one( ENOSYS );
80  #endif
[03598b1]81
82  /*
83   *  P1003.1c/Draft 10, p. 121.
84   *
85   *  If inheritsched is set to PTHREAD_INHERIT_SCHED, then this thread
86   *  inherits scheduling attributes from the creating thread.   If it is
[874297f3]87   *  PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the
[03598b1]88   *  attributes structure.
89   */
90  switch ( the_attr->inheritsched ) {
91    case PTHREAD_INHERIT_SCHED:
92      api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
93      schedpolicy = api->schedpolicy;
94      schedparam  = api->schedparam;
[874297f3]95      break;
[03598b1]96
97    case PTHREAD_EXPLICIT_SCHED:
98      schedpolicy = the_attr->schedpolicy;
99      schedparam  = the_attr->schedparam;
[874297f3]100      break;
[03598b1]101
102    default:
103      return EINVAL;
104  }
105
106  /*
[874297f3]107   *  Check the contentionscope since rtems only supports PROCESS wide
[03598b1]108   *  contention (i.e. no system wide contention).
109   */
110  if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS )
111    return ENOTSUP;
112
113  /*
114   *  Interpret the scheduling parameters.
115   */
116  if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) )
117    return EINVAL;
[874297f3]118
[03598b1]119  core_priority = _POSIX_Priority_To_core( schedparam.sched_priority );
[874297f3]120
[03598b1]121  /*
122   *  Set the core scheduling policy information.
123   */
[2212a2ad]124  rc = _POSIX_Thread_Translate_sched_param(
125    schedpolicy,
126    &schedparam,
127    &budget_algorithm,
128    &budget_callout
129  );
130  if ( rc )
131    return rc;
[03598b1]132
133  /*
[874297f3]134   *  Currently all POSIX threads are floating point if the hardware
[03598b1]135   *  supports it.
136   */
[2212a2ad]137  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
138    is_fp = true;
139  #else
140    is_fp = false;
141  #endif
[03598b1]142
143  /*
[5088d97]144   *  Lock the allocator mutex for protection
[03598b1]145   */
[5088d97]146  _RTEMS_Lock_allocator();
[874297f3]147
[03598b1]148  /*
149   *  Allocate the thread control block.
150   *
151   *  NOTE:  Global threads are not currently supported.
152   */
153  the_thread = _POSIX_Threads_Allocate();
154  if ( !the_thread ) {
[5088d97]155    _RTEMS_Unlock_allocator();
[03598b1]156    return EAGAIN;
157  }
158
159  /*
160   *  Initialize the core thread for this task.
161   */
[ce19f1fa]162  name.name_p = NULL;   /* posix threads don't have a name by default */
[03598b1]163  status = _Thread_Initialize(
164    &_POSIX_Threads_Information,
165    the_thread,
166    the_attr->stackaddr,
[ecf0f4c]167    _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize),
[03598b1]168    is_fp,
169    core_priority,
[b1dbfd7]170    true,                 /* preemptible */
[03598b1]171    budget_algorithm,
172    budget_callout,
173    0,                    /* isr level */
[ce19f1fa]174    name                  /* posix threads don't have a name */
[03598b1]175  );
[874297f3]176
[03598b1]177  if ( !status ) {
178    _POSIX_Threads_Free( the_thread );
[5088d97]179    _RTEMS_Unlock_allocator();
[03598b1]180    return EAGAIN;
181  }
182
183  /*
184   *  finish initializing the per API structure
185   */
186  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
187
188  api->Attributes  = *the_attr;
189  api->detachstate = the_attr->detachstate;
190  api->schedpolicy = schedpolicy;
191  api->schedparam  = schedparam;
192
193  /*
194   *  This insures we evaluate the process-wide signals pending when we
195   *  first run.
196   *
197   *  NOTE:  Since the thread starts with all unblocked, this is necessary.
198   */
[f8437c8]199  the_thread->do_post_task_switch_extension = true;
[03598b1]200
201  /*
202   *  POSIX threads are allocated and started in one operation.
203   */
204  status = _Thread_Start(
205    the_thread,
206    THREAD_START_POINTER,
207    start_routine,
208    arg,
209    0                     /* unused */
210  );
211
[2212a2ad]212  #if defined(RTEMS_DEBUG)
213    /*
214     *  _Thread_Start only fails if the thread was in the incorrect state
[1de949a8]215     *
[2212a2ad]216     *  NOTE: This can only happen if someone slips in and touches the
217     *        thread while we are creating it.
218     */
219    if ( !status ) {
220      _POSIX_Threads_Free( the_thread );
221      _RTEMS_Unlock_allocator();
222      return EINVAL;
223    }
224  #endif
225
[03598b1]226  if ( schedpolicy == SCHED_SPORADIC ) {
227    _Watchdog_Insert_ticks(
228      &api->Sporadic_timer,
[412dbff6]229      _Timespec_To_ticks( &api->schedparam.ss_replenish_period )
[03598b1]230    );
231  }
232
233  /*
234   *  Return the id and indicate we successfully created the thread
235   */
236  *thread = the_thread->Object.id;
237
[5088d97]238  _RTEMS_Unlock_allocator();
239  return 0;
[03598b1]240}
Note: See TracBrowser for help on using the repository browser.