source: rtems/cpukit/posix/src/pthread.c @ 5a18e04

4.104.114.84.95
Last change on this file since 5a18e04 was 5a18e04, checked in by Joel Sherrill <joel.sherrill@…>, on 05/28/96 at 19:28:32

added initial set of api extension callouts

  • Property mode set to 100644
File size: 12.9 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  if ( user_tasks == NULL || number_of_initialization_tasks == 0 )
158    _Internal_error_Occurred( INTERNAL_ERROR_POSIX_API, TRUE, EINVAL );
159
160  _Objects_Initialize_information(
161    &_POSIX_Threads_Information,
162    OBJECTS_POSIX_THREADS,
163    TRUE,
164    maximum_pthreads,
165    sizeof( POSIX_Threads_Control ),
166    TRUE,
167    _POSIX_PATH_MAX,
168    TRUE
169  );
170
171  /* XXX add api extensions */
172}
173
174/*PAGE
175 *
176 *  3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
177 *
178 *  RTEMS does not support processes, so we fall under this and do not
179 *  provide this routine:
180 *
181 *  "Either the implementation shall support the pthread_atfork() function
182 *   as described above or the pthread_atfork() funciton shall not be
183 *   provided."
184 */
185
186/*PAGE
187 *
188 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
189 */
190
191int pthread_attr_setscope(
192  pthread_attr_t  *attr,
193  int              contentionscope
194)
195{
196  if ( !attr || !attr->is_initialized )
197    return EINVAL;
198
199  attr->contentionscope = contentionscope;
200  return 0;
201}
202
203/*PAGE
204 *
205 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
206 */
207
208int pthread_attr_getscope(
209  const pthread_attr_t  *attr,
210  int                   *contentionscope
211)
212{
213  if ( !attr || !attr->is_initialized )
214    return EINVAL;
215
216  *contentionscope = attr->contentionscope;
217  return 0;
218}
219
220/*PAGE
221 *
222 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
223 */
224
225int pthread_attr_setinheritsched(
226  pthread_attr_t  *attr,
227  int              inheritsched
228)
229{
230  if ( !attr || !attr->is_initialized )
231    return EINVAL;
232
233  attr->inheritsched = inheritsched;
234  return 0;
235}
236
237/*PAGE
238 *
239 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
240 */
241
242int pthread_attr_getinheritsched(
243  const pthread_attr_t  *attr,
244  int                   *inheritsched
245)
246{
247  if ( !attr || !attr->is_initialized )
248    return EINVAL;
249
250  *inheritsched = attr->inheritsched;
251  return 0;
252}
253
254/*PAGE
255 *
256 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
257 */
258
259int pthread_attr_setschedpolicy(
260  pthread_attr_t  *attr,
261  int              policy
262)
263{
264  if ( !attr || !attr->is_initialized )
265    return EINVAL;
266
267  attr->schedpolicy = policy;
268  return 0;
269}
270
271/*PAGE
272 *
273 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
274 */
275
276int pthread_attr_getschedpolicy(
277  const pthread_attr_t  *attr,
278  int                   *policy
279)
280{
281  if ( !attr || !attr->is_initialized )
282    return EINVAL;
283
284  *policy = attr->schedpolicy;
285  return 0;
286}
287
288/*PAGE
289 *
290 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
291 */
292
293int pthread_attr_setschedparam(
294  pthread_attr_t            *attr,
295  const struct sched_param  *param
296)
297{
298  if ( !attr || !attr->is_initialized )
299    return EINVAL;
300
301  attr->schedparam = *param;
302  return 0;
303}
304
305/*PAGE
306 *
307 *  13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
308 */
309
310int pthread_attr_getschedparam(
311  const pthread_attr_t   *attr,
312  struct sched_param     *param
313)
314{
315  if ( !attr || !attr->is_initialized )
316    return EINVAL;
317
318  *param = attr->schedparam;
319  return 0;
320}
321
322/*PAGE
323 *
324 *  13.5.2 Dynamic Thread Scheduling Parameters Access,
325 *         P1003.1c/Draft 10, p. 124
326 */
327
328int pthread_getschedparam(
329  pthread_t           thread,
330  int                *policy,
331  struct sched_param *param
332)
333{
334  pthread_attr_t *attr;   /* XXX: really need to get this from the thread */
335
336  if ( !policy || !param  )
337    return EINVAL;
338
339  *policy = attr->schedpolicy;
340  *param  = attr->schedparam;
341  return 0;
342}
343
344/*PAGE
345 *
346 *  13.5.2 Dynamic Thread Scheduling Parameters Access,
347 *         P1003.1c/Draft 10, p. 124
348 */
349
350int pthread_setschedparam(
351  pthread_t           thread,
352  int                 policy,
353  struct sched_param *param
354)
355{
356  /* XXX need to reschedule after doing this to the thread */
357  pthread_attr_t *attr;   /* XXX: really need to get this from the thread */
358
359  if ( !param )
360    return EINVAL;
361
362  attr->schedpolicy = policy;
363  attr->schedparam  = *param;
364  return 0;
365}
366
367/*PAGE
368 *
369 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
370 */
371
372int pthread_attr_init(
373  pthread_attr_t  *attr
374)
375{
376  if ( !attr )
377    return EINVAL;
378 
379  *attr = _POSIX_Threads_Default_attributes;
380  return 0;
381}
382
383/*PAGE
384 *
385 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
386 */
387
388int pthread_attr_destroy(
389  pthread_attr_t  *attr
390)
391{
392  if ( !attr || !attr->is_initialized )
393    return EINVAL;
394 
395  attr->is_initialized = FALSE;
396  return 0;
397}
398 
399/*PAGE
400 *
401 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
402 */
403
404int pthread_attr_getstacksize(
405  const pthread_attr_t  *attr,
406  size_t                *stacksize
407)
408{
409  if ( !attr || !attr->is_initialized )
410    return EINVAL;
411
412  *stacksize = attr->stacksize;
413  return 0;
414}
415 
416/*PAGE
417 *
418 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
419 */
420
421int pthread_attr_setstacksize(
422  pthread_attr_t  *attr,
423  size_t           stacksize
424)
425{
426  if ( !attr || !attr->is_initialized )
427    return EINVAL;
428
429  attr->stacksize = stacksize;
430  return 0;
431}
432 
433/*PAGE
434 *
435 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
436 */
437
438int pthread_attr_getstackaddr(
439  const pthread_attr_t   *attr,
440  void                  **stackaddr
441)
442{
443  if ( !attr || !attr->is_initialized )
444    return EINVAL;
445
446  *stackaddr = attr->stackaddr;
447  return 0;
448}
449 
450/*PAGE
451 *
452 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
453 */
454
455int pthread_attr_setstackaddr(
456  pthread_attr_t  *attr,
457  void            *stackaddr
458)
459{
460  if ( !attr || !attr->is_initialized )
461    return EINVAL;
462
463  attr->stackaddr = stackaddr;
464  return 0;
465}
466 
467/*PAGE
468 *
469 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
470 */
471
472int pthread_attr_getdetachstate(
473  const pthread_attr_t  *attr,
474  int                   *detachstate
475)
476{
477  if ( !attr || !attr->is_initialized )
478    return EINVAL;
479
480  *detachstate = attr->detachstate;
481  return 0;
482}
483 
484/*PAGE
485 *
486 *  16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
487 */
488
489int pthread_attr_setdetachstate(
490  pthread_attr_t  *attr,
491  int              detachstate
492)
493{
494  if ( !attr || !attr->is_initialized )
495    return EINVAL;
496
497  attr->detachstate = detachstate;
498  return 0;
499}
500
501#ifdef NOT_IMPLEMENTED_YET
502
503/*PAGE
504 *
505 *  16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
506 */
507
508int pthread_create(
509  pthread_t             *thread,
510  const pthread_attr_t  *attr,
511  void                 (*start_routine)( void * ),
512  void                  *arg
513)
514{
515  const pthread_attr_t  *local_attr;
516
517  local_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes;
518
519  if ( !local_attr->is_initialized )
520    return EINVAL;
521
522  /*
523   *  Core Thread Initialize insures we get the minimum amount of
524   *  stack space.
525   */
526
527#if 0
528  int contentionscope;
529  int inheritsched;
530  int schedpolicy;
531  struct sched_param schedparam;
532
533#if defined(_POSIX_THREAD_CPUTIME)
534  int  cputime_clock_allowed;  /* see time.h */
535#endif
536  int  detachstate;
537#endif
538}
539
540/*PAGE
541 *
542 *  16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147
543 */
544
545int pthread_join(
546  pthread_t   thread,
547  void      **value_ptr
548)
549{
550  return POSIX_NOT_IMPLEMENTED();
551}
552
553/*PAGE
554 *
555 *  16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149
556 */
557
558int pthread_detach(
559  pthread_t   thread
560)
561{
562  return POSIX_NOT_IMPLEMENTED();
563}
564
565#endif
566
567/*PAGE
568 *
569 * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX
570 */
571
572pthread_t pthread_self( void )
573{
574  return _Thread_Executing->Object.id;
575}
576
577/*PAGE
578 *
579 *  16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153
580 */
581
582int pthread_equal(
583  pthread_t  t1,
584  pthread_t  t2
585)
586{
587#ifdef RTEMS_DEBUG
588 /* XXX may want to do a "get" to make sure both are valid. */
589 /* XXX behavior is undefined if not valid pthread_t's */
590#endif
591  return _Objects_Are_ids_equal( t1, t1 );
592}
593
594/*PAGE
595 *
596 *  16.1.8 Dynamic Package Initialization
597 */
598
599int pthread_once(
600  pthread_once_t  *once_control,
601  void           (*init_routine)(void)
602)
603{
604  /* XXX: Should we implement this routine this way or make it a full */
605  /* XXX: fledged object? */
606
607  if ( !once_control || !init_routine )
608    return EINVAL;
609
610  _Thread_Disable_dispatch();
611
612  if ( !once_control->is_initialized ) {
613
614    once_control->is_initialized = TRUE;
615    once_control->init_executed = TRUE;
616    (*init_routine)();
617
618  } if ( !once_control->init_executed ) {
619
620    once_control->init_executed = TRUE;
621    (*init_routine)();
622
623  }
624 
625  _Thread_Enable_dispatch();
626
627  return 0;
628}
629
630#ifdef NOT_IMPLEMENTED_YET
631
632/*PAGE
633 *
634 *  20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58
635 */
636 
637int pthread_getcpuclockid(
638  pthread_t    pid,
639  clockid_t   *clock_id
640)
641{
642  return POSIX_NOT_IMPLEMENTED();
643}
644
645#endif
646 
647/*PAGE
648 *
649 *  20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59
650 */
651
652int pthread_attr_setcputime(
653  pthread_attr_t  *attr,
654  int              clock_allowed
655)
656{
657  if ( !attr || !attr->is_initialized )
658    return EINVAL;
659
660  attr->cputime_clock_allowed = clock_allowed;
661  return 0;
662}
663
664/*PAGE
665 *
666 *  20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59
667 */
668
669int pthread_attr_getcputime(
670  pthread_attr_t  *attr,
671  int             *clock_allowed
672)
673{
674  if ( !attr || !attr->is_initialized )
675    return EINVAL;
676
677  *clock_allowed = attr->cputime_clock_allowed;
678  return 0;
679}
Note: See TracBrowser for help on using the repository browser.