source: rtems/cpukit/rtems/src/tasks.c @ 7f6a24ab

4.104.114.84.95
Last change on this file since 7f6a24ab was 7f6a24ab, checked in by Joel Sherrill <joel.sherrill@…>, on 08/28/95 at 15:30:29

Added unused priority ceiling parameter to rtems_semaphore_create.

Rearranged code to created thread handler routines to initialize,
start, restart, and "close/delete" a thread.

Made internal threads their own object class. This now uses the
thread support routines for starting and initializing a thread.

Insured deleted tasks are freed to the Inactive pool associated with the
correct Information block.

Added an RTEMS API specific data area to the thread control block.

Beginnings of removing the word "rtems" from the core.

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