source: rtems/c/src/exec/posix/src/pthread.c @ 613cff6

4.104.114.84.95
Last change on this file since 613cff6 was 613cff6, checked in by Joel Sherrill <joel.sherrill@…>, on 05/29/96 at 16:54:52

removed all ifdef's on NOT_IMPLEMENTED.

  • Property mode set to 100644
File size: 13.6 KB
Line 
1/*
2 *  $Id$
3 */
4
5#include <assert.h>
6#include <errno.h>
7#include <pthread.h>
8#include <limits.h>
9
10#include <rtems/system.h>
11#include <rtems/score/apiext.h>
12#include <rtems/score/stack.h>
13#include <rtems/score/thread.h>
14#include <rtems/score/userext.h>
15#include <rtems/score/wkspace.h>
16#include <rtems/posix/pthread.h>
17#include <rtems/posix/config.h>
18
19/*PAGE
20 *
21 *  The default pthreads attributes structure.
22 */
23 
24const pthread_attr_t _POSIX_Threads_Default_attributes = {
25  TRUE,                    /* is_initialized */
26  0,                       /* stackaddr */
27  STACK_MINIMUM_SIZE,      /* stacksize */
28  PTHREAD_SCOPE_PROCESS,   /* contentionscope */
29  PTHREAD_INHERIT_SCHED,   /* inheritsched */
30  SCHED_FIFO,              /* schedpolicy */
31  {                        /* schedparam */
32    128,                   /* sched_priority */
33    0,                     /* ss_low_priority */
34    { 0L, 0 },             /* ss_replenish_period */
35    { 0L, 0 }              /* ss_initial_budget */
36  },
37  PTHREAD_CREATE_DETACHED, /* detachstate */
38  1                        /* cputime_clock_allowed */
39};
40
41/*PAGE
42 *
43 *  _POSIX_Threads_Create_extension
44 *
45 *  XXX
46 */
47 
48boolean _POSIX_Threads_Create_extension(
49  Thread_Control *executing,
50  Thread_Control *created
51)
52{
53  POSIX_API_Control *api;
54 
55  api = _Workspace_Allocate( sizeof( POSIX_API_Control ) );
56 
57  if ( !api )
58    return FALSE;
59 
60  created->API_Extensions[ THREAD_API_POSIX ] = api;
61 
62  /* XXX something should go here */
63
64  return TRUE;
65}
66 
67/*PAGE
68 *
69 *  _POSIX_Threads_Delete_extension
70 *
71 *  XXX
72 */
73 
74User_extensions_routine _POSIX_Threads_Delete_extension(
75  Thread_Control *executing,
76  Thread_Control *deleted
77)
78{
79  (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_POSIX ] );
80 
81  deleted->API_Extensions[ THREAD_API_POSIX ] = NULL;
82}
83
84/*PAGE
85 *
86 *  _POSIX_Threads_Initialize_user_tasks
87 *
88 *  This routine creates and starts all configured user
89 *  initialzation threads.
90 *
91 *  Input parameters: NONE
92 *
93 *  Output parameters:  NONE
94 */
95 
96void _POSIX_Threads_Initialize_user_tasks( void )
97{
98  int                               status;
99  unsigned32                        index;
100  unsigned32                        maximum;
101  posix_initialization_tasks_table *user_tasks;
102  pthread_t                         thread_id;
103 
104  /*
105   *  NOTE:  This is slightly different from the Ada implementation.
106   */
107 
108  user_tasks = _POSIX_Threads_User_initialization_tasks;
109  maximum    = _POSIX_Threads_Number_of_initialization_tasks;
110
111  if ( !user_tasks || maximum == 0 )
112    return;
113 
114  for ( index=0 ; index < maximum ; index++ ) {
115    status = pthread_create(&thread_id,  NULL, user_tasks[ index ].entry, NULL);
116    assert( !status );
117  }
118}
119
120API_extensions_Control _POSIX_Threads_API_extensions = {
121  { NULL, NULL },
122  NULL,                                     /* predriver */
123  _POSIX_Threads_Initialize_user_tasks,     /* postdriver */
124  NULL,                                     /* post switch */
125};
126 
127User_extensions_Control _POSIX_Threads_User_extensions = {
128  { NULL, NULL },
129  { _POSIX_Threads_Create_extension,          /* create */
130    NULL,                                     /* start */
131    NULL,                                     /* restart */
132    _POSIX_Threads_Delete_extension,          /* delete */
133    NULL,                                     /* switch */
134    NULL,                                     /* begin */
135    NULL,                                     /* exitted */
136    NULL                                      /* fatal */
137  }
138};
139 
140/*PAGE
141 *
142 *  _POSIX_Threads_Manager_initialization
143 *
144 *  This routine initializes all threads manager related data structures.
145 *
146 *  Input parameters:
147 *    maximum_pthreads - maximum configured pthreads
148 *
149 *  Output parameters:  NONE
150 */
151 
152void _POSIX_Threads_Manager_initialization(
153  unsigned32                        maximum_pthreads,
154  unsigned32                        number_of_initialization_tasks,
155  posix_initialization_tasks_table *user_tasks
156 
157)
158{
159  _POSIX_Threads_Number_of_initialization_tasks =
160                                                 number_of_initialization_tasks;
161  _POSIX_Threads_User_initialization_tasks = user_tasks;
162
163  /*
164   *  There may not be any POSIX initialization threads configured.
165   */
166
167#if 0
168  if ( user_tasks == NULL || number_of_initialization_tasks == 0 )
169    _Internal_error_Occurred( INTERNAL_ERROR_POSIX_API, TRUE, EINVAL );
170#endif
171
172  _Objects_Initialize_information(
173    &_POSIX_Threads_Information,
174    OBJECTS_POSIX_THREADS,
175    TRUE,
176    maximum_pthreads,
177    sizeof( POSIX_Threads_Control ),
178    TRUE,
179    _POSIX_PATH_MAX,
180    TRUE
181  );
182
183  /*
184   *  Add all the extensions for this API
185   */
186 
187  _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions );
188 
189  _API_extensions_Add( &_POSIX_Threads_API_extensions );
190 
191  /*
192   *  If we supported MP, then here we would ...
193   *       Register the MP Process Packet routine.
194   */
195 
196}
197
198/*PAGE
199 *
200 *  3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
201 *
202 *  RTEMS does not support processes, so we fall under this and do not
203 *  provide this routine:
204 *
205 *  "Either the implementation shall support the pthread_atfork() function
206 *   as described above or the pthread_atfork() funciton shall not be
207 *   provided."
208 */
209
210/*PAGE
211 *
212 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
213 */
214
215int pthread_attr_setscope(
216  pthread_attr_t  *attr,
217  int              contentionscope
218)
219{
220  if ( !attr || !attr->is_initialized )
221    return EINVAL;
222
223  attr->contentionscope = contentionscope;
224  return 0;
225}
226
227/*PAGE
228 *
229 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
230 */
231
232int pthread_attr_getscope(
233  const pthread_attr_t  *attr,
234  int                   *contentionscope
235)
236{
237  if ( !attr || !attr->is_initialized )
238    return EINVAL;
239
240  *contentionscope = attr->contentionscope;
241  return 0;
242}
243
244/*PAGE
245 *
246 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
247 */
248
249int pthread_attr_setinheritsched(
250  pthread_attr_t  *attr,
251  int              inheritsched
252)
253{
254  if ( !attr || !attr->is_initialized )
255    return EINVAL;
256
257  attr->inheritsched = inheritsched;
258  return 0;
259}
260
261/*PAGE
262 *
263 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
264 */
265
266int pthread_attr_getinheritsched(
267  const pthread_attr_t  *attr,
268  int                   *inheritsched
269)
270{
271  if ( !attr || !attr->is_initialized )
272    return EINVAL;
273
274  *inheritsched = attr->inheritsched;
275  return 0;
276}
277
278/*PAGE
279 *
280 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
281 */
282
283int pthread_attr_setschedpolicy(
284  pthread_attr_t  *attr,
285  int              policy
286)
287{
288  if ( !attr || !attr->is_initialized )
289    return EINVAL;
290
291  attr->schedpolicy = policy;
292  return 0;
293}
294
295/*PAGE
296 *
297 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
298 */
299
300int pthread_attr_getschedpolicy(
301  const pthread_attr_t  *attr,
302  int                   *policy
303)
304{
305  if ( !attr || !attr->is_initialized )
306    return EINVAL;
307
308  *policy = attr->schedpolicy;
309  return 0;
310}
311
312/*PAGE
313 *
314 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
315 */
316
317int pthread_attr_setschedparam(
318  pthread_attr_t            *attr,
319  const struct sched_param  *param
320)
321{
322  if ( !attr || !attr->is_initialized )
323    return EINVAL;
324
325  attr->schedparam = *param;
326  return 0;
327}
328
329/*PAGE
330 *
331 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
332 */
333
334int pthread_attr_getschedparam(
335  const pthread_attr_t   *attr,
336  struct sched_param     *param
337)
338{
339  if ( !attr || !attr->is_initialized )
340    return EINVAL;
341
342  *param = attr->schedparam;
343  return 0;
344}
345
346/*PAGE
347 *
348 *  13.5.2 Dynamic Thread Scheduling Parameters Access,
349 *         P1003.1c/Draft 10, p. 124
350 */
351
352int pthread_getschedparam(
353  pthread_t           thread,
354  int                *policy,
355  struct sched_param *param
356)
357{
358  pthread_attr_t *attr;   /* XXX: really need to get this from the thread */
359
360  if ( !policy || !param  )
361    return EINVAL;
362
363  *policy = attr->schedpolicy;
364  *param  = attr->schedparam;
365  return 0;
366}
367
368/*PAGE
369 *
370 *  13.5.2 Dynamic Thread Scheduling Parameters Access,
371 *         P1003.1c/Draft 10, p. 124
372 */
373
374int pthread_setschedparam(
375  pthread_t           thread,
376  int                 policy,
377  struct sched_param *param
378)
379{
380  /* XXX need to reschedule after doing this to the thread */
381  pthread_attr_t *attr;   /* XXX: really need to get this from the thread */
382
383  if ( !param )
384    return EINVAL;
385
386  attr->schedpolicy = policy;
387  attr->schedparam  = *param;
388  return 0;
389}
390
391/*PAGE
392 *
393 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
394 */
395
396int pthread_attr_init(
397  pthread_attr_t  *attr
398)
399{
400  if ( !attr )
401    return EINVAL;
402 
403  *attr = _POSIX_Threads_Default_attributes;
404  return 0;
405}
406
407/*PAGE
408 *
409 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
410 */
411
412int pthread_attr_destroy(
413  pthread_attr_t  *attr
414)
415{
416  if ( !attr || !attr->is_initialized )
417    return EINVAL;
418 
419  attr->is_initialized = FALSE;
420  return 0;
421}
422 
423/*PAGE
424 *
425 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
426 */
427
428int pthread_attr_getstacksize(
429  const pthread_attr_t  *attr,
430  size_t                *stacksize
431)
432{
433  if ( !attr || !attr->is_initialized )
434    return EINVAL;
435
436  *stacksize = attr->stacksize;
437  return 0;
438}
439 
440/*PAGE
441 *
442 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
443 */
444
445int pthread_attr_setstacksize(
446  pthread_attr_t  *attr,
447  size_t           stacksize
448)
449{
450  if ( !attr || !attr->is_initialized )
451    return EINVAL;
452
453  attr->stacksize = stacksize;
454  return 0;
455}
456 
457/*PAGE
458 *
459 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
460 */
461
462int pthread_attr_getstackaddr(
463  const pthread_attr_t   *attr,
464  void                  **stackaddr
465)
466{
467  if ( !attr || !attr->is_initialized )
468    return EINVAL;
469
470  *stackaddr = attr->stackaddr;
471  return 0;
472}
473 
474/*PAGE
475 *
476 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
477 */
478
479int pthread_attr_setstackaddr(
480  pthread_attr_t  *attr,
481  void            *stackaddr
482)
483{
484  if ( !attr || !attr->is_initialized )
485    return EINVAL;
486
487  attr->stackaddr = stackaddr;
488  return 0;
489}
490 
491/*PAGE
492 *
493 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
494 */
495
496int pthread_attr_getdetachstate(
497  const pthread_attr_t  *attr,
498  int                   *detachstate
499)
500{
501  if ( !attr || !attr->is_initialized )
502    return EINVAL;
503
504  *detachstate = attr->detachstate;
505  return 0;
506}
507 
508/*PAGE
509 *
510 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
511 */
512
513int pthread_attr_setdetachstate(
514  pthread_attr_t  *attr,
515  int              detachstate
516)
517{
518  if ( !attr || !attr->is_initialized )
519    return EINVAL;
520
521  attr->detachstate = detachstate;
522  return 0;
523}
524
525/*PAGE
526 *
527 *  16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
528 */
529
530int pthread_create(
531  pthread_t              *thread,
532  const pthread_attr_t   *attr,
533  void                 *(*start_routine)( void * ),
534  void                   *arg
535)
536{
537  const pthread_attr_t  *local_attr;
538
539  local_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
540
541  if ( !local_attr->is_initialized )
542    return EINVAL;
543
544  /*
545   *  Core Thread Initialize insures we get the minimum amount of
546   *  stack space.
547   */
548
549#if 0
550  int contentionscope;
551  int inheritsched;
552  int schedpolicy;
553  struct sched_param schedparam;
554
555#if defined(_POSIX_THREAD_CPUTIME)
556  int  cputime_clock_allowed;  /* see time.h */
557#endif
558  int  detachstate;
559#endif
560
561  return POSIX_NOT_IMPLEMENTED();
562}
563
564/*PAGE
565 *
566 *  16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147
567 */
568
569int pthread_join(
570  pthread_t   thread,
571  void      **value_ptr
572)
573{
574  return POSIX_NOT_IMPLEMENTED();
575}
576
577/*PAGE
578 *
579 *  16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149
580 */
581
582int pthread_detach(
583  pthread_t   thread
584)
585{
586  return POSIX_NOT_IMPLEMENTED();
587}
588
589/*PAGE
590 *
591 * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150
592 */
593 
594void pthread_exit(
595  void  *value_ptr
596)
597{
598  POSIX_NOT_IMPLEMENTED();
599}
600
601/*PAGE
602 *
603 * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX
604 */
605
606pthread_t pthread_self( void )
607{
608  return _Thread_Executing->Object.id;
609}
610
611/*PAGE
612 *
613 *  16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153
614 */
615
616int pthread_equal(
617  pthread_t  t1,
618  pthread_t  t2
619)
620{
621#ifdef RTEMS_DEBUG
622 /* XXX may want to do a "get" to make sure both are valid. */
623 /* XXX behavior is undefined if not valid pthread_t's */
624#endif
625  return _Objects_Are_ids_equal( t1, t1 );
626}
627
628/*PAGE
629 *
630 *  16.1.8 Dynamic Package Initialization
631 */
632
633int pthread_once(
634  pthread_once_t  *once_control,
635  void           (*init_routine)(void)
636)
637{
638  /* XXX: Should we implement this routine this way or make it a full */
639  /* XXX: fledged object? */
640
641  if ( !once_control || !init_routine )
642    return EINVAL;
643
644  _Thread_Disable_dispatch();
645
646  if ( !once_control->is_initialized ) {
647
648    once_control->is_initialized = TRUE;
649    once_control->init_executed = TRUE;
650    (*init_routine)();
651
652  } if ( !once_control->init_executed ) {
653
654    once_control->init_executed = TRUE;
655    (*init_routine)();
656
657  }
658 
659  _Thread_Enable_dispatch();
660
661  return 0;
662}
663
664/*PAGE
665 *
666 *  20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58
667 */
668 
669int pthread_getcpuclockid(
670  pthread_t    pid,
671  clockid_t   *clock_id
672)
673{
674  return POSIX_NOT_IMPLEMENTED();
675}
676
677/*PAGE
678 *
679 *  20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59
680 */
681
682int pthread_attr_setcputime(
683  pthread_attr_t  *attr,
684  int              clock_allowed
685)
686{
687  if ( !attr || !attr->is_initialized )
688    return EINVAL;
689
690  attr->cputime_clock_allowed = clock_allowed;
691  return 0;
692}
693
694/*PAGE
695 *
696 *  20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59
697 */
698
699int pthread_attr_getcputime(
700  pthread_attr_t  *attr,
701  int             *clock_allowed
702)
703{
704  if ( !attr || !attr->is_initialized )
705    return EINVAL;
706
707  *clock_allowed = attr->cputime_clock_allowed;
708  return 0;
709}
Note: See TracBrowser for help on using the repository browser.