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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [posix/] [src/] [pthread.c] - Blame information for rev 1026

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

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  pthread.c,v 1.57 2002/07/05 18:13:18 joel Exp
3
 */
4
 
5
#if HAVE_CONFIG_H
6
#include "config.h"
7
#endif
8
 
9
#include <assert.h>
10
#include <errno.h>
11
#include <pthread.h>
12
#include <limits.h>
13
 
14
#include <rtems/system.h>
15
#include <rtems/score/apiext.h>
16
#include <rtems/score/stack.h>
17
#include <rtems/score/thread.h>
18
#include <rtems/score/userext.h>
19
#include <rtems/score/wkspace.h>
20
#include <rtems/posix/cancel.h>
21
#include <rtems/posix/pthread.h>
22
#include <rtems/posix/priority.h>
23
#include <rtems/posix/psignal.h>
24
#include <rtems/posix/config.h>
25
#include <rtems/posix/key.h>
26
#include <rtems/posix/time.h>
27
 
28
/*PAGE
29
 *
30
 *  The default pthreads attributes structure.
31
 *
32
 *  NOTE: Be careful .. if the default attribute set changes,
33
 *        _POSIX_Threads_Initialize_user_threads will need to be examined.
34
 *
35
 */
36
 
37
const pthread_attr_t _POSIX_Threads_Default_attributes = {
38
  TRUE,                       /* is_initialized */
39
  NULL,                       /* stackaddr */
40
  PTHREAD_MINIMUM_STACK_SIZE, /* stacksize */
41
  PTHREAD_SCOPE_PROCESS,      /* contentionscope */
42
  PTHREAD_INHERIT_SCHED,      /* inheritsched */
43
  SCHED_FIFO,                 /* schedpolicy */
44
  {                           /* schedparam */
45
    2,                        /* sched_priority */
46
    0,                        /* ss_low_priority */
47
    { 0L, 0 },                /* ss_replenish_period */
48
    { 0L, 0 }                 /* ss_initial_budget */
49
  },
50
  PTHREAD_CREATE_JOINABLE,    /* detachstate */
51
  1                           /* cputime_clock_allowed */
52
};
53
 
54
/*PAGE
55
 *
56
 *  _POSIX_Threads_Sporadic_budget_TSR
57
 */
58
 
59
void _POSIX_Threads_Sporadic_budget_TSR(
60
  Objects_Id      id,
61
  void           *argument
62
)
63
{
64
  unsigned32          ticks;
65
  unsigned32          new_priority;
66
  Thread_Control     *the_thread;
67
  POSIX_API_Control  *api;
68
 
69
  the_thread = argument;
70
 
71
  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
72
 
73
  ticks = _POSIX_Timespec_to_interval( &api->schedparam.ss_initial_budget );
74
 
75
  if ( !ticks )
76
    ticks = 1;
77
 
78
  the_thread->cpu_time_budget = ticks;
79
 
80
  new_priority = _POSIX_Priority_To_core( api->ss_high_priority );
81
  the_thread->real_priority = new_priority;
82
 
83
  if ( the_thread->resource_count == 0 ||
84
       the_thread->current_priority > new_priority )
85
    _Thread_Change_priority( the_thread, new_priority, TRUE );
86
 
87
  ticks = _POSIX_Timespec_to_interval( &api->schedparam.ss_replenish_period );
88
 
89
  if ( !ticks )
90
    ticks = 1;
91
 
92
  _Watchdog_Insert_ticks( &api->Sporadic_timer, ticks );
93
}
94
 
95
/*PAGE
96
 *
97
 *  _POSIX_Threads_Sporadic_budget_callout
98
 */
99
 
100
void _POSIX_Threads_Sporadic_budget_callout(
101
  Thread_Control *the_thread
102
)
103
{
104
  POSIX_API_Control *api;
105
  unsigned32         new_priority;
106
 
107
  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
108
 
109
  /*
110
   *  This will prevent the thread from consuming its entire "budget"
111
   *  while at low priority.
112
   */
113
 
114
 
115
  the_thread->cpu_time_budget = 0xFFFFFFFF; /* XXX should be based on MAX_U32 */
116
 
117
  new_priority = _POSIX_Priority_To_core( api->schedparam.ss_low_priority );
118
  the_thread->real_priority = new_priority;
119
 
120
 if ( the_thread->resource_count == 0 ||
121
      the_thread->current_priority > new_priority )
122
    _Thread_Change_priority( the_thread, new_priority, TRUE );
123
}
124
 
125
/*PAGE
126
 *
127
 *  _POSIX_Threads_Create_extension
128
 *
129
 *  XXX
130
 */
131
 
132
boolean _POSIX_Threads_Create_extension(
133
  Thread_Control *executing,
134
  Thread_Control *created
135
)
136
{
137
  POSIX_API_Control *api;
138
  POSIX_API_Control *executing_api;
139
 
140
  api = _Workspace_Allocate( sizeof( POSIX_API_Control ) );
141
 
142
  if ( !api )
143
    return FALSE;
144
 
145
  created->API_Extensions[ THREAD_API_POSIX ] = api;
146
 
147
  /* XXX check all fields are touched */
148
  api->Attributes  = _POSIX_Threads_Default_attributes;
149
  api->detachstate = _POSIX_Threads_Default_attributes.detachstate;
150
  api->schedpolicy = _POSIX_Threads_Default_attributes.schedpolicy;
151
  api->schedparam  = _POSIX_Threads_Default_attributes.schedparam;
152
  api->schedparam.sched_priority =
153
     _POSIX_Priority_From_core( created->current_priority );
154
 
155
  /*
156
   *  POSIX 1003.1 1996, 18.2.2.2
157
   */
158
  api->cancelation_requested = 0;
159
  api->cancelability_state = PTHREAD_CANCEL_ENABLE;
160
  api->cancelability_type = PTHREAD_CANCEL_DEFERRED;
161
  _Chain_Initialize_empty (&api->Cancellation_Handlers);
162
 
163
  /*
164
   *  If the thread is not a posix thread, then all posix signals are blocked
165
   *  by default.
166
   */
167
 
168
  /* XXX use signal constants */
169
  api->signals_pending = 0;
170
  if ( _Objects_Get_API( created->Object.id ) == OBJECTS_POSIX_API &&
171
       _Objects_Get_class( created->Object.id ) == 1 ) {
172
    executing_api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
173
    api->signals_blocked = api->signals_blocked;
174
  } else
175
    api->signals_blocked = 0xffffffff;
176
 
177
  _Thread_queue_Initialize(
178
    &api->Join_List,
179
    THREAD_QUEUE_DISCIPLINE_FIFO,
180
    STATES_WAITING_FOR_JOIN_AT_EXIT,
181
 
182
  );
183
 
184
  _Watchdog_Initialize(
185
    &api->Sporadic_timer,
186
    _POSIX_Threads_Sporadic_budget_TSR,
187
    created->Object.id,
188
    created
189
  );
190
 
191
  return TRUE;
192
}
193
 
194
/*PAGE
195
 *
196
 *  _POSIX_Threads_Delete_extension
197
 */
198
 
199
User_extensions_routine _POSIX_Threads_Delete_extension(
200
  Thread_Control *executing,
201
  Thread_Control *deleted
202
)
203
{
204
  Thread_Control     *the_thread;
205
  POSIX_API_Control  *api;
206
  void              **value_ptr;
207
 
208
  api = deleted->API_Extensions[ THREAD_API_POSIX ];
209
 
210
  /*
211
   *  Run the POSIX cancellation handlers
212
   */
213
 
214
  _POSIX_Keys_Run_destructors( deleted );
215
 
216
  /*
217
   *  Wakeup all the tasks which joined with this one
218
   */
219
 
220
  value_ptr = (void **) deleted->Wait.return_argument;
221
 
222
  while ( (the_thread = _Thread_queue_Dequeue( &api->Join_List )) )
223
      *(void **)the_thread->Wait.return_argument = value_ptr;
224
 
225
  if ( api->schedpolicy == SCHED_SPORADIC )
226
    (void) _Watchdog_Remove( &api->Sporadic_timer );
227
 
228
  deleted->API_Extensions[ THREAD_API_POSIX ] = NULL;
229
 
230
  (void) _Workspace_Free( api );
231
}
232
 
233
/*
234
 *
235
 *  _POSIX_Threads_Exitted_extension
236
 */
237
 
238
User_extensions_routine _POSIX_Threads_Exitted_extension(
239
  Thread_Control *executing
240
)
241
{
242
  pthread_exit( executing->Wait.return_argument );
243
}
244
 
245
/*PAGE
246
 *
247
 *  _POSIX_Threads_Initialize_user_threads
248
 *
249
 *  This routine creates and starts all configured user
250
 *  initialzation threads.
251
 *
252
 *  Input parameters: NONE
253
 *
254
 *  Output parameters:  NONE
255
 */
256
 
257
void _POSIX_Threads_Initialize_user_threads( void )
258
{
259
  int                                 status;
260
  unsigned32                          index;
261
  unsigned32                          maximum;
262
  posix_initialization_threads_table *user_threads;
263
  pthread_t                           thread_id;
264
  pthread_attr_t                      attr;
265
 
266
  user_threads = _POSIX_Threads_User_initialization_threads;
267
  maximum      = _POSIX_Threads_Number_of_initialization_threads;
268
 
269
  if ( !user_threads || maximum == 0 )
270
    return;
271
 
272
  /*
273
   *  Be careful .. if the default attribute set changes, this may need to.
274
   *
275
   *  Setting the attributes explicitly is critical, since we don't want
276
   *  to inherit the idle tasks attributes.
277
   */
278
 
279
  for ( index=0 ; index < maximum ; index++ ) {
280
    status = pthread_attr_init( &attr );
281
    assert( !status );
282
 
283
    status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
284
    assert( !status );
285
 
286
    status = pthread_attr_setstacksize( &attr, user_threads[ index ].stack_size);
287
    assert( !status );
288
 
289
    status = pthread_create(
290
      &thread_id,
291
      &attr,
292
      user_threads[ index ].thread_entry,
293
      NULL
294
    );
295
    assert( !status );
296
  }
297
}
298
 
299
/*PAGE
300
 *
301
 *  API Extension control structures
302
 */
303
 
304
API_extensions_Control _POSIX_Threads_API_extensions = {
305
  { NULL, NULL },
306
  NULL,                                     /* predriver */
307
  _POSIX_Threads_Initialize_user_threads,   /* postdriver */
308
  _POSIX_signals_Post_switch_extension,     /* post switch */
309
};
310
 
311
User_extensions_Control _POSIX_Threads_User_extensions = {
312
  { NULL, NULL },
313
  { { NULL, NULL }, NULL },
314
  { _POSIX_Threads_Create_extension,          /* create */
315
    NULL,                                     /* start */
316
    NULL,                                     /* restart */
317
    _POSIX_Threads_Delete_extension,          /* delete */
318
    NULL,                                     /* switch */
319
    NULL,                                     /* begin */
320
    _POSIX_Threads_Exitted_extension,         /* exitted */
321
    NULL                                      /* fatal */
322
  }
323
};
324
 
325
/*PAGE
326
 *
327
 *  _POSIX_Threads_Manager_initialization
328
 *
329
 *  This routine initializes all threads manager related data structures.
330
 *
331
 *  Input parameters:
332
 *    maximum_pthreads - maximum configured pthreads
333
 *
334
 *  Output parameters:  NONE
335
 */
336
 
337
void _POSIX_Threads_Manager_initialization(
338
  unsigned32                          maximum_pthreads,
339
  unsigned32                          number_of_initialization_threads,
340
  posix_initialization_threads_table *user_threads
341
 
342
)
343
{
344
  _POSIX_Threads_Number_of_initialization_threads =
345
                                           number_of_initialization_threads;
346
  _POSIX_Threads_User_initialization_threads = user_threads;
347
 
348
  /*
349
   *  There may not be any POSIX initialization threads configured.
350
   */
351
 
352
#if 0
353
  if ( user_threads == NULL || number_of_initialization_threads == 0 )
354
    _Internal_error_Occurred( INTERNAL_ERROR_POSIX_API, TRUE, EINVAL );
355
#endif
356
 
357
  _Objects_Initialize_information(
358
    &_POSIX_Threads_Information, /* object information table */
359
    OBJECTS_POSIX_API,           /* object API */
360
    OBJECTS_POSIX_THREADS,       /* object class */
361
    maximum_pthreads,            /* maximum objects of this class */
362
    sizeof( Thread_Control ),
363
                                 /* size of this object's control block */
364
    FALSE,                       /* TRUE if names for this object are strings */
365
 
366
#if defined(RTEMS_MULTIPROCESSING)
367
    ,
368
    FALSE,                       /* TRUE if this is a global object class */
369
    NULL                         /* Proxy extraction support callout */
370
#endif
371
  );
372
 
373
  /*
374
   *  Add all the extensions for this API
375
   */
376
 
377
  _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions );
378
 
379
  _API_extensions_Add( &_POSIX_Threads_API_extensions );
380
 
381
 
382
  /*
383
   *  If we supported MP, then here we would ...
384
   *       Register the MP Process Packet routine.
385
   */
386
 
387
}

powered by: WebSVN 2.1.0

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