source: rtems/cpukit/posix/src/pthread.c @ 974ff40

4.104.114.84.95
Last change on this file since 974ff40 was 974ff40, checked in by Joel Sherrill <joel.sherrill@…>, on 05/29/96 at 16:04:31

renamed signal.c to psignal.c to avoid naming problems.

added mp stubs to cond.c and mutex.c to eliminate link errors.

added pthread_exit to pthread.c

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