source: rtems/c/src/exec/rtems/src/tasks.c @ 4ca27cf

4.104.114.84.95
Last change on this file since 4ca27cf was ac7d5ef0, checked in by Joel Sherrill <joel.sherrill@…>, on 05/11/95 at 17:39:37

Initial revision

  • 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/modes.h>
18#include <rtems/object.h>
19#include <rtems/stack.h>
20#include <rtems/states.h>
21#include <rtems/tasks.h>
22#include <rtems/thread.h>
23#include <rtems/threadq.h>
24#include <rtems/tod.h>
25#include <rtems/userext.h>
26#include <rtems/wkspace.h>
27
28/*PAGE
29 *
30 *  rtems_task_create
31 *
32 *  This directive creates a thread by allocating and initializing a
33 *  thread control block and a stack.  The newly created thread is
34 *  placed in the dormant state.
35 *
36 *  Input parameters:
37 *    name             - user defined thread name
38 *    initial_priority - thread priority
39 *    stack_size       - stack size in bytes
40 *    initial_modes    - initial thread mode
41 *    attribute_set    - thread attributes
42 *    id               - pointer to thread id
43 *
44 *  Output parameters:
45 *    id                - thread id
46 *    RTEMS_SUCCESSFUL - if successful
47 *    error code        - if unsuccessful
48 */
49
50rtems_status_code rtems_task_create(
51  Objects_Name         name,
52  rtems_task_priority  initial_priority,
53  unsigned32           stack_size,
54  rtems_mode           initial_modes,
55  rtems_attribute      attribute_set,
56  Objects_Id          *id
57)
58{
59  register Thread_Control *the_thread;
60  unsigned32               actual_stack_size;
61  unsigned32               memory_needed;
62  void                    *memory;
63  rtems_attribute          the_attribute_set;
64
65  if ( !_Objects_Is_name_valid( name ) )
66    return ( RTEMS_INVALID_NAME );
67
68#if 0
69  if ( !_Stack_Is_enough( stack_size ) )
70    return( RTEMS_INVALID_SIZE );
71#endif
72
73  if ( !_Stack_Is_enough( stack_size ) )
74    actual_stack_size = RTEMS_MINIMUM_STACK_SIZE;
75  else
76    actual_stack_size = stack_size;
77
78  if ( !_Priority_Is_valid( initial_priority ) )
79    return( RTEMS_INVALID_PRIORITY );
80
81  /*
82   *  Fix the attribute set to match the attributes which
83   *  this processor (1) requires and (2) is able to support.
84   *  First add in the required flags for attribute_set
85   *  Typically this might include FP if the platform
86   *  or application required all tasks to be fp aware.
87   *  Then turn off the requested bits which are not supported.
88   */
89
90  the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
91  the_attribute_set =
92    _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
93
94  if ( _Attributes_Is_global( the_attribute_set ) &&
95       !_Configuration_Is_multiprocessing() )
96    return( RTEMS_MP_NOT_CONFIGURED );
97
98  _Thread_Disable_dispatch();          /* to prevent deletion */
99
100  the_thread = _RTEMS_tasks_Allocate();
101
102  if ( !the_thread ) {
103    _Thread_Enable_dispatch();
104    return( RTEMS_TOO_MANY );
105  }
106
107  actual_stack_size = _Stack_Adjust_size( actual_stack_size );
108  memory_needed = actual_stack_size;
109
110  if ( _Attributes_Is_floating_point( the_attribute_set ) )
111    memory_needed += CONTEXT_FP_SIZE;
112
113  memory = _Workspace_Allocate( memory_needed );
114
115  if ( !memory ) {
116    _RTEMS_tasks_Free( the_thread );
117    _Thread_Enable_dispatch();
118    return( RTEMS_UNSATISFIED );
119  }
120
121  /*
122   *  Stack is put in the lower address regions of the allocated memory.
123   *  The optional floating point context area goes into the higher part
124   *  of the allocated memory.
125   */
126
127  _Stack_Initialize(
128     &the_thread->Start.Initial_stack, memory, actual_stack_size );
129
130  if ( _Attributes_Is_floating_point( the_attribute_set ) )
131    the_thread->fp_context = _Context_Fp_start( memory, actual_stack_size );
132  else
133    the_thread->fp_context = NULL;
134
135  the_thread->Start.fp_context = the_thread->fp_context;
136
137  if ( _Attributes_Is_global( the_attribute_set ) &&
138       !( _Objects_MP_Open( &_Thread_Information, name,
139                            the_thread->Object.id, FALSE ) ) ) {
140    _RTEMS_tasks_Free( the_thread );
141    (void) _Workspace_Free( memory );
142    _Thread_Enable_dispatch();
143    return( RTEMS_TOO_MANY );
144  }
145
146  the_thread->name                   = name;
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  Objects_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.