source: rtems/cpukit/rtems/src/tasks.c @ 3235ad9

4.104.114.84.95
Last change on this file since 3235ad9 was 3235ad9, checked in by Joel Sherrill <joel.sherrill@…>, on 08/23/95 at 19:30:23

Support for variable length names added to Object Handler. This supports
both fixed length "raw" names and strings from the API's point of view.

Both inline and macro implementations were tested.

  • Property mode set to 100644
File size: 21.3 KB
Line 
1/*
2 *  RTEMS Task Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
6 *  On-Line Applications Research Corporation (OAR).
7 *  All rights assigned to U.S. Government, 1994.
8 *
9 *  This material may be reproduced by or for the U.S. Government pursuant
10 *  to the copyright license under the clause at DFARS 252.227-7013.  This
11 *  notice must appear in all copies of this file and its derivatives.
12 *
13 *  $Id$
14 */
15
16#include <rtems/system.h>
17#include <rtems/support.h>
18#include <rtems/modes.h>
19#include <rtems/object.h>
20#include <rtems/stack.h>
21#include <rtems/states.h>
22#include <rtems/tasks.h>
23#include <rtems/thread.h>
24#include <rtems/threadq.h>
25#include <rtems/tod.h>
26#include <rtems/userext.h>
27#include <rtems/wkspace.h>
28
29/*PAGE
30 *
31 *  rtems_task_create
32 *
33 *  This directive creates a thread by allocating and initializing a
34 *  thread control block and a stack.  The newly created thread is
35 *  placed in the dormant state.
36 *
37 *  Input parameters:
38 *    name             - user defined thread name
39 *    initial_priority - thread priority
40 *    stack_size       - stack size in bytes
41 *    initial_modes    - initial thread mode
42 *    attribute_set    - thread attributes
43 *    id               - pointer to thread id
44 *
45 *  Output parameters:
46 *    id                - thread id
47 *    RTEMS_SUCCESSFUL - if successful
48 *    error code        - if unsuccessful
49 */
50
51rtems_status_code rtems_task_create(
52  rtems_name           name,
53  rtems_task_priority  initial_priority,
54  unsigned32           stack_size,
55  rtems_mode           initial_modes,
56  rtems_attribute      attribute_set,
57  Objects_Id          *id
58)
59{
60  register Thread_Control *the_thread;
61  unsigned32               actual_stack_size;
62  unsigned32               memory_needed;
63  void                    *memory;
64  rtems_attribute          the_attribute_set;
65
66  if ( !rtems_is_name_valid( name ) )
67    return ( RTEMS_INVALID_NAME );
68
69#if 0
70  if ( !_Stack_Is_enough( stack_size ) )
71    return( RTEMS_INVALID_SIZE );
72#endif
73
74  if ( !_Stack_Is_enough( stack_size ) )
75    actual_stack_size = RTEMS_MINIMUM_STACK_SIZE;
76  else
77    actual_stack_size = stack_size;
78
79  if ( !_Priority_Is_valid( initial_priority ) )
80    return( RTEMS_INVALID_PRIORITY );
81
82  /*
83   *  Fix the attribute set to match the attributes which
84   *  this processor (1) requires and (2) is able to support.
85   *  First add in the required flags for attribute_set
86   *  Typically this might include FP if the platform
87   *  or application required all tasks to be fp aware.
88   *  Then turn off the requested bits which are not supported.
89   */
90
91  the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
92  the_attribute_set =
93    _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
94
95  if ( _Attributes_Is_global( the_attribute_set ) &&
96       !_Configuration_Is_multiprocessing() )
97    return( RTEMS_MP_NOT_CONFIGURED );
98
99  _Thread_Disable_dispatch();          /* to prevent deletion */
100
101  the_thread = _RTEMS_tasks_Allocate();
102
103  if ( !the_thread ) {
104    _Thread_Enable_dispatch();
105    return( RTEMS_TOO_MANY );
106  }
107
108  actual_stack_size = _Stack_Adjust_size( actual_stack_size );
109  memory_needed = actual_stack_size;
110
111  if ( _Attributes_Is_floating_point( the_attribute_set ) )
112    memory_needed += CONTEXT_FP_SIZE;
113
114  memory = _Workspace_Allocate( memory_needed );
115
116  if ( !memory ) {
117    _RTEMS_tasks_Free( the_thread );
118    _Thread_Enable_dispatch();
119    return( RTEMS_UNSATISFIED );
120  }
121
122  /*
123   *  Stack is put in the lower address regions of the allocated memory.
124   *  The optional floating point context area goes into the higher part
125   *  of the allocated memory.
126   */
127
128  _Stack_Initialize(
129     &the_thread->Start.Initial_stack, memory, actual_stack_size );
130
131  if ( _Attributes_Is_floating_point( the_attribute_set ) )
132    the_thread->fp_context = _Context_Fp_start( memory, actual_stack_size );
133  else
134    the_thread->fp_context = NULL;
135
136  the_thread->Start.fp_context = the_thread->fp_context;
137
138  if ( _Attributes_Is_global( the_attribute_set ) &&
139       !( _Objects_MP_Open( &_Thread_Information, name,
140                            the_thread->Object.id, FALSE ) ) ) {
141    _RTEMS_tasks_Free( the_thread );
142    (void) _Workspace_Free( memory );
143    _Thread_Enable_dispatch();
144    return( RTEMS_TOO_MANY );
145  }
146
147  the_thread->attribute_set          = the_attribute_set;
148  the_thread->current_state          = STATES_DORMANT;
149  the_thread->current_modes          = initial_modes;
150  the_thread->pending_events         = EVENT_SETS_NONE_PENDING;
151  the_thread->resource_count         = 0;
152  the_thread->real_priority          = initial_priority;
153  the_thread->Start.initial_priority = initial_priority;
154  the_thread->Start.initial_modes    = initial_modes;
155
156  _Thread_Set_priority( the_thread, initial_priority );
157
158  _ASR_Initialize( &the_thread->Signal );
159
160  _Objects_Open( &_Thread_Information, &the_thread->Object, &name );
161
162  *id = the_thread->Object.id;
163
164  _User_extensions_Task_create( the_thread );
165
166  if ( _Attributes_Is_global( the_attribute_set ) )
167    _RTEMS_tasks_MP_Send_process_packet(
168      RTEMS_TASKS_MP_ANNOUNCE_CREATE,
169      the_thread->Object.id,
170      name
171    );
172
173  _Thread_Enable_dispatch();
174  return( RTEMS_SUCCESSFUL );
175}
176
177/*PAGE
178 *
179 *  rtems_task_ident
180 *
181 *  This directive returns the system ID associated with
182 *  the thread name.
183 *
184 *  Input parameters:
185 *    name - user defined thread name
186 *    node - node(s) to be searched
187 *    id   - pointer to thread id
188 *
189 *  Output parameters:
190 *    *id               - thread id
191 *    RTEMS_SUCCESSFUL - if successful
192 *    error code        - if unsuccessful
193 */
194
195rtems_status_code rtems_task_ident(
196  rtems_name    name,
197  unsigned32    node,
198  Objects_Id   *id
199)
200{
201  if ( name != OBJECTS_ID_OF_SELF )
202    return( _Objects_Name_to_id( &_Thread_Information, &name, node, id ) );
203
204  *id = _Thread_Executing->Object.id;
205  return( RTEMS_SUCCESSFUL );
206}
207
208/*PAGE
209 *
210 *  rtems_task_start
211 *
212 *  This directive readies the thread identified by the "id"
213 *  based on its current priorty, to await execution.  A thread
214 *  can be started only from the dormant state.
215 *
216 *  Input parameters:
217 *    id          - thread id
218 *    entry_point - start execution address of thread
219 *    argument    - thread argument
220 *
221 *  Output parameters:
222 *    RTEMS_SUCCESSFUL - if successful
223 *    error code        - if unsuccessful
224 */
225
226rtems_status_code rtems_task_start(
227  Objects_Id   id,
228  rtems_task_entry entry_point,
229  unsigned32   argument
230)
231{
232  register Thread_Control *the_thread;
233  Objects_Locations        location;
234
235  if ( entry_point == NULL )
236    return( RTEMS_INVALID_ADDRESS );
237
238  the_thread = _Thread_Get( id, &location );
239  switch ( location ) {
240    case OBJECTS_ERROR:
241      return( RTEMS_INVALID_ID );
242    case OBJECTS_REMOTE:
243      _Thread_Dispatch();
244      return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT );
245    case OBJECTS_LOCAL:
246      if ( _States_Is_dormant( the_thread->current_state ) ) {
247
248        the_thread->Start.entry_point      = entry_point;
249        the_thread->Start.initial_argument = argument;
250
251        _Thread_Load_environment( the_thread );
252
253        _Thread_Ready( the_thread );
254
255        _User_extensions_Task_start( the_thread );
256
257        _Thread_Enable_dispatch();
258        return( RTEMS_SUCCESSFUL );
259      }
260      _Thread_Enable_dispatch();
261      return( RTEMS_INCORRECT_STATE );
262  }
263
264  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
265}
266
267/*PAGE
268 *
269 *  rtems_task_restart
270 *
271 *  This directive readies the specified thread.  It restores
272 *  the thread environment to the original values established
273 *  at thread creation and start time.  A thread can be restarted
274 *  from any state except the dormant state.
275 *
276 *  Input parameters:
277 *    id       - thread id
278 *    argument - thread argument
279 *
280 *  Output parameters:
281 *    RTEMS_SUCCESSFUL - if successful
282 *    error code        - if unsuccessful
283 */
284
285rtems_status_code rtems_task_restart(
286  Objects_Id id,
287  unsigned32 argument
288)
289{
290  register Thread_Control *the_thread;
291  Objects_Locations               location;
292
293  the_thread = _Thread_Get( id, &location );
294  switch ( location ) {
295    case OBJECTS_ERROR:
296      return( RTEMS_INVALID_ID );
297    case OBJECTS_REMOTE:
298      _Thread_Dispatch();
299      return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT );
300    case OBJECTS_LOCAL:
301      if ( !_States_Is_dormant( the_thread->current_state ) ) {
302
303        _Thread_Set_transient( the_thread );
304        _ASR_Initialize( &the_thread->Signal );
305        the_thread->pending_events = EVENT_SETS_NONE_PENDING;
306        the_thread->resource_count = 0;
307        the_thread->current_modes  = the_thread->Start.initial_modes;
308        the_thread->Start.initial_argument = argument;
309
310        _RTEMS_tasks_Cancel_wait( the_thread );
311
312        if ( the_thread->current_priority !=
313                         the_thread->Start.initial_priority ) {
314          the_thread->real_priority = the_thread->Start.initial_priority;
315          _Thread_Set_priority( the_thread,
316             the_thread->Start.initial_priority );
317        }
318
319        _Thread_Load_environment( the_thread );
320
321        _Thread_Ready( the_thread );
322
323        _User_extensions_Task_restart( the_thread );
324
325        if ( _Thread_Is_executing ( the_thread ) )
326          _Thread_Restart_self();
327
328        _Thread_Enable_dispatch();
329        return( RTEMS_SUCCESSFUL );
330      }
331      _Thread_Enable_dispatch();
332      return( RTEMS_INCORRECT_STATE );
333  }
334
335  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
336}
337
338/*PAGE
339 *
340 *  rtems_task_delete
341 *
342 *  This directive allows a thread to delete itself or the thread
343 *  identified in the id field.  The executive halts execution
344 *  of the thread and frees the thread control block.
345 *
346 *  Input parameters:
347 *    id - thread id
348 *
349 *  Output parameters:
350 *    nothing           - if id is the requesting thread (always succeeds)
351 *    RTEMS_SUCCESSFUL - if successful and id is
352 *                           not the requesting thread
353 *    error code        - if unsuccessful
354 */
355
356rtems_status_code rtems_task_delete(
357  Objects_Id id
358)
359{
360  register Thread_Control *the_thread;
361  Objects_Locations        location;
362
363  the_thread = _Thread_Get( id, &location );
364  switch ( location ) {
365    case OBJECTS_ERROR:
366      return( RTEMS_INVALID_ID );
367    case OBJECTS_REMOTE:
368      _Thread_Dispatch();
369      return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT );
370    case OBJECTS_LOCAL:
371      _Objects_Close( &_Thread_Information, &the_thread->Object );
372
373      _Thread_Set_state( the_thread, STATES_TRANSIENT );
374
375      _User_extensions_Task_delete( the_thread );
376
377#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
378      if ( _Thread_Is_allocated_fp( the_thread ) )
379        _Thread_Deallocate_fp();
380#endif
381      the_thread->fp_context = NULL;
382
383      _RTEMS_tasks_Cancel_wait( the_thread );
384
385      (void) _Workspace_Free( the_thread->Start.Initial_stack.area );
386
387      _RTEMS_tasks_Free( the_thread );
388
389      if ( _Attributes_Is_global( the_thread->attribute_set ) ) {
390
391        _Objects_MP_Close( &_Thread_Information, the_thread->Object.id );
392
393        _RTEMS_tasks_MP_Send_process_packet(
394          RTEMS_TASKS_MP_ANNOUNCE_DELETE,
395          the_thread->Object.id,
396          0                                /* Not used */
397        );
398      }
399
400      _Thread_Enable_dispatch();
401      return( RTEMS_SUCCESSFUL );
402  }
403
404  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
405}
406
407/*PAGE
408 *
409 *  rtems_task_suspend
410 *
411 *  This directive will place the specified thread in the "suspended"
412 *  state.  Note that the suspended state can be in addition to
413 *  other waiting states.
414 *
415 *  Input parameters:
416 *    id - thread id
417 *
418 *  Output parameters:
419 *    RTEMS_SUCCESSFUL - if successful
420 *    error code        - if unsuccessful
421 */
422
423rtems_status_code rtems_task_suspend(
424  Objects_Id id
425)
426{
427  register Thread_Control *the_thread;
428  Objects_Locations               location;
429
430  the_thread = _Thread_Get( id, &location );
431  switch ( location ) {
432    case OBJECTS_ERROR:
433      return( RTEMS_INVALID_ID );
434    case OBJECTS_REMOTE:
435      return(
436        _RTEMS_tasks_MP_Send_request_packet(
437          RTEMS_TASKS_MP_SUSPEND_REQUEST,
438          id,
439          0,          /* Not used */
440          0,          /* Not used */
441          0           /* Not used */
442        )
443      );
444    case OBJECTS_LOCAL:
445      if ( !_States_Is_suspended( the_thread->current_state ) ) {
446        _Thread_Set_state( the_thread, STATES_SUSPENDED );
447        _Thread_Enable_dispatch();
448        return( RTEMS_SUCCESSFUL );
449      }
450      _Thread_Enable_dispatch();
451      return( RTEMS_ALREADY_SUSPENDED );
452  }
453
454  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
455}
456
457/*PAGE
458 *
459 *  rtems_task_resume
460 *
461 *  This directive will remove the specified thread
462 *  from the suspended state.
463 *
464 *  Input parameters:
465 *    id - thread id
466 *
467 *  Output parameters:
468 *    RTEMS_SUCCESSFUL - if successful
469 *    error code        - if unsuccessful
470 */
471
472rtems_status_code rtems_task_resume(
473  Objects_Id id
474)
475{
476  register Thread_Control *the_thread;
477  Objects_Locations        location;
478
479  the_thread = _Thread_Get( id, &location );
480  switch ( location ) {
481    case OBJECTS_ERROR:
482      return( RTEMS_INVALID_ID );
483    case OBJECTS_REMOTE:
484      return(
485        _RTEMS_tasks_MP_Send_request_packet(
486          RTEMS_TASKS_MP_RESUME_REQUEST,
487          id,
488          0,          /* Not used */
489          0,          /* Not used */
490          0           /* Not used */
491        )
492      );
493    case OBJECTS_LOCAL:
494      if ( _States_Is_suspended( the_thread->current_state ) ) {
495        _Thread_Resume( the_thread );
496        _Thread_Enable_dispatch();
497        return( RTEMS_SUCCESSFUL );
498      }
499      _Thread_Enable_dispatch();
500      return( RTEMS_INCORRECT_STATE );
501  }
502
503  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
504}
505
506/*PAGE
507 *
508 *  rtems_task_set_priority
509 *
510 *  This directive changes the priority of the specified thread.
511 *  The specified thread can be any thread in the system including
512 *  the requesting thread.
513 *
514 *  Input parameters:
515 *    id           - thread id (0 indicates requesting thread)
516 *    new_priority - thread priority (0 indicates current priority)
517 *    old_priority - pointer to previous priority
518 *
519 *  Output parameters:
520 *    old_priority      - previous priority
521 *    RTEMS_SUCCESSFUL - if successful
522 *    error code        - if unsuccessful
523 */
524
525rtems_status_code rtems_task_set_priority(
526  Objects_Id        id,
527  rtems_task_priority  new_priority,
528  rtems_task_priority *old_priority
529)
530{
531  register Thread_Control *the_thread;
532  Objects_Locations               location;
533
534  if ( new_priority != RTEMS_CURRENT_PRIORITY &&
535       !_Priority_Is_valid( new_priority ) )
536    return( RTEMS_INVALID_PRIORITY );
537
538  the_thread = _Thread_Get( id, &location );
539  switch ( location ) {
540    case OBJECTS_ERROR:
541      return( RTEMS_INVALID_ID );
542    case OBJECTS_REMOTE:
543      _Thread_Executing->Wait.return_argument = old_priority;
544      return(
545        _RTEMS_tasks_MP_Send_request_packet(
546          RTEMS_TASKS_MP_SET_PRIORITY_REQUEST,
547          id,
548          new_priority,
549          0,          /* Not used */
550          0           /* Not used */
551        )
552      );
553    case OBJECTS_LOCAL:
554      *old_priority = the_thread->current_priority;
555      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
556        the_thread->real_priority = new_priority;
557        if ( the_thread->resource_count == 0 ||
558             the_thread->current_priority > new_priority )
559          _Thread_Change_priority( the_thread, new_priority );
560      }
561      _Thread_Enable_dispatch();
562      return( RTEMS_SUCCESSFUL );
563  }
564
565  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
566}
567
568/*PAGE
569 *
570 *  rtems_task_mode
571 *
572 *  This directive enables and disables several modes of
573 *  execution for the requesting thread.
574 *
575 *  Input parameters:
576 *    mode_set          - new mode
577 *    mask              - mask
578 *    previous_mode_set - address of previous mode set
579 *
580 *  Output:
581 *    *previous_mode_set - previous mode set
582 *     always returns RTEMS_SUCCESSFUL
583 */
584
585rtems_status_code rtems_task_mode(
586  rtems_mode  mode_set,
587  rtems_mode  mask,
588  rtems_mode *previous_mode_set
589)
590{
591  if ( _Thread_Change_mode( mode_set, mask, previous_mode_set ) )
592    _Thread_Dispatch();
593  return( RTEMS_SUCCESSFUL );
594}
595
596/*PAGE
597 *
598 *  rtems_task_get_note
599 *
600 *  This directive obtains the note from the specified notepad
601 *  of the specified thread.
602 *
603 *  Input parameters:
604 *    id      - thread id
605 *    notepad - notepad number
606 *    note    - pointer to note
607 *
608 *  Output parameters:
609 *    note              - filled in if successful
610 *    RTEMS_SUCCESSFUL - if successful
611 *    error code        - if unsuccessful
612 */
613
614rtems_status_code rtems_task_get_note(
615  Objects_Id  id,
616  unsigned32  notepad,
617  unsigned32 *note
618)
619{
620  register Thread_Control *the_thread;
621  Objects_Locations        location;
622
623  /*
624   *  NOTE:  There is no check for < RTEMS_NOTEPAD_FIRST because that would
625   *         be checking an unsigned number for being negative.
626   */
627
628  if ( notepad > RTEMS_NOTEPAD_LAST )
629    return( RTEMS_INVALID_NUMBER );
630
631  /*
632   *  Optimize the most likely case to avoid the Thread_Dispatch.
633   */
634
635  if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
636       _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {
637      *note = _Thread_Executing->Notepads[ notepad ];
638      return( RTEMS_SUCCESSFUL );
639  }
640
641  the_thread = _Thread_Get( id, &location );
642  switch ( location ) {
643    case OBJECTS_ERROR:
644      return( RTEMS_INVALID_ID );
645    case OBJECTS_REMOTE:
646      _Thread_Executing->Wait.return_argument = note;
647
648      return _RTEMS_tasks_MP_Send_request_packet(
649        RTEMS_TASKS_MP_GET_NOTE_REQUEST,
650        id,
651        0,          /* Not used */
652        notepad,
653        0           /* Not used */
654      );
655    case OBJECTS_LOCAL:
656      *note= the_thread->Notepads[ notepad ];
657      _Thread_Enable_dispatch();
658      return( RTEMS_SUCCESSFUL );
659  }
660
661  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
662}
663
664/*PAGE
665 *
666 * rtems_task_set_note
667 *
668 *  This directive sets the specified notepad contents to the given
669 *  note.
670 *
671 *  Input parameters:
672 *    id      - thread id
673 *    notepad - notepad number
674 *    note    - note value
675 *
676 *  Output parameters:
677 *    RTEMS_SUCCESSFUL - if successful
678 *    error code        - if unsuccessful
679 */
680
681rtems_status_code rtems_task_set_note(
682  Objects_Id id,
683  unsigned32 notepad,
684  unsigned32 note
685)
686{
687  register Thread_Control *the_thread;
688  Objects_Locations        location;
689
690  /*
691   *  NOTE:  There is no check for < RTEMS_NOTEPAD_FIRST because that would
692   *         be checking an unsigned number for being negative.
693   */
694
695  if ( notepad > RTEMS_NOTEPAD_LAST )
696    return( RTEMS_INVALID_NUMBER );
697
698  /*
699   *  Optimize the most likely case to avoid the Thread_Dispatch.
700   */
701
702  if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
703       _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {
704      _Thread_Executing->Notepads[ notepad ] = note;
705      return( RTEMS_SUCCESSFUL );
706  }
707
708  the_thread = _Thread_Get( id, &location );
709  switch ( location ) {
710    case OBJECTS_ERROR:
711      return( RTEMS_INVALID_ID );
712    case OBJECTS_REMOTE:
713      return _RTEMS_tasks_MP_Send_request_packet(
714        RTEMS_TASKS_MP_SET_NOTE_REQUEST,
715        id,
716        0,          /* Not used */
717        notepad,
718        note
719      );
720
721    case OBJECTS_LOCAL:
722      the_thread->Notepads[ notepad ] = note;
723      _Thread_Enable_dispatch();
724      return( RTEMS_SUCCESSFUL );
725  }
726
727  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
728}
729
730/*PAGE
731 *
732 *  rtems_task_wake_after
733 *
734 *  This directive suspends the requesting thread for the given amount
735 *  of ticks.
736 *
737 *  Input parameters:
738 *    ticks - number of ticks to wait
739 *
740 *  Output parameters:
741 *    RTEMS_SUCCESSFUL - always successful
742 */
743
744rtems_status_code rtems_task_wake_after(
745  rtems_interval ticks
746)
747{
748  if ( ticks == 0 ) {
749    _Thread_Yield_processor();
750    _Thread_Dispatch();
751  } else {
752    _Thread_Disable_dispatch();
753      _Thread_Set_state( _Thread_Executing, STATES_DELAYING );
754      _Watchdog_Initialize(
755        &_Thread_Executing->Timer,
756        _Thread_Delay_ended,
757        _Thread_Executing->Object.id,
758        NULL
759      );
760      _Watchdog_Insert_ticks( &_Thread_Executing->Timer,
761                              ticks, WATCHDOG_ACTIVATE_NOW );
762    _Thread_Enable_dispatch();
763  }
764  return( RTEMS_SUCCESSFUL );
765}
766
767/*PAGE
768 *
769 *  rtems_task_wake_when
770 *
771 *  This directive blocks the requesting thread until the given date and
772 *  time is reached.
773 *
774 *  Input parameters:
775 *    time_buffer - pointer to the time and date structure
776 *
777 *  Output parameters:
778 *    RTEMS_SUCCESSFUL - if successful
779 *    error code        - if unsuccessful
780 */
781
782rtems_status_code rtems_task_wake_when(
783rtems_time_of_day *time_buffer
784)
785{
786  rtems_interval seconds;
787  rtems_status_code      local_result;
788
789  if ( !_TOD_Is_set() )
790    return( RTEMS_NOT_DEFINED );
791
792  time_buffer->ticks = 0;
793
794  local_result = _TOD_Validate( time_buffer );
795
796  if  ( !rtems_is_status_successful( local_result ) )
797    return( local_result );
798
799  seconds = _TOD_To_seconds( time_buffer );
800
801  if ( seconds <= _TOD_Seconds_since_epoch )
802    return( RTEMS_INVALID_CLOCK );
803
804  _Thread_Disable_dispatch();
805    _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
806    _Watchdog_Initialize(
807      &_Thread_Executing->Timer,
808      _Thread_Delay_ended,
809      _Thread_Executing->Object.id,
810      NULL
811    );
812    _Watchdog_Insert_seconds( &_Thread_Executing->Timer,
813            seconds - _TOD_Seconds_since_epoch, WATCHDOG_ACTIVATE_NOW );
814  _Thread_Enable_dispatch();
815  return( RTEMS_SUCCESSFUL );
816}
Note: See TracBrowser for help on using the repository browser.