Changeset c4d69e2 in rtems
- Timestamp:
- May 17, 1999, 9:02:16 PM (22 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- d7851582
- Parents:
- 05df0a8
- Files:
-
- 28 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/rtems/src/Makefile.in
r05df0a8 rc4d69e2 20 20 MP_PIECES = $(MP_PIECES_$(HAS_MP)_V) 21 21 22 TASK_PIECES=\ 23 tasks taskcreate taskdelete taskgetnote taskident taskinitusers \ 24 taskmode taskrestart taskresume tasksetnote tasksetpriority \ 25 taskstart tasksuspend taskwakeafter taskwakewhen 26 22 27 C_PIECES=attr clock dpmem event intr intrbody msg \ 23 28 part ratemon region sem signal \ 24 taskstimer $(MP_PIECES)29 $(TASK_PIECES) timer $(MP_PIECES) 25 30 C_FILES=$(C_PIECES:%=%.c) 26 31 C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) -
c/src/exec/rtems/src/tasks.c
r05df0a8 rc4d69e2 216 216 } 217 217 218 /*PAGE219 *220 * rtems_task_create221 *222 * This directive creates a thread by allocating and initializing a223 * thread control block and a stack. The newly created thread is224 * placed in the dormant state.225 *226 * Input parameters:227 * name - user defined thread name228 * initial_priority - thread priority229 * stack_size - stack size in bytes230 * initial_modes - initial thread mode231 * attribute_set - thread attributes232 * id - pointer to thread id233 *234 * Output parameters:235 * id - thread id236 * RTEMS_SUCCESSFUL - if successful237 * error code - if unsuccessful238 */239 240 rtems_status_code rtems_task_create(241 rtems_name name,242 rtems_task_priority initial_priority,243 unsigned32 stack_size,244 rtems_mode initial_modes,245 rtems_attribute attribute_set,246 Objects_Id *id247 )248 {249 register Thread_Control *the_thread;250 boolean is_fp;251 #if defined(RTEMS_MULTIPROCESSING)252 Objects_MP_Control *the_global_object = NULL;253 boolean is_global;254 #endif255 boolean status;256 rtems_attribute the_attribute_set;257 Priority_Control core_priority;258 RTEMS_API_Control *api;259 ASR_Information *asr;260 261 262 if ( !rtems_is_name_valid( name ) )263 return RTEMS_INVALID_NAME;264 265 /*266 * Core Thread Initialize insures we get the minimum amount of267 * stack space.268 */269 270 #if 0271 if ( !_Stack_Is_enough( stack_size ) )272 return RTEMS_INVALID_SIZE;273 #endif274 275 /*276 * Fix the attribute set to match the attributes which277 * this processor (1) requires and (2) is able to support.278 * First add in the required flags for attribute_set279 * Typically this might include FP if the platform280 * or application required all tasks to be fp aware.281 * Then turn off the requested bits which are not supported.282 */283 284 the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );285 the_attribute_set =286 _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );287 288 if ( _Attributes_Is_floating_point( the_attribute_set ) )289 is_fp = TRUE;290 else291 is_fp = FALSE;292 293 /*294 * Validate the RTEMS API priority and convert it to the core priority range.295 */296 297 if ( !_Attributes_Is_system_task( the_attribute_set ) ) {298 if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) )299 return RTEMS_INVALID_PRIORITY;300 }301 302 core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority );303 304 #if defined(RTEMS_MULTIPROCESSING)305 if ( _Attributes_Is_global( the_attribute_set ) ) {306 307 is_global = TRUE;308 309 if ( !_System_state_Is_multiprocessing )310 return RTEMS_MP_NOT_CONFIGURED;311 312 } else313 is_global = FALSE;314 #endif315 316 /*317 * Make sure system is MP if this task is global318 */319 320 /*321 * Disable dispatch for protection322 */323 324 _Thread_Disable_dispatch();325 326 /*327 * Allocate the thread control block and -- if the task is global --328 * allocate a global object control block.329 *330 * NOTE: This routine does not use the combined allocate and open331 * global object routine because this results in a lack of332 * control over when memory is allocated and can be freed in333 * the event of an error.334 */335 336 the_thread = _RTEMS_tasks_Allocate();337 338 if ( !the_thread ) {339 _Thread_Enable_dispatch();340 return RTEMS_TOO_MANY;341 }342 343 #if defined(RTEMS_MULTIPROCESSING)344 if ( is_global ) {345 the_global_object = _Objects_MP_Allocate_global_object();346 347 if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {348 _RTEMS_tasks_Free( the_thread );349 _Thread_Enable_dispatch();350 return RTEMS_TOO_MANY;351 }352 }353 #endif354 355 /*356 * Initialize the core thread for this task.357 */358 359 status = _Thread_Initialize(360 &_RTEMS_tasks_Information,361 the_thread,362 NULL,363 stack_size,364 is_fp,365 core_priority,366 _Modes_Is_preempt(initial_modes) ? TRUE : FALSE,367 _Modes_Is_timeslice(initial_modes) ?368 THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :369 THREAD_CPU_BUDGET_ALGORITHM_NONE,370 NULL, /* no budget algorithm callout */371 _Modes_Get_interrupt_level(initial_modes),372 &name373 );374 375 if ( !status ) {376 #if defined(RTEMS_MULTIPROCESSING)377 if ( is_global )378 _Objects_MP_Free_global_object( the_global_object );379 #endif380 _RTEMS_tasks_Free( the_thread );381 _Thread_Enable_dispatch();382 return RTEMS_UNSATISFIED;383 }384 385 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];386 asr = &api->Signal;387 388 asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE;389 390 *id = the_thread->Object.id;391 392 #if defined(RTEMS_MULTIPROCESSING)393 if ( is_global ) {394 395 the_thread->is_global = TRUE;396 397 _Objects_MP_Open(398 &_RTEMS_tasks_Information,399 the_global_object,400 name,401 the_thread->Object.id402 );403 404 _RTEMS_tasks_MP_Send_process_packet(405 RTEMS_TASKS_MP_ANNOUNCE_CREATE,406 the_thread->Object.id,407 name408 );409 410 }411 #endif412 413 _Thread_Enable_dispatch();414 return RTEMS_SUCCESSFUL;415 }416 417 /*PAGE418 *419 * rtems_task_ident420 *421 * This directive returns the system ID associated with422 * the thread name.423 *424 * Input parameters:425 * name - user defined thread name426 * node - node(s) to be searched427 * id - pointer to thread id428 *429 * Output parameters:430 * *id - thread id431 * RTEMS_SUCCESSFUL - if successful432 * error code - if unsuccessful433 */434 435 rtems_status_code rtems_task_ident(436 rtems_name name,437 unsigned32 node,438 Objects_Id *id439 )440 {441 Objects_Name_to_id_errors status;442 443 if ( name == OBJECTS_ID_OF_SELF ) {444 *id = _Thread_Executing->Object.id;445 return RTEMS_SUCCESSFUL;446 }447 448 status = _Objects_Name_to_id( &_RTEMS_tasks_Information, &name, node, id );449 450 return _Status_Object_name_errors_to_status[ status ];451 }452 453 /*PAGE454 *455 * rtems_task_start456 *457 * This directive readies the thread identified by the "id"458 * based on its current priorty, to await execution. A thread459 * can be started only from the dormant state.460 *461 * Input parameters:462 * id - thread id463 * entry_point - start execution address of thread464 * argument - thread argument465 *466 * Output parameters:467 * RTEMS_SUCCESSFUL - if successful468 * error code - if unsuccessful469 */470 471 rtems_status_code rtems_task_start(472 rtems_id id,473 rtems_task_entry entry_point,474 unsigned32 argument475 )476 {477 register Thread_Control *the_thread;478 Objects_Locations location;479 480 if ( entry_point == NULL )481 return RTEMS_INVALID_ADDRESS;482 483 the_thread = _Thread_Get( id, &location );484 switch ( location ) {485 486 case OBJECTS_REMOTE:487 #if defined(RTEMS_MULTIPROCESSING)488 _Thread_Dispatch();489 return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;490 #endif491 492 case OBJECTS_ERROR:493 return RTEMS_INVALID_ID;494 495 case OBJECTS_LOCAL:496 if ( _Thread_Start(497 the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) {498 _Thread_Enable_dispatch();499 return RTEMS_SUCCESSFUL;500 }501 _Thread_Enable_dispatch();502 return RTEMS_INCORRECT_STATE;503 }504 505 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */506 }507 508 /*PAGE509 *510 * rtems_task_restart511 *512 * This directive readies the specified thread. It restores513 * the thread environment to the original values established514 * at thread creation and start time. A thread can be restarted515 * from any state except the dormant state.516 *517 * Input parameters:518 * id - thread id519 * argument - thread argument520 *521 * Output parameters:522 * RTEMS_SUCCESSFUL - if successful523 * error code - if unsuccessful524 */525 526 rtems_status_code rtems_task_restart(527 Objects_Id id,528 unsigned32 argument529 )530 {531 register Thread_Control *the_thread;532 Objects_Locations location;533 534 the_thread = _Thread_Get( id, &location );535 switch ( location ) {536 537 case OBJECTS_REMOTE:538 #if defined(RTEMS_MULTIPROCESSING)539 _Thread_Dispatch();540 return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;541 #endif542 543 case OBJECTS_ERROR:544 return RTEMS_INVALID_ID;545 546 case OBJECTS_LOCAL:547 if ( _Thread_Restart( the_thread, NULL, argument ) ) {548 _Thread_Enable_dispatch();549 return RTEMS_SUCCESSFUL;550 }551 _Thread_Enable_dispatch();552 return RTEMS_INCORRECT_STATE;553 }554 555 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */556 }557 558 /*PAGE559 *560 * rtems_task_delete561 *562 * This directive allows a thread to delete itself or the thread563 * identified in the id field. The executive halts execution564 * of the thread and frees the thread control block.565 *566 * Input parameters:567 * id - thread id568 *569 * Output parameters:570 * nothing - if id is the requesting thread (always succeeds)571 * RTEMS_SUCCESSFUL - if successful and id is572 * not the requesting thread573 * error code - if unsuccessful574 */575 576 rtems_status_code rtems_task_delete(577 Objects_Id id578 )579 {580 register Thread_Control *the_thread;581 Objects_Locations location;582 Objects_Information *the_information;583 584 the_thread = _Thread_Get( id, &location );585 switch ( location ) {586 587 case OBJECTS_REMOTE:588 #if defined(RTEMS_MULTIPROCESSING)589 _Thread_Dispatch();590 return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;591 #endif592 593 case OBJECTS_ERROR:594 return RTEMS_INVALID_ID;595 596 case OBJECTS_LOCAL:597 the_information = _Objects_Get_information( the_thread->Object.id );598 599 if ( !the_information ) {600 _Thread_Enable_dispatch();601 return RTEMS_INVALID_ID;602 /* This should never happen if _Thread_Get() works right */603 }604 605 _Thread_Close( the_information, the_thread );606 607 _RTEMS_tasks_Free( the_thread );608 609 #if defined(RTEMS_MULTIPROCESSING)610 if ( the_thread->is_global ) {611 612 _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id );613 614 _RTEMS_tasks_MP_Send_process_packet(615 RTEMS_TASKS_MP_ANNOUNCE_DELETE,616 the_thread->Object.id,617 0 /* Not used */618 );619 }620 #endif621 622 _Thread_Enable_dispatch();623 return RTEMS_SUCCESSFUL;624 }625 626 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */627 }628 629 /*PAGE630 *631 * rtems_task_suspend632 *633 * This directive will place the specified thread in the "suspended"634 * state. Note that the suspended state can be in addition to635 * other waiting states.636 *637 * Input parameters:638 * id - thread id639 *640 * Output parameters:641 * RTEMS_SUCCESSFUL - if successful642 * error code - if unsuccessful643 */644 645 rtems_status_code rtems_task_suspend(646 Objects_Id id647 )648 {649 register Thread_Control *the_thread;650 Objects_Locations location;651 652 the_thread = _Thread_Get( id, &location );653 switch ( location ) {654 655 case OBJECTS_REMOTE:656 #if defined(RTEMS_MULTIPROCESSING)657 return _RTEMS_tasks_MP_Send_request_packet(658 RTEMS_TASKS_MP_SUSPEND_REQUEST,659 id,660 0, /* Not used */661 0, /* Not used */662 0 /* Not used */663 );664 #endif665 666 case OBJECTS_ERROR:667 return RTEMS_INVALID_ID;668 669 case OBJECTS_LOCAL:670 if ( !_States_Is_suspended( the_thread->current_state ) ) {671 _Thread_Set_state( the_thread, STATES_SUSPENDED );672 _Thread_Enable_dispatch();673 return RTEMS_SUCCESSFUL;674 }675 _Thread_Enable_dispatch();676 return RTEMS_ALREADY_SUSPENDED;677 }678 679 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */680 }681 682 /*PAGE683 *684 * rtems_task_resume685 *686 * This directive will remove the specified thread687 * from the suspended state.688 *689 * Input parameters:690 * id - thread id691 *692 * Output parameters:693 * RTEMS_SUCCESSFUL - if successful694 * error code - if unsuccessful695 */696 697 rtems_status_code rtems_task_resume(698 Objects_Id id699 )700 {701 register Thread_Control *the_thread;702 Objects_Locations location;703 704 the_thread = _Thread_Get( id, &location );705 switch ( location ) {706 707 case OBJECTS_REMOTE:708 #if defined(RTEMS_MULTIPROCESSING)709 return _RTEMS_tasks_MP_Send_request_packet(710 RTEMS_TASKS_MP_RESUME_REQUEST,711 id,712 0, /* Not used */713 0, /* Not used */714 0 /* Not used */715 );716 #endif717 718 case OBJECTS_ERROR:719 return RTEMS_INVALID_ID;720 721 case OBJECTS_LOCAL:722 if ( _States_Is_suspended( the_thread->current_state ) ) {723 _Thread_Resume( the_thread );724 _Thread_Enable_dispatch();725 return RTEMS_SUCCESSFUL;726 }727 _Thread_Enable_dispatch();728 return RTEMS_INCORRECT_STATE;729 }730 731 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */732 }733 734 /*PAGE735 *736 * rtems_task_set_priority737 *738 * This directive changes the priority of the specified thread.739 * The specified thread can be any thread in the system including740 * the requesting thread.741 *742 * Input parameters:743 * id - thread id (0 indicates requesting thread)744 * new_priority - thread priority (0 indicates current priority)745 * old_priority - pointer to previous priority746 *747 * Output parameters:748 * old_priority - previous priority749 * RTEMS_SUCCESSFUL - if successful750 * error code - if unsuccessful751 */752 753 rtems_status_code rtems_task_set_priority(754 Objects_Id id,755 rtems_task_priority new_priority,756 rtems_task_priority *old_priority757 )758 {759 register Thread_Control *the_thread;760 Objects_Locations location;761 762 if ( new_priority != RTEMS_CURRENT_PRIORITY &&763 !_RTEMS_tasks_Priority_is_valid( new_priority ) )764 return RTEMS_INVALID_PRIORITY;765 766 the_thread = _Thread_Get( id, &location );767 switch ( location ) {768 769 case OBJECTS_REMOTE:770 #if defined(RTEMS_MULTIPROCESSING)771 _Thread_Executing->Wait.return_argument = old_priority;772 return _RTEMS_tasks_MP_Send_request_packet(773 RTEMS_TASKS_MP_SET_PRIORITY_REQUEST,774 id,775 new_priority,776 0, /* Not used */777 0 /* Not used */778 );779 #endif780 781 case OBJECTS_ERROR:782 return RTEMS_INVALID_ID;783 784 case OBJECTS_LOCAL:785 *old_priority = the_thread->current_priority;786 if ( new_priority != RTEMS_CURRENT_PRIORITY ) {787 the_thread->real_priority = new_priority;788 if ( the_thread->resource_count == 0 ||789 the_thread->current_priority > new_priority )790 _Thread_Change_priority( the_thread, new_priority, FALSE );791 }792 _Thread_Enable_dispatch();793 return RTEMS_SUCCESSFUL;794 }795 796 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */797 }798 799 /*PAGE800 *801 * rtems_task_mode802 *803 * This directive enables and disables several modes of804 * execution for the requesting thread.805 *806 * Input parameters:807 * mode_set - new mode808 * mask - mask809 * previous_mode_set - address of previous mode set810 *811 * Output:812 * *previous_mode_set - previous mode set813 * always return RTEMS_SUCCESSFUL;814 */815 816 rtems_status_code rtems_task_mode(817 rtems_mode mode_set,818 rtems_mode mask,819 rtems_mode *previous_mode_set820 )821 {822 Thread_Control *executing;823 RTEMS_API_Control *api;824 ASR_Information *asr;825 boolean is_asr_enabled = FALSE;826 boolean needs_asr_dispatching = FALSE;827 rtems_mode old_mode;828 829 executing = _Thread_Executing;830 api = executing->API_Extensions[ THREAD_API_RTEMS ];831 asr = &api->Signal;832 833 old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;834 835 if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )836 old_mode |= RTEMS_NO_TIMESLICE;837 else838 old_mode |= RTEMS_TIMESLICE;839 840 old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;841 old_mode |= _ISR_Get_level();842 843 *previous_mode_set = old_mode;844 845 /*846 * These are generic thread scheduling characteristics.847 */848 849 if ( mask & RTEMS_PREEMPT_MASK )850 executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;851 852 if ( mask & RTEMS_TIMESLICE_MASK ) {853 if ( _Modes_Is_timeslice(mode_set) )854 executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;855 else856 executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;857 }858 859 /*860 * Set the new interrupt level861 */862 863 if ( mask & RTEMS_INTERRUPT_MASK )864 _Modes_Set_interrupt_level( mode_set );865 866 /*867 * This is specific to the RTEMS API868 */869 870 is_asr_enabled = FALSE;871 needs_asr_dispatching = FALSE;872 873 if ( mask & RTEMS_ASR_MASK ) {874 is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE;875 if ( is_asr_enabled != asr->is_enabled ) {876 asr->is_enabled = is_asr_enabled;877 _ASR_Swap_signals( asr );878 if ( _ASR_Are_signals_pending( asr ) ) {879 needs_asr_dispatching = TRUE;880 executing->do_post_task_switch_extension = TRUE;881 }882 }883 }884 885 if ( _Thread_Evaluate_mode() || needs_asr_dispatching )886 _Thread_Dispatch();887 888 return RTEMS_SUCCESSFUL;889 }890 891 /*PAGE892 *893 * rtems_task_get_note894 *895 * This directive obtains the note from the specified notepad896 * of the specified thread.897 *898 * Input parameters:899 * id - thread id900 * notepad - notepad number901 * note - pointer to note902 *903 * Output parameters:904 * note - filled in if successful905 * RTEMS_SUCCESSFUL - if successful906 * error code - if unsuccessful907 */908 909 rtems_status_code rtems_task_get_note(910 Objects_Id id,911 unsigned32 notepad,912 unsigned32 *note913 )914 {915 register Thread_Control *the_thread;916 Objects_Locations location;917 RTEMS_API_Control *api;918 919 /*920 * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would921 * be checking an unsigned number for being negative.922 */923 924 if ( notepad > RTEMS_NOTEPAD_LAST )925 return RTEMS_INVALID_NUMBER;926 927 /*928 * Optimize the most likely case to avoid the Thread_Dispatch.929 */930 931 if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||932 _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {933 api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];934 *note = api->Notepads[ notepad ];935 return RTEMS_SUCCESSFUL;936 }937 938 the_thread = _Thread_Get( id, &location );939 switch ( location ) {940 941 case OBJECTS_REMOTE:942 #if defined(RTEMS_MULTIPROCESSING)943 _Thread_Executing->Wait.return_argument = note;944 945 return _RTEMS_tasks_MP_Send_request_packet(946 RTEMS_TASKS_MP_GET_NOTE_REQUEST,947 id,948 0, /* Not used */949 notepad,950 0 /* Not used */951 );952 #endif953 954 case OBJECTS_ERROR:955 return RTEMS_INVALID_ID;956 957 case OBJECTS_LOCAL:958 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];959 *note = api->Notepads[ notepad ];960 _Thread_Enable_dispatch();961 return RTEMS_SUCCESSFUL;962 }963 964 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */965 }966 967 /*PAGE968 *969 * rtems_task_set_note970 *971 * This directive sets the specified notepad contents to the given972 * note.973 *974 * Input parameters:975 * id - thread id976 * notepad - notepad number977 * note - note value978 *979 * Output parameters:980 * RTEMS_SUCCESSFUL - if successful981 * error code - if unsuccessful982 */983 984 rtems_status_code rtems_task_set_note(985 Objects_Id id,986 unsigned32 notepad,987 unsigned32 note988 )989 {990 register Thread_Control *the_thread;991 Objects_Locations location;992 RTEMS_API_Control *api;993 994 /*995 * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would996 * be checking an unsigned number for being negative.997 */998 999 if ( notepad > RTEMS_NOTEPAD_LAST )1000 return RTEMS_INVALID_NUMBER;1001 1002 /*1003 * Optimize the most likely case to avoid the Thread_Dispatch.1004 */1005 1006 if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||1007 _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {1008 api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];1009 api->Notepads[ notepad ] = note;1010 return RTEMS_SUCCESSFUL;1011 }1012 1013 the_thread = _Thread_Get( id, &location );1014 switch ( location ) {1015 1016 case OBJECTS_REMOTE:1017 #if defined(RTEMS_MULTIPROCESSING)1018 return _RTEMS_tasks_MP_Send_request_packet(1019 RTEMS_TASKS_MP_SET_NOTE_REQUEST,1020 id,1021 0, /* Not used */1022 notepad,1023 note1024 );1025 #endif1026 1027 case OBJECTS_ERROR:1028 return RTEMS_INVALID_ID;1029 1030 case OBJECTS_LOCAL:1031 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];1032 api->Notepads[ notepad ] = note;1033 _Thread_Enable_dispatch();1034 return RTEMS_SUCCESSFUL;1035 }1036 1037 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */1038 }1039 1040 /*PAGE1041 *1042 * rtems_task_wake_after1043 *1044 * This directive suspends the requesting thread for the given amount1045 * of ticks.1046 *1047 * Input parameters:1048 * ticks - number of ticks to wait1049 *1050 * Output parameters:1051 * RTEMS_SUCCESSFUL - always successful1052 */1053 1054 rtems_status_code rtems_task_wake_after(1055 rtems_interval ticks1056 )1057 {1058 _Thread_Disable_dispatch();1059 if ( ticks == 0 ) {1060 _Thread_Yield_processor();1061 } else {1062 _Thread_Set_state( _Thread_Executing, STATES_DELAYING );1063 _Watchdog_Initialize(1064 &_Thread_Executing->Timer,1065 _Thread_Delay_ended,1066 _Thread_Executing->Object.id,1067 NULL1068 );1069 _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );1070 }1071 _Thread_Enable_dispatch();1072 return RTEMS_SUCCESSFUL;1073 }1074 1075 /*PAGE1076 *1077 * rtems_task_wake_when1078 *1079 * This directive blocks the requesting thread until the given date and1080 * time is reached.1081 *1082 * Input parameters:1083 * time_buffer - pointer to the time and date structure1084 *1085 * Output parameters:1086 * RTEMS_SUCCESSFUL - if successful1087 * error code - if unsuccessful1088 */1089 1090 rtems_status_code rtems_task_wake_when(1091 rtems_time_of_day *time_buffer1092 )1093 {1094 Watchdog_Interval seconds;1095 1096 if ( !_TOD_Is_set )1097 return RTEMS_NOT_DEFINED;1098 1099 time_buffer->ticks = 0;1100 1101 if ( !_TOD_Validate( time_buffer ) )1102 return RTEMS_INVALID_CLOCK;1103 1104 seconds = _TOD_To_seconds( time_buffer );1105 1106 if ( seconds <= _TOD_Seconds_since_epoch )1107 return RTEMS_INVALID_CLOCK;1108 1109 _Thread_Disable_dispatch();1110 _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );1111 _Watchdog_Initialize(1112 &_Thread_Executing->Timer,1113 _Thread_Delay_ended,1114 _Thread_Executing->Object.id,1115 NULL1116 );1117 _Watchdog_Insert_seconds(1118 &_Thread_Executing->Timer,1119 seconds - _TOD_Seconds_since_epoch1120 );1121 _Thread_Enable_dispatch();1122 return RTEMS_SUCCESSFUL;1123 }1124 1125 /*PAGE1126 *1127 * _RTEMS_tasks_Initialize_user_tasks1128 *1129 * This routine creates and starts all configured user1130 * initialzation threads.1131 *1132 * Input parameters: NONE1133 *1134 * Output parameters: NONE1135 */1136 1137 void _RTEMS_tasks_Initialize_user_tasks( void )1138 {1139 unsigned32 index;1140 unsigned32 maximum;1141 rtems_id id;1142 rtems_status_code return_value;1143 rtems_initialization_tasks_table *user_tasks;1144 1145 /*1146 * NOTE: This is slightly different from the Ada implementation.1147 */1148 1149 user_tasks = _RTEMS_tasks_User_initialization_tasks;1150 maximum = _RTEMS_tasks_Number_of_initialization_tasks;1151 1152 if ( !user_tasks || maximum == 0 )1153 return;1154 1155 for ( index=0 ; index < maximum ; index++ ) {1156 return_value = rtems_task_create(1157 user_tasks[ index ].name,1158 user_tasks[ index ].initial_priority,1159 user_tasks[ index ].stack_size,1160 user_tasks[ index ].mode_set,1161 user_tasks[ index ].attribute_set,1162 &id1163 );1164 1165 if ( !rtems_is_status_successful( return_value ) )1166 _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value );1167 1168 return_value = rtems_task_start(1169 id,1170 user_tasks[ index ].entry_point,1171 user_tasks[ index ].argument1172 );1173 1174 if ( !rtems_is_status_successful( return_value ) )1175 _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value );1176 }1177 }1178 -
cpukit/rtems/src/tasks.c
r05df0a8 rc4d69e2 216 216 } 217 217 218 /*PAGE219 *220 * rtems_task_create221 *222 * This directive creates a thread by allocating and initializing a223 * thread control block and a stack. The newly created thread is224 * placed in the dormant state.225 *226 * Input parameters:227 * name - user defined thread name228 * initial_priority - thread priority229 * stack_size - stack size in bytes230 * initial_modes - initial thread mode231 * attribute_set - thread attributes232 * id - pointer to thread id233 *234 * Output parameters:235 * id - thread id236 * RTEMS_SUCCESSFUL - if successful237 * error code - if unsuccessful238 */239 240 rtems_status_code rtems_task_create(241 rtems_name name,242 rtems_task_priority initial_priority,243 unsigned32 stack_size,244 rtems_mode initial_modes,245 rtems_attribute attribute_set,246 Objects_Id *id247 )248 {249 register Thread_Control *the_thread;250 boolean is_fp;251 #if defined(RTEMS_MULTIPROCESSING)252 Objects_MP_Control *the_global_object = NULL;253 boolean is_global;254 #endif255 boolean status;256 rtems_attribute the_attribute_set;257 Priority_Control core_priority;258 RTEMS_API_Control *api;259 ASR_Information *asr;260 261 262 if ( !rtems_is_name_valid( name ) )263 return RTEMS_INVALID_NAME;264 265 /*266 * Core Thread Initialize insures we get the minimum amount of267 * stack space.268 */269 270 #if 0271 if ( !_Stack_Is_enough( stack_size ) )272 return RTEMS_INVALID_SIZE;273 #endif274 275 /*276 * Fix the attribute set to match the attributes which277 * this processor (1) requires and (2) is able to support.278 * First add in the required flags for attribute_set279 * Typically this might include FP if the platform280 * or application required all tasks to be fp aware.281 * Then turn off the requested bits which are not supported.282 */283 284 the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );285 the_attribute_set =286 _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );287 288 if ( _Attributes_Is_floating_point( the_attribute_set ) )289 is_fp = TRUE;290 else291 is_fp = FALSE;292 293 /*294 * Validate the RTEMS API priority and convert it to the core priority range.295 */296 297 if ( !_Attributes_Is_system_task( the_attribute_set ) ) {298 if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) )299 return RTEMS_INVALID_PRIORITY;300 }301 302 core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority );303 304 #if defined(RTEMS_MULTIPROCESSING)305 if ( _Attributes_Is_global( the_attribute_set ) ) {306 307 is_global = TRUE;308 309 if ( !_System_state_Is_multiprocessing )310 return RTEMS_MP_NOT_CONFIGURED;311 312 } else313 is_global = FALSE;314 #endif315 316 /*317 * Make sure system is MP if this task is global318 */319 320 /*321 * Disable dispatch for protection322 */323 324 _Thread_Disable_dispatch();325 326 /*327 * Allocate the thread control block and -- if the task is global --328 * allocate a global object control block.329 *330 * NOTE: This routine does not use the combined allocate and open331 * global object routine because this results in a lack of332 * control over when memory is allocated and can be freed in333 * the event of an error.334 */335 336 the_thread = _RTEMS_tasks_Allocate();337 338 if ( !the_thread ) {339 _Thread_Enable_dispatch();340 return RTEMS_TOO_MANY;341 }342 343 #if defined(RTEMS_MULTIPROCESSING)344 if ( is_global ) {345 the_global_object = _Objects_MP_Allocate_global_object();346 347 if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {348 _RTEMS_tasks_Free( the_thread );349 _Thread_Enable_dispatch();350 return RTEMS_TOO_MANY;351 }352 }353 #endif354 355 /*356 * Initialize the core thread for this task.357 */358 359 status = _Thread_Initialize(360 &_RTEMS_tasks_Information,361 the_thread,362 NULL,363 stack_size,364 is_fp,365 core_priority,366 _Modes_Is_preempt(initial_modes) ? TRUE : FALSE,367 _Modes_Is_timeslice(initial_modes) ?368 THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :369 THREAD_CPU_BUDGET_ALGORITHM_NONE,370 NULL, /* no budget algorithm callout */371 _Modes_Get_interrupt_level(initial_modes),372 &name373 );374 375 if ( !status ) {376 #if defined(RTEMS_MULTIPROCESSING)377 if ( is_global )378 _Objects_MP_Free_global_object( the_global_object );379 #endif380 _RTEMS_tasks_Free( the_thread );381 _Thread_Enable_dispatch();382 return RTEMS_UNSATISFIED;383 }384 385 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];386 asr = &api->Signal;387 388 asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE;389 390 *id = the_thread->Object.id;391 392 #if defined(RTEMS_MULTIPROCESSING)393 if ( is_global ) {394 395 the_thread->is_global = TRUE;396 397 _Objects_MP_Open(398 &_RTEMS_tasks_Information,399 the_global_object,400 name,401 the_thread->Object.id402 );403 404 _RTEMS_tasks_MP_Send_process_packet(405 RTEMS_TASKS_MP_ANNOUNCE_CREATE,406 the_thread->Object.id,407 name408 );409 410 }411 #endif412 413 _Thread_Enable_dispatch();414 return RTEMS_SUCCESSFUL;415 }416 417 /*PAGE418 *419 * rtems_task_ident420 *421 * This directive returns the system ID associated with422 * the thread name.423 *424 * Input parameters:425 * name - user defined thread name426 * node - node(s) to be searched427 * id - pointer to thread id428 *429 * Output parameters:430 * *id - thread id431 * RTEMS_SUCCESSFUL - if successful432 * error code - if unsuccessful433 */434 435 rtems_status_code rtems_task_ident(436 rtems_name name,437 unsigned32 node,438 Objects_Id *id439 )440 {441 Objects_Name_to_id_errors status;442 443 if ( name == OBJECTS_ID_OF_SELF ) {444 *id = _Thread_Executing->Object.id;445 return RTEMS_SUCCESSFUL;446 }447 448 status = _Objects_Name_to_id( &_RTEMS_tasks_Information, &name, node, id );449 450 return _Status_Object_name_errors_to_status[ status ];451 }452 453 /*PAGE454 *455 * rtems_task_start456 *457 * This directive readies the thread identified by the "id"458 * based on its current priorty, to await execution. A thread459 * can be started only from the dormant state.460 *461 * Input parameters:462 * id - thread id463 * entry_point - start execution address of thread464 * argument - thread argument465 *466 * Output parameters:467 * RTEMS_SUCCESSFUL - if successful468 * error code - if unsuccessful469 */470 471 rtems_status_code rtems_task_start(472 rtems_id id,473 rtems_task_entry entry_point,474 unsigned32 argument475 )476 {477 register Thread_Control *the_thread;478 Objects_Locations location;479 480 if ( entry_point == NULL )481 return RTEMS_INVALID_ADDRESS;482 483 the_thread = _Thread_Get( id, &location );484 switch ( location ) {485 486 case OBJECTS_REMOTE:487 #if defined(RTEMS_MULTIPROCESSING)488 _Thread_Dispatch();489 return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;490 #endif491 492 case OBJECTS_ERROR:493 return RTEMS_INVALID_ID;494 495 case OBJECTS_LOCAL:496 if ( _Thread_Start(497 the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) {498 _Thread_Enable_dispatch();499 return RTEMS_SUCCESSFUL;500 }501 _Thread_Enable_dispatch();502 return RTEMS_INCORRECT_STATE;503 }504 505 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */506 }507 508 /*PAGE509 *510 * rtems_task_restart511 *512 * This directive readies the specified thread. It restores513 * the thread environment to the original values established514 * at thread creation and start time. A thread can be restarted515 * from any state except the dormant state.516 *517 * Input parameters:518 * id - thread id519 * argument - thread argument520 *521 * Output parameters:522 * RTEMS_SUCCESSFUL - if successful523 * error code - if unsuccessful524 */525 526 rtems_status_code rtems_task_restart(527 Objects_Id id,528 unsigned32 argument529 )530 {531 register Thread_Control *the_thread;532 Objects_Locations location;533 534 the_thread = _Thread_Get( id, &location );535 switch ( location ) {536 537 case OBJECTS_REMOTE:538 #if defined(RTEMS_MULTIPROCESSING)539 _Thread_Dispatch();540 return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;541 #endif542 543 case OBJECTS_ERROR:544 return RTEMS_INVALID_ID;545 546 case OBJECTS_LOCAL:547 if ( _Thread_Restart( the_thread, NULL, argument ) ) {548 _Thread_Enable_dispatch();549 return RTEMS_SUCCESSFUL;550 }551 _Thread_Enable_dispatch();552 return RTEMS_INCORRECT_STATE;553 }554 555 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */556 }557 558 /*PAGE559 *560 * rtems_task_delete561 *562 * This directive allows a thread to delete itself or the thread563 * identified in the id field. The executive halts execution564 * of the thread and frees the thread control block.565 *566 * Input parameters:567 * id - thread id568 *569 * Output parameters:570 * nothing - if id is the requesting thread (always succeeds)571 * RTEMS_SUCCESSFUL - if successful and id is572 * not the requesting thread573 * error code - if unsuccessful574 */575 576 rtems_status_code rtems_task_delete(577 Objects_Id id578 )579 {580 register Thread_Control *the_thread;581 Objects_Locations location;582 Objects_Information *the_information;583 584 the_thread = _Thread_Get( id, &location );585 switch ( location ) {586 587 case OBJECTS_REMOTE:588 #if defined(RTEMS_MULTIPROCESSING)589 _Thread_Dispatch();590 return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;591 #endif592 593 case OBJECTS_ERROR:594 return RTEMS_INVALID_ID;595 596 case OBJECTS_LOCAL:597 the_information = _Objects_Get_information( the_thread->Object.id );598 599 if ( !the_information ) {600 _Thread_Enable_dispatch();601 return RTEMS_INVALID_ID;602 /* This should never happen if _Thread_Get() works right */603 }604 605 _Thread_Close( the_information, the_thread );606 607 _RTEMS_tasks_Free( the_thread );608 609 #if defined(RTEMS_MULTIPROCESSING)610 if ( the_thread->is_global ) {611 612 _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id );613 614 _RTEMS_tasks_MP_Send_process_packet(615 RTEMS_TASKS_MP_ANNOUNCE_DELETE,616 the_thread->Object.id,617 0 /* Not used */618 );619 }620 #endif621 622 _Thread_Enable_dispatch();623 return RTEMS_SUCCESSFUL;624 }625 626 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */627 }628 629 /*PAGE630 *631 * rtems_task_suspend632 *633 * This directive will place the specified thread in the "suspended"634 * state. Note that the suspended state can be in addition to635 * other waiting states.636 *637 * Input parameters:638 * id - thread id639 *640 * Output parameters:641 * RTEMS_SUCCESSFUL - if successful642 * error code - if unsuccessful643 */644 645 rtems_status_code rtems_task_suspend(646 Objects_Id id647 )648 {649 register Thread_Control *the_thread;650 Objects_Locations location;651 652 the_thread = _Thread_Get( id, &location );653 switch ( location ) {654 655 case OBJECTS_REMOTE:656 #if defined(RTEMS_MULTIPROCESSING)657 return _RTEMS_tasks_MP_Send_request_packet(658 RTEMS_TASKS_MP_SUSPEND_REQUEST,659 id,660 0, /* Not used */661 0, /* Not used */662 0 /* Not used */663 );664 #endif665 666 case OBJECTS_ERROR:667 return RTEMS_INVALID_ID;668 669 case OBJECTS_LOCAL:670 if ( !_States_Is_suspended( the_thread->current_state ) ) {671 _Thread_Set_state( the_thread, STATES_SUSPENDED );672 _Thread_Enable_dispatch();673 return RTEMS_SUCCESSFUL;674 }675 _Thread_Enable_dispatch();676 return RTEMS_ALREADY_SUSPENDED;677 }678 679 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */680 }681 682 /*PAGE683 *684 * rtems_task_resume685 *686 * This directive will remove the specified thread687 * from the suspended state.688 *689 * Input parameters:690 * id - thread id691 *692 * Output parameters:693 * RTEMS_SUCCESSFUL - if successful694 * error code - if unsuccessful695 */696 697 rtems_status_code rtems_task_resume(698 Objects_Id id699 )700 {701 register Thread_Control *the_thread;702 Objects_Locations location;703 704 the_thread = _Thread_Get( id, &location );705 switch ( location ) {706 707 case OBJECTS_REMOTE:708 #if defined(RTEMS_MULTIPROCESSING)709 return _RTEMS_tasks_MP_Send_request_packet(710 RTEMS_TASKS_MP_RESUME_REQUEST,711 id,712 0, /* Not used */713 0, /* Not used */714 0 /* Not used */715 );716 #endif717 718 case OBJECTS_ERROR:719 return RTEMS_INVALID_ID;720 721 case OBJECTS_LOCAL:722 if ( _States_Is_suspended( the_thread->current_state ) ) {723 _Thread_Resume( the_thread );724 _Thread_Enable_dispatch();725 return RTEMS_SUCCESSFUL;726 }727 _Thread_Enable_dispatch();728 return RTEMS_INCORRECT_STATE;729 }730 731 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */732 }733 734 /*PAGE735 *736 * rtems_task_set_priority737 *738 * This directive changes the priority of the specified thread.739 * The specified thread can be any thread in the system including740 * the requesting thread.741 *742 * Input parameters:743 * id - thread id (0 indicates requesting thread)744 * new_priority - thread priority (0 indicates current priority)745 * old_priority - pointer to previous priority746 *747 * Output parameters:748 * old_priority - previous priority749 * RTEMS_SUCCESSFUL - if successful750 * error code - if unsuccessful751 */752 753 rtems_status_code rtems_task_set_priority(754 Objects_Id id,755 rtems_task_priority new_priority,756 rtems_task_priority *old_priority757 )758 {759 register Thread_Control *the_thread;760 Objects_Locations location;761 762 if ( new_priority != RTEMS_CURRENT_PRIORITY &&763 !_RTEMS_tasks_Priority_is_valid( new_priority ) )764 return RTEMS_INVALID_PRIORITY;765 766 the_thread = _Thread_Get( id, &location );767 switch ( location ) {768 769 case OBJECTS_REMOTE:770 #if defined(RTEMS_MULTIPROCESSING)771 _Thread_Executing->Wait.return_argument = old_priority;772 return _RTEMS_tasks_MP_Send_request_packet(773 RTEMS_TASKS_MP_SET_PRIORITY_REQUEST,774 id,775 new_priority,776 0, /* Not used */777 0 /* Not used */778 );779 #endif780 781 case OBJECTS_ERROR:782 return RTEMS_INVALID_ID;783 784 case OBJECTS_LOCAL:785 *old_priority = the_thread->current_priority;786 if ( new_priority != RTEMS_CURRENT_PRIORITY ) {787 the_thread->real_priority = new_priority;788 if ( the_thread->resource_count == 0 ||789 the_thread->current_priority > new_priority )790 _Thread_Change_priority( the_thread, new_priority, FALSE );791 }792 _Thread_Enable_dispatch();793 return RTEMS_SUCCESSFUL;794 }795 796 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */797 }798 799 /*PAGE800 *801 * rtems_task_mode802 *803 * This directive enables and disables several modes of804 * execution for the requesting thread.805 *806 * Input parameters:807 * mode_set - new mode808 * mask - mask809 * previous_mode_set - address of previous mode set810 *811 * Output:812 * *previous_mode_set - previous mode set813 * always return RTEMS_SUCCESSFUL;814 */815 816 rtems_status_code rtems_task_mode(817 rtems_mode mode_set,818 rtems_mode mask,819 rtems_mode *previous_mode_set820 )821 {822 Thread_Control *executing;823 RTEMS_API_Control *api;824 ASR_Information *asr;825 boolean is_asr_enabled = FALSE;826 boolean needs_asr_dispatching = FALSE;827 rtems_mode old_mode;828 829 executing = _Thread_Executing;830 api = executing->API_Extensions[ THREAD_API_RTEMS ];831 asr = &api->Signal;832 833 old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT;834 835 if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE )836 old_mode |= RTEMS_NO_TIMESLICE;837 else838 old_mode |= RTEMS_TIMESLICE;839 840 old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR;841 old_mode |= _ISR_Get_level();842 843 *previous_mode_set = old_mode;844 845 /*846 * These are generic thread scheduling characteristics.847 */848 849 if ( mask & RTEMS_PREEMPT_MASK )850 executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE;851 852 if ( mask & RTEMS_TIMESLICE_MASK ) {853 if ( _Modes_Is_timeslice(mode_set) )854 executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE;855 else856 executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;857 }858 859 /*860 * Set the new interrupt level861 */862 863 if ( mask & RTEMS_INTERRUPT_MASK )864 _Modes_Set_interrupt_level( mode_set );865 866 /*867 * This is specific to the RTEMS API868 */869 870 is_asr_enabled = FALSE;871 needs_asr_dispatching = FALSE;872 873 if ( mask & RTEMS_ASR_MASK ) {874 is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE;875 if ( is_asr_enabled != asr->is_enabled ) {876 asr->is_enabled = is_asr_enabled;877 _ASR_Swap_signals( asr );878 if ( _ASR_Are_signals_pending( asr ) ) {879 needs_asr_dispatching = TRUE;880 executing->do_post_task_switch_extension = TRUE;881 }882 }883 }884 885 if ( _Thread_Evaluate_mode() || needs_asr_dispatching )886 _Thread_Dispatch();887 888 return RTEMS_SUCCESSFUL;889 }890 891 /*PAGE892 *893 * rtems_task_get_note894 *895 * This directive obtains the note from the specified notepad896 * of the specified thread.897 *898 * Input parameters:899 * id - thread id900 * notepad - notepad number901 * note - pointer to note902 *903 * Output parameters:904 * note - filled in if successful905 * RTEMS_SUCCESSFUL - if successful906 * error code - if unsuccessful907 */908 909 rtems_status_code rtems_task_get_note(910 Objects_Id id,911 unsigned32 notepad,912 unsigned32 *note913 )914 {915 register Thread_Control *the_thread;916 Objects_Locations location;917 RTEMS_API_Control *api;918 919 /*920 * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would921 * be checking an unsigned number for being negative.922 */923 924 if ( notepad > RTEMS_NOTEPAD_LAST )925 return RTEMS_INVALID_NUMBER;926 927 /*928 * Optimize the most likely case to avoid the Thread_Dispatch.929 */930 931 if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||932 _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {933 api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];934 *note = api->Notepads[ notepad ];935 return RTEMS_SUCCESSFUL;936 }937 938 the_thread = _Thread_Get( id, &location );939 switch ( location ) {940 941 case OBJECTS_REMOTE:942 #if defined(RTEMS_MULTIPROCESSING)943 _Thread_Executing->Wait.return_argument = note;944 945 return _RTEMS_tasks_MP_Send_request_packet(946 RTEMS_TASKS_MP_GET_NOTE_REQUEST,947 id,948 0, /* Not used */949 notepad,950 0 /* Not used */951 );952 #endif953 954 case OBJECTS_ERROR:955 return RTEMS_INVALID_ID;956 957 case OBJECTS_LOCAL:958 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];959 *note = api->Notepads[ notepad ];960 _Thread_Enable_dispatch();961 return RTEMS_SUCCESSFUL;962 }963 964 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */965 }966 967 /*PAGE968 *969 * rtems_task_set_note970 *971 * This directive sets the specified notepad contents to the given972 * note.973 *974 * Input parameters:975 * id - thread id976 * notepad - notepad number977 * note - note value978 *979 * Output parameters:980 * RTEMS_SUCCESSFUL - if successful981 * error code - if unsuccessful982 */983 984 rtems_status_code rtems_task_set_note(985 Objects_Id id,986 unsigned32 notepad,987 unsigned32 note988 )989 {990 register Thread_Control *the_thread;991 Objects_Locations location;992 RTEMS_API_Control *api;993 994 /*995 * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would996 * be checking an unsigned number for being negative.997 */998 999 if ( notepad > RTEMS_NOTEPAD_LAST )1000 return RTEMS_INVALID_NUMBER;1001 1002 /*1003 * Optimize the most likely case to avoid the Thread_Dispatch.1004 */1005 1006 if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||1007 _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {1008 api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];1009 api->Notepads[ notepad ] = note;1010 return RTEMS_SUCCESSFUL;1011 }1012 1013 the_thread = _Thread_Get( id, &location );1014 switch ( location ) {1015 1016 case OBJECTS_REMOTE:1017 #if defined(RTEMS_MULTIPROCESSING)1018 return _RTEMS_tasks_MP_Send_request_packet(1019 RTEMS_TASKS_MP_SET_NOTE_REQUEST,1020 id,1021 0, /* Not used */1022 notepad,1023 note1024 );1025 #endif1026 1027 case OBJECTS_ERROR:1028 return RTEMS_INVALID_ID;1029 1030 case OBJECTS_LOCAL:1031 api = the_thread->API_Extensions[ THREAD_API_RTEMS ];1032 api->Notepads[ notepad ] = note;1033 _Thread_Enable_dispatch();1034 return RTEMS_SUCCESSFUL;1035 }1036 1037 return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */1038 }1039 1040 /*PAGE1041 *1042 * rtems_task_wake_after1043 *1044 * This directive suspends the requesting thread for the given amount1045 * of ticks.1046 *1047 * Input parameters:1048 * ticks - number of ticks to wait1049 *1050 * Output parameters:1051 * RTEMS_SUCCESSFUL - always successful1052 */1053 1054 rtems_status_code rtems_task_wake_after(1055 rtems_interval ticks1056 )1057 {1058 _Thread_Disable_dispatch();1059 if ( ticks == 0 ) {1060 _Thread_Yield_processor();1061 } else {1062 _Thread_Set_state( _Thread_Executing, STATES_DELAYING );1063 _Watchdog_Initialize(1064 &_Thread_Executing->Timer,1065 _Thread_Delay_ended,1066 _Thread_Executing->Object.id,1067 NULL1068 );1069 _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );1070 }1071 _Thread_Enable_dispatch();1072 return RTEMS_SUCCESSFUL;1073 }1074 1075 /*PAGE1076 *1077 * rtems_task_wake_when1078 *1079 * This directive blocks the requesting thread until the given date and1080 * time is reached.1081 *1082 * Input parameters:1083 * time_buffer - pointer to the time and date structure1084 *1085 * Output parameters:1086 * RTEMS_SUCCESSFUL - if successful1087 * error code - if unsuccessful1088 */1089 1090 rtems_status_code rtems_task_wake_when(1091 rtems_time_of_day *time_buffer1092 )1093 {1094 Watchdog_Interval seconds;1095 1096 if ( !_TOD_Is_set )1097 return RTEMS_NOT_DEFINED;1098 1099 time_buffer->ticks = 0;1100 1101 if ( !_TOD_Validate( time_buffer ) )1102 return RTEMS_INVALID_CLOCK;1103 1104 seconds = _TOD_To_seconds( time_buffer );1105 1106 if ( seconds <= _TOD_Seconds_since_epoch )1107 return RTEMS_INVALID_CLOCK;1108 1109 _Thread_Disable_dispatch();1110 _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );1111 _Watchdog_Initialize(1112 &_Thread_Executing->Timer,1113 _Thread_Delay_ended,1114 _Thread_Executing->Object.id,1115 NULL1116 );1117 _Watchdog_Insert_seconds(1118 &_Thread_Executing->Timer,1119 seconds - _TOD_Seconds_since_epoch1120 );1121 _Thread_Enable_dispatch();1122 return RTEMS_SUCCESSFUL;1123 }1124 1125 /*PAGE1126 *1127 * _RTEMS_tasks_Initialize_user_tasks1128 *1129 * This routine creates and starts all configured user1130 * initialzation threads.1131 *1132 * Input parameters: NONE1133 *1134 * Output parameters: NONE1135 */1136 1137 void _RTEMS_tasks_Initialize_user_tasks( void )1138 {1139 unsigned32 index;1140 unsigned32 maximum;1141 rtems_id id;1142 rtems_status_code return_value;1143 rtems_initialization_tasks_table *user_tasks;1144 1145 /*1146 * NOTE: This is slightly different from the Ada implementation.1147 */1148 1149 user_tasks = _RTEMS_tasks_User_initialization_tasks;1150 maximum = _RTEMS_tasks_Number_of_initialization_tasks;1151 1152 if ( !user_tasks || maximum == 0 )1153 return;1154 1155 for ( index=0 ; index < maximum ; index++ ) {1156 return_value = rtems_task_create(1157 user_tasks[ index ].name,1158 user_tasks[ index ].initial_priority,1159 user_tasks[ index ].stack_size,1160 user_tasks[ index ].mode_set,1161 user_tasks[ index ].attribute_set,1162 &id1163 );1164 1165 if ( !rtems_is_status_successful( return_value ) )1166 _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value );1167 1168 return_value = rtems_task_start(1169 id,1170 user_tasks[ index ].entry_point,1171 user_tasks[ index ].argument1172 );1173 1174 if ( !rtems_is_status_successful( return_value ) )1175 _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value );1176 }1177 }1178
Note: See TracChangeset
for help on using the changeset viewer.