Changeset e768aea in mainline


Ignore:
Timestamp:
2018-06-26T17:34:48Z (6 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
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)
Message:

Simplify async manager.

Location:
uspace/lib/c/generic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async/server.c

    rab6edb6 re768aea  
    10661066        assert(call);
    10671067
    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                }
    10711076                return;
    10721077        }
     
    10961101
    10971102/** Fire all timeouts that expired. */
    1098 static void handle_expired_timeouts(void)
    1099 {
     1103static 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
    11001108        struct timeval tv;
    11011109        getuptime(&tv);
    11021110
    1103         futex_lock(&async_futex);
     1111        bool fired = false;
    11041112
    11051113        link_t *cur = list_first(&timeout_list);
     
    11081116                    list_get_instance(cur, awaiter_t, to_event.link);
    11091117
    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                }
    11121126
    11131127                list_remove(&waiter->to_event.link);
     
    11221136                        waiter->active = true;
    11231137                        fibril_add_ready(waiter->fid);
     1138                        fired = true;
    11241139                }
    11251140
     
    11271142        }
    11281143
    1129         futex_unlock(&async_futex);
     1144        if (fired) {
     1145                *flags = SYNCH_FLAGS_NON_BLOCKING;
     1146                return 0;
     1147        }
     1148
     1149        return SYNCH_NO_TIMEOUT;
    11301150}
    11311151
     
    11461166                 */
    11471167
    1148                 suseconds_t timeout;
    11491168                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);
    11821171
    11831172                atomic_inc(&threads_in_ipc_wait);
    11841173
    11851174                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);
    11871176
    11881177                atomic_dec(&threads_in_ipc_wait);
    11891178
    11901179                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 
    12041180                handle_call(call.cap_handle, &call);
    12051181        }
  • uspace/lib/c/generic/fibril.c

    rab6edb6 re768aea  
    151151        /* Choose a new fibril to run */
    152152        if (list_empty(&ready_list)) {
    153                 if (stype == FIBRIL_PREEMPT) {
     153                if (stype == FIBRIL_PREEMPT || stype == FIBRIL_FROM_MANAGER) {
    154154                        // FIXME: This means that as long as there is a fibril
    155155                        // that only yields, IPC messages are never retrieved.
Note: See TracChangeset for help on using the changeset viewer.