OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [exec/] [posix/] [src/] [pthreadcreate.c] - Blame information for rev 580

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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: pthreadcreate.c,v 1.2 2001-09-27 11:59:17 chris Exp $
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
 
23
int 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
  is_fp = CPU_HARDWARE_FP;
144
 
145
  /*
146
   *  Disable dispatch for protection
147
   */
148
 
149
  _Thread_Disable_dispatch();
150
 
151
  /*
152
   *  Allocate the thread control block.
153
   *
154
   *  NOTE:  Global threads are not currently supported.
155
   */
156
 
157
  the_thread = _POSIX_Threads_Allocate();
158
 
159
  if ( !the_thread ) {
160
    _Thread_Enable_dispatch();
161
    return EAGAIN;
162
  }
163
 
164
  /*
165
   *  Initialize the core thread for this task.
166
   */
167
 
168
  status = _Thread_Initialize(
169
    &_POSIX_Threads_Information,
170
    the_thread,
171
    the_attr->stackaddr,
172
    the_attr->stacksize,
173
    is_fp,
174
    core_priority,
175
    TRUE,                 /* preemptible */
176
    budget_algorithm,
177
    budget_callout,
178
    0,                    /* isr level */
179
    NULL                  /* posix threads don't have a name */
180
  );
181
 
182
  if ( !status ) {
183
    _POSIX_Threads_Free( the_thread );
184
    _Thread_Enable_dispatch();
185
    return EAGAIN;
186
  }
187
 
188
  /*
189
   *  finish initializing the per API structure
190
   */
191
 
192
 
193
  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
194
 
195
  api->Attributes  = *the_attr;
196
  api->detachstate = the_attr->detachstate;
197
  api->schedpolicy = schedpolicy;
198
  api->schedparam  = schedparam;
199
 
200
  /*
201
   *  This insures we evaluate the process-wide signals pending when we
202
   *  first run.
203
   *
204
   *  NOTE:  Since the thread starts with all unblocked, this is necessary.
205
   */
206
 
207
  the_thread->do_post_task_switch_extension = TRUE;
208
 
209
  /*
210
   *  POSIX threads are allocated and started in one operation.
211
   */
212
 
213
  status = _Thread_Start(
214
    the_thread,
215
    THREAD_START_POINTER,
216
    start_routine,
217
    arg,
218
 
219
  );
220
 
221
  if ( schedpolicy == SCHED_SPORADIC ) {
222
    _Watchdog_Insert_ticks(
223
      &api->Sporadic_timer,
224
      _POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period )
225
    );
226
  }
227
 
228
  /*
229
   *  _Thread_Start only fails if the thread was in the incorrect state
230
   */
231
 
232
  if ( !status ) {
233
    _POSIX_Threads_Free( the_thread );
234
    _Thread_Enable_dispatch();
235
    return EINVAL;
236
  }
237
 
238
  /*
239
   *  Return the id and indicate we successfully created the thread
240
   */
241
 
242
  *thread = the_thread->Object.id;
243
 
244
 _Thread_Enable_dispatch();
245
 
246
 return 0;
247
}
248
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.