Changeset da41ecbc in rtems
- Timestamp:
- 04/15/99 18:58:02 (24 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 2df1974
- Parents:
- 93994fdb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/posix/src/psignal.c
r93994fdb rda41ecbc 37 37 sigset_t _POSIX_signals_Pending; 38 38 39 void _POSIX_signals_Ab ormal_termination_handler( int signo )39 void _POSIX_signals_Abnormal_termination_handler( int signo ) 40 40 { 41 41 exit( 1 ); 42 42 } 43 44 #define _POSIX_signals_Stop_handler NULL45 #define _POSIX_signals_Continue_handler NULL46 47 #define SIGACTION_TERMINATE \48 { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} }49 #define SIGACTION_IGNORE \50 { 0, SIGNAL_ALL_MASK, {SIG_IGN} }51 #define SIGACTION_STOP \52 { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }53 #define SIGACTION_CONTINUE \54 { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }55 43 56 44 #define SIG_ARRAY_MAX (SIGRTMAX + 1) … … 924 912 } 925 913 926 /*PAGE927 *928 * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68929 *930 * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.931 */932 933 #define _POSIX_signals_Is_interested( _api, _mask ) \934 ( ~(_api)->signals_blocked & (_mask) )935 936 int killinfo(937 pid_t pid,938 int sig,939 const union sigval *value940 )941 {942 sigset_t mask;943 POSIX_API_Control *api;944 unsigned32 the_class;945 unsigned32 index;946 unsigned32 maximum;947 Objects_Information *the_info;948 Objects_Control **object_table;949 Thread_Control *the_thread;950 Thread_Control *interested_thread;951 Priority_Control interested_priority;952 Chain_Control *the_chain;953 Chain_Node *the_node;954 siginfo_t siginfo_struct;955 siginfo_t *siginfo;956 POSIX_signals_Siginfo_node *psiginfo;957 958 959 960 /*961 * Only supported for the "calling process" (i.e. this node).962 */963 964 if( pid != getpid() )965 set_errno_and_return_minus_one( ESRCH );966 967 /*968 * Validate the signal passed if not 0.969 */970 971 if ( sig && !is_valid_signo(sig) )972 {973 set_errno_and_return_minus_one( EINVAL );974 }975 976 /*977 * If the signal is being ignored, then we are out of here.978 */979 980 if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )981 {982 return 0;983 }984 985 /*986 * P1003.1c/Draft 10, p. 33 says that certain signals should always987 * be directed to the executing thread such as those caused by hardware988 * faults.989 */990 991 switch ( sig ) {992 case SIGFPE:993 case SIGILL:994 case SIGSEGV:995 return pthread_kill( pthread_self(), sig );996 default:997 break;998 }999 1000 mask = signo_to_mask( sig );1001 1002 /*1003 * Build up a siginfo structure1004 */1005 1006 siginfo = &siginfo_struct;1007 siginfo->si_signo = sig;1008 siginfo->si_code = SI_USER;1009 if ( !value ) {1010 siginfo->si_value.sival_int = 0;1011 } else {1012 siginfo->si_value = *value;1013 }1014 1015 _Thread_Disable_dispatch();1016 1017 /*1018 * Is the currently executing thread interested? If so then it will1019 * get it an execute it as soon as the dispatcher executes.1020 */1021 1022 the_thread = _Thread_Executing;1023 1024 api = the_thread->API_Extensions[ THREAD_API_POSIX ];1025 if ( _POSIX_signals_Is_interested( api, mask ) ) {1026 goto process_it;1027 }1028 1029 /*1030 * Is an interested thread waiting for this signal (sigwait())?1031 */1032 1033 /* XXX violation of visibility -- need to define thread queue support */1034 1035 for( index=0 ;1036 index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;1037 index++ ) {1038 1039 the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];1040 1041 for ( the_node = the_chain->first ;1042 !_Chain_Is_tail( the_chain, the_node ) ;1043 the_node = the_node->next ) {1044 1045 the_thread = (Thread_Control *)the_node;1046 api = the_thread->API_Extensions[ THREAD_API_POSIX ];1047 1048 if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {1049 goto process_it;1050 }1051 1052 }1053 }1054 1055 /*1056 * Is any other thread interested? The highest priority interested1057 * thread is selected. In the event of a tie, then the following1058 * additional criteria is used:1059 *1060 * + ready thread over blocked1061 * + blocked on call interruptible by signal (can return EINTR)1062 * + blocked on call not interruptible by signal1063 *1064 * This looks at every thread in the system regardless of the creating API.1065 *1066 * NOTES:1067 *1068 * + rtems internal threads do not receive signals.1069 */1070 1071 interested_thread = NULL;1072 interested_priority = PRIORITY_MAXIMUM + 1;1073 1074 for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;1075 the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;1076 the_class++ ) {1077 1078 if ( the_class == OBJECTS_INTERNAL_THREADS )1079 continue;1080 1081 the_info = _Objects_Information_table[ the_class ];1082 1083 if ( !the_info ) /* manager not installed */1084 continue;1085 1086 maximum = the_info->maximum;1087 object_table = the_info->local_table;1088 1089 assert( object_table ); /* always at least 1 entry */1090 1091 for ( index = 1 ; index <= maximum ; index++ ) {1092 the_thread = (Thread_Control *) object_table[ index ];1093 1094 if ( !the_thread )1095 continue;1096 1097 /*1098 * If this thread is of lower priority than the interested thread,1099 * go on to the next thread.1100 */1101 1102 if ( the_thread->current_priority > interested_priority )1103 continue;1104 1105 /*1106 * If this thread is not interested, then go on to the next thread.1107 */1108 1109 api = the_thread->API_Extensions[ THREAD_API_POSIX ];1110 1111 if ( !api || !_POSIX_signals_Is_interested( api, mask ) )1112 continue;1113 1114 /*1115 * Now we know the thread under connsideration is interested.1116 * If the thread under consideration is of higher priority, then1117 * it becomes the interested thread.1118 */1119 1120 if ( the_thread->current_priority < interested_priority ) {1121 interested_thread = the_thread;1122 interested_priority = the_thread->current_priority;1123 continue;1124 }1125 1126 /*1127 * Now the thread and the interested thread have the same priority.1128 * If the interested thread is ready, then we don't need to send it1129 * to a blocked thread.1130 */1131 1132 if ( _States_Is_ready( interested_thread->current_state ) )1133 continue;1134 1135 /*1136 * Now the interested thread is blocked.1137 * If the thread we are considering is not, the it becomes the1138 * interested thread.1139 */1140 1141 if ( _States_Is_ready( the_thread->current_state ) ) {1142 interested_thread = the_thread;1143 interested_priority = the_thread->current_priority;1144 continue;1145 }1146 1147 /*1148 * Now we know both threads are blocked.1149 * If the interested thread is interruptible, then just use it.1150 */1151 1152 /* XXX need a new states macro */1153 if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )1154 continue;1155 1156 /*1157 * Now both threads are blocked and the interested thread is not1158 * interruptible.1159 * If the thread under consideration is interruptible by a signal,1160 * then it becomes the interested thread.1161 */1162 1163 /* XXX need a new states macro */1164 if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {1165 interested_thread = the_thread;1166 interested_priority = the_thread->current_priority;1167 }1168 }1169 }1170 1171 if ( interested_thread ) {1172 the_thread = interested_thread;1173 goto process_it;1174 }1175 1176 /*1177 * OK so no threads were interested right now. It will be left on the1178 * global pending until a thread receives it. The global set of threads1179 * can change interest in this signal in one of the following ways:1180 *1181 * + a thread is created with the signal unblocked,1182 * + pthread_sigmask() unblocks the signal,1183 * + sigprocmask() unblocks the signal, OR1184 * + sigaction() which changes the handler to SIG_IGN.1185 */1186 1187 the_thread = NULL;1188 goto post_process_signal;1189 1190 /*1191 * We found a thread which was interested, so now we mark that this1192 * thread needs to do the post context switch extension so it can1193 * evaluate the signals pending.1194 */1195 1196 process_it:1197 1198 the_thread->do_post_task_switch_extension = TRUE;1199 1200 /*1201 * Returns TRUE if the signal was synchronously given to a thread1202 * blocked waiting for the signal.1203 */1204 1205 if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {1206 _Thread_Enable_dispatch();1207 return 0;1208 }1209 1210 post_process_signal:1211 1212 /*1213 * We may have woken up a thread but we definitely need to post the1214 * signal to the process wide information set.1215 */1216 1217 _POSIX_signals_Set_process_signals( mask );1218 1219 if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {1220 1221 psiginfo = (POSIX_signals_Siginfo_node *)1222 _Chain_Get( &_POSIX_signals_Inactive_siginfo );1223 if ( !psiginfo )1224 {1225 set_errno_and_return_minus_one( EAGAIN );1226 }1227 1228 psiginfo->Info = *siginfo;1229 1230 _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );1231 }1232 1233 _Thread_Enable_dispatch();1234 return 0;1235 }1236 1237 914 /* 1238 915 * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 … … 1307 984 return POSIX_BOTTOM_REACHED(); 1308 985 } 1309 1310 /*1311 * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 791312 */1313 1314 Watchdog_Control _POSIX_signals_Alarm_timer;1315 1316 unsigned int alarm(1317 unsigned int seconds1318 )1319 {1320 unsigned int remaining = 0;1321 Watchdog_Control *the_timer;1322 1323 the_timer = &_POSIX_signals_Alarm_timer;1324 1325 switch ( _Watchdog_Remove( the_timer ) ) {1326 case WATCHDOG_INACTIVE:1327 case WATCHDOG_BEING_INSERTED:1328 break;1329 1330 case WATCHDOG_ACTIVE:1331 case WATCHDOG_REMOVE_IT:1332 remaining = the_timer->initial -1333 (the_timer->stop_time - the_timer->start_time);1334 break;1335 }1336 1337 _Watchdog_Insert_seconds( the_timer, seconds );1338 1339 return remaining;1340 }1341 1342 /*1343 * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 811344 */1345 1346 int pause( void )1347 {1348 sigset_t all_signals;1349 int status;1350 1351 (void) sigfillset( &all_signals );1352 1353 status = sigtimedwait( &all_signals, NULL, NULL );1354 1355 return status;1356 } -
cpukit/posix/src/psignal.c
r93994fdb rda41ecbc 37 37 sigset_t _POSIX_signals_Pending; 38 38 39 void _POSIX_signals_Ab ormal_termination_handler( int signo )39 void _POSIX_signals_Abnormal_termination_handler( int signo ) 40 40 { 41 41 exit( 1 ); 42 42 } 43 44 #define _POSIX_signals_Stop_handler NULL45 #define _POSIX_signals_Continue_handler NULL46 47 #define SIGACTION_TERMINATE \48 { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} }49 #define SIGACTION_IGNORE \50 { 0, SIGNAL_ALL_MASK, {SIG_IGN} }51 #define SIGACTION_STOP \52 { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }53 #define SIGACTION_CONTINUE \54 { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }55 43 56 44 #define SIG_ARRAY_MAX (SIGRTMAX + 1) … … 924 912 } 925 913 926 /*PAGE927 *928 * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68929 *930 * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.931 */932 933 #define _POSIX_signals_Is_interested( _api, _mask ) \934 ( ~(_api)->signals_blocked & (_mask) )935 936 int killinfo(937 pid_t pid,938 int sig,939 const union sigval *value940 )941 {942 sigset_t mask;943 POSIX_API_Control *api;944 unsigned32 the_class;945 unsigned32 index;946 unsigned32 maximum;947 Objects_Information *the_info;948 Objects_Control **object_table;949 Thread_Control *the_thread;950 Thread_Control *interested_thread;951 Priority_Control interested_priority;952 Chain_Control *the_chain;953 Chain_Node *the_node;954 siginfo_t siginfo_struct;955 siginfo_t *siginfo;956 POSIX_signals_Siginfo_node *psiginfo;957 958 959 960 /*961 * Only supported for the "calling process" (i.e. this node).962 */963 964 if( pid != getpid() )965 set_errno_and_return_minus_one( ESRCH );966 967 /*968 * Validate the signal passed if not 0.969 */970 971 if ( sig && !is_valid_signo(sig) )972 {973 set_errno_and_return_minus_one( EINVAL );974 }975 976 /*977 * If the signal is being ignored, then we are out of here.978 */979 980 if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )981 {982 return 0;983 }984 985 /*986 * P1003.1c/Draft 10, p. 33 says that certain signals should always987 * be directed to the executing thread such as those caused by hardware988 * faults.989 */990 991 switch ( sig ) {992 case SIGFPE:993 case SIGILL:994 case SIGSEGV:995 return pthread_kill( pthread_self(), sig );996 default:997 break;998 }999 1000 mask = signo_to_mask( sig );1001 1002 /*1003 * Build up a siginfo structure1004 */1005 1006 siginfo = &siginfo_struct;1007 siginfo->si_signo = sig;1008 siginfo->si_code = SI_USER;1009 if ( !value ) {1010 siginfo->si_value.sival_int = 0;1011 } else {1012 siginfo->si_value = *value;1013 }1014 1015 _Thread_Disable_dispatch();1016 1017 /*1018 * Is the currently executing thread interested? If so then it will1019 * get it an execute it as soon as the dispatcher executes.1020 */1021 1022 the_thread = _Thread_Executing;1023 1024 api = the_thread->API_Extensions[ THREAD_API_POSIX ];1025 if ( _POSIX_signals_Is_interested( api, mask ) ) {1026 goto process_it;1027 }1028 1029 /*1030 * Is an interested thread waiting for this signal (sigwait())?1031 */1032 1033 /* XXX violation of visibility -- need to define thread queue support */1034 1035 for( index=0 ;1036 index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;1037 index++ ) {1038 1039 the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];1040 1041 for ( the_node = the_chain->first ;1042 !_Chain_Is_tail( the_chain, the_node ) ;1043 the_node = the_node->next ) {1044 1045 the_thread = (Thread_Control *)the_node;1046 api = the_thread->API_Extensions[ THREAD_API_POSIX ];1047 1048 if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {1049 goto process_it;1050 }1051 1052 }1053 }1054 1055 /*1056 * Is any other thread interested? The highest priority interested1057 * thread is selected. In the event of a tie, then the following1058 * additional criteria is used:1059 *1060 * + ready thread over blocked1061 * + blocked on call interruptible by signal (can return EINTR)1062 * + blocked on call not interruptible by signal1063 *1064 * This looks at every thread in the system regardless of the creating API.1065 *1066 * NOTES:1067 *1068 * + rtems internal threads do not receive signals.1069 */1070 1071 interested_thread = NULL;1072 interested_priority = PRIORITY_MAXIMUM + 1;1073 1074 for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;1075 the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;1076 the_class++ ) {1077 1078 if ( the_class == OBJECTS_INTERNAL_THREADS )1079 continue;1080 1081 the_info = _Objects_Information_table[ the_class ];1082 1083 if ( !the_info ) /* manager not installed */1084 continue;1085 1086 maximum = the_info->maximum;1087 object_table = the_info->local_table;1088 1089 assert( object_table ); /* always at least 1 entry */1090 1091 for ( index = 1 ; index <= maximum ; index++ ) {1092 the_thread = (Thread_Control *) object_table[ index ];1093 1094 if ( !the_thread )1095 continue;1096 1097 /*1098 * If this thread is of lower priority than the interested thread,1099 * go on to the next thread.1100 */1101 1102 if ( the_thread->current_priority > interested_priority )1103 continue;1104 1105 /*1106 * If this thread is not interested, then go on to the next thread.1107 */1108 1109 api = the_thread->API_Extensions[ THREAD_API_POSIX ];1110 1111 if ( !api || !_POSIX_signals_Is_interested( api, mask ) )1112 continue;1113 1114 /*1115 * Now we know the thread under connsideration is interested.1116 * If the thread under consideration is of higher priority, then1117 * it becomes the interested thread.1118 */1119 1120 if ( the_thread->current_priority < interested_priority ) {1121 interested_thread = the_thread;1122 interested_priority = the_thread->current_priority;1123 continue;1124 }1125 1126 /*1127 * Now the thread and the interested thread have the same priority.1128 * If the interested thread is ready, then we don't need to send it1129 * to a blocked thread.1130 */1131 1132 if ( _States_Is_ready( interested_thread->current_state ) )1133 continue;1134 1135 /*1136 * Now the interested thread is blocked.1137 * If the thread we are considering is not, the it becomes the1138 * interested thread.1139 */1140 1141 if ( _States_Is_ready( the_thread->current_state ) ) {1142 interested_thread = the_thread;1143 interested_priority = the_thread->current_priority;1144 continue;1145 }1146 1147 /*1148 * Now we know both threads are blocked.1149 * If the interested thread is interruptible, then just use it.1150 */1151 1152 /* XXX need a new states macro */1153 if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )1154 continue;1155 1156 /*1157 * Now both threads are blocked and the interested thread is not1158 * interruptible.1159 * If the thread under consideration is interruptible by a signal,1160 * then it becomes the interested thread.1161 */1162 1163 /* XXX need a new states macro */1164 if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {1165 interested_thread = the_thread;1166 interested_priority = the_thread->current_priority;1167 }1168 }1169 }1170 1171 if ( interested_thread ) {1172 the_thread = interested_thread;1173 goto process_it;1174 }1175 1176 /*1177 * OK so no threads were interested right now. It will be left on the1178 * global pending until a thread receives it. The global set of threads1179 * can change interest in this signal in one of the following ways:1180 *1181 * + a thread is created with the signal unblocked,1182 * + pthread_sigmask() unblocks the signal,1183 * + sigprocmask() unblocks the signal, OR1184 * + sigaction() which changes the handler to SIG_IGN.1185 */1186 1187 the_thread = NULL;1188 goto post_process_signal;1189 1190 /*1191 * We found a thread which was interested, so now we mark that this1192 * thread needs to do the post context switch extension so it can1193 * evaluate the signals pending.1194 */1195 1196 process_it:1197 1198 the_thread->do_post_task_switch_extension = TRUE;1199 1200 /*1201 * Returns TRUE if the signal was synchronously given to a thread1202 * blocked waiting for the signal.1203 */1204 1205 if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {1206 _Thread_Enable_dispatch();1207 return 0;1208 }1209 1210 post_process_signal:1211 1212 /*1213 * We may have woken up a thread but we definitely need to post the1214 * signal to the process wide information set.1215 */1216 1217 _POSIX_signals_Set_process_signals( mask );1218 1219 if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {1220 1221 psiginfo = (POSIX_signals_Siginfo_node *)1222 _Chain_Get( &_POSIX_signals_Inactive_siginfo );1223 if ( !psiginfo )1224 {1225 set_errno_and_return_minus_one( EAGAIN );1226 }1227 1228 psiginfo->Info = *siginfo;1229 1230 _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );1231 }1232 1233 _Thread_Enable_dispatch();1234 return 0;1235 }1236 1237 914 /* 1238 915 * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 … … 1307 984 return POSIX_BOTTOM_REACHED(); 1308 985 } 1309 1310 /*1311 * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 791312 */1313 1314 Watchdog_Control _POSIX_signals_Alarm_timer;1315 1316 unsigned int alarm(1317 unsigned int seconds1318 )1319 {1320 unsigned int remaining = 0;1321 Watchdog_Control *the_timer;1322 1323 the_timer = &_POSIX_signals_Alarm_timer;1324 1325 switch ( _Watchdog_Remove( the_timer ) ) {1326 case WATCHDOG_INACTIVE:1327 case WATCHDOG_BEING_INSERTED:1328 break;1329 1330 case WATCHDOG_ACTIVE:1331 case WATCHDOG_REMOVE_IT:1332 remaining = the_timer->initial -1333 (the_timer->stop_time - the_timer->start_time);1334 break;1335 }1336 1337 _Watchdog_Insert_seconds( the_timer, seconds );1338 1339 return remaining;1340 }1341 1342 /*1343 * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 811344 */1345 1346 int pause( void )1347 {1348 sigset_t all_signals;1349 int status;1350 1351 (void) sigfillset( &all_signals );1352 1353 status = sigtimedwait( &all_signals, NULL, NULL );1354 1355 return status;1356 }
Note: See TracChangeset
for help on using the changeset viewer.