source: rtems/c/src/exec/rtems/src/tasks.c @ 5250ff39

4.104.114.84.9
Last change on this file since 5250ff39 was 5250ff39, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 23, 1995 at 9:06:31 PM

Moved _Thread_Information -> _RTEMS_tasks_Information.

Added a table of object information control blocks.

Modified _Thread_Get so it looks up a thread regardless of which
thread management "entity" (manager, internal, etc) actually "owns" it.

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