source: rtems/c/src/exec/rtems/src/tasks.c @ 9863dbf

4.104.114.84.95
Last change on this file since 9863dbf was 9863dbf, checked in by Joel Sherrill <joel.sherrill@…>, on 08/18/95 at 21:42:58

+ Added object type field to object id.

+ Added name pointer to Object_Control.

+ Modified Object Open and Close to address name field.

+ Removed name as separate element from Thread and Proxy Control.

+ Added parameter "object class" to calls to Initialize Information

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