Changeset e768aea in mainline
- Timestamp:
- 2018-06-26T17:34:48Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8119363
- Parents:
- ab6edb6
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-16 18:56:15)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-26 17:34:48)
- Location:
- uspace/lib/c/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/server.c
rab6edb6 re768aea 1066 1066 assert(call); 1067 1067 1068 /* Kernel notification */ 1069 if ((chandle == CAP_NIL) && (call->flags & IPC_CALL_NOTIF)) { 1070 queue_notification(call); 1068 if (call->flags & IPC_CALL_ANSWERED) 1069 return; 1070 1071 if (chandle == CAP_NIL) { 1072 if (call->flags & IPC_CALL_NOTIF) { 1073 /* Kernel notification */ 1074 queue_notification(call); 1075 } 1071 1076 return; 1072 1077 } … … 1096 1101 1097 1102 /** Fire all timeouts that expired. */ 1098 static void handle_expired_timeouts(void) 1099 { 1103 static suseconds_t handle_expired_timeouts(unsigned int *flags) 1104 { 1105 /* Make sure the async_futex is held. */ 1106 futex_assert_is_locked(&async_futex); 1107 1100 1108 struct timeval tv; 1101 1109 getuptime(&tv); 1102 1110 1103 futex_lock(&async_futex);1111 bool fired = false; 1104 1112 1105 1113 link_t *cur = list_first(&timeout_list); … … 1108 1116 list_get_instance(cur, awaiter_t, to_event.link); 1109 1117 1110 if (tv_gt(&waiter->to_event.expires, &tv)) 1111 break; 1118 if (tv_gt(&waiter->to_event.expires, &tv)) { 1119 if (fired) { 1120 *flags = SYNCH_FLAGS_NON_BLOCKING; 1121 return 0; 1122 } 1123 *flags = 0; 1124 return tv_sub_diff(&waiter->to_event.expires, &tv); 1125 } 1112 1126 1113 1127 list_remove(&waiter->to_event.link); … … 1122 1136 waiter->active = true; 1123 1137 fibril_add_ready(waiter->fid); 1138 fired = true; 1124 1139 } 1125 1140 … … 1127 1142 } 1128 1143 1129 futex_unlock(&async_futex); 1144 if (fired) { 1145 *flags = SYNCH_FLAGS_NON_BLOCKING; 1146 return 0; 1147 } 1148 1149 return SYNCH_NO_TIMEOUT; 1130 1150 } 1131 1151 … … 1146 1166 */ 1147 1167 1148 suseconds_t timeout;1149 1168 unsigned int flags = SYNCH_FLAGS_NONE; 1150 if (!list_empty(&timeout_list)) { 1151 awaiter_t *waiter = list_get_instance( 1152 list_first(&timeout_list), awaiter_t, to_event.link); 1153 1154 struct timeval tv; 1155 getuptime(&tv); 1156 1157 if (tv_gteq(&tv, &waiter->to_event.expires)) { 1158 futex_unlock(&async_futex); 1159 handle_expired_timeouts(); 1160 /* 1161 * Notice that even if the event(s) already 1162 * expired (and thus the other fibril was 1163 * supposed to be running already), 1164 * we check for incoming IPC. 1165 * 1166 * Otherwise, a fibril that continuously 1167 * creates (almost) expired events could 1168 * prevent IPC retrieval from the kernel. 1169 */ 1170 timeout = 0; 1171 flags = SYNCH_FLAGS_NON_BLOCKING; 1172 1173 } else { 1174 timeout = tv_sub_diff(&waiter->to_event.expires, 1175 &tv); 1176 futex_unlock(&async_futex); 1177 } 1178 } else { 1179 futex_unlock(&async_futex); 1180 timeout = SYNCH_NO_TIMEOUT; 1181 } 1169 suseconds_t next_timeout = handle_expired_timeouts(&flags); 1170 futex_unlock(&async_futex); 1182 1171 1183 1172 atomic_inc(&threads_in_ipc_wait); 1184 1173 1185 1174 ipc_call_t call; 1186 errno_t rc = ipc_wait_cycle(&call, timeout, flags);1175 errno_t rc = ipc_wait_cycle(&call, next_timeout, flags); 1187 1176 1188 1177 atomic_dec(&threads_in_ipc_wait); 1189 1178 1190 1179 assert(rc == EOK); 1191 1192 if (call.cap_handle == CAP_NIL) {1193 if ((call.flags &1194 (IPC_CALL_NOTIF | IPC_CALL_ANSWERED)) == 0) {1195 /* Neither a notification nor an answer. */1196 handle_expired_timeouts();1197 continue;1198 }1199 }1200 1201 if (call.flags & IPC_CALL_ANSWERED)1202 continue;1203 1204 1180 handle_call(call.cap_handle, &call); 1205 1181 } -
uspace/lib/c/generic/fibril.c
rab6edb6 re768aea 151 151 /* Choose a new fibril to run */ 152 152 if (list_empty(&ready_list)) { 153 if (stype == FIBRIL_PREEMPT ) {153 if (stype == FIBRIL_PREEMPT || stype == FIBRIL_FROM_MANAGER) { 154 154 // FIXME: This means that as long as there is a fibril 155 155 // that only yields, IPC messages are never retrieved.
Note:
See TracChangeset
for help on using the changeset viewer.