Changeset ab6edb6 in mainline for uspace/lib/c/generic/fibril.c


Ignore:
Timestamp:
2018-06-26T17:34:48Z (7 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:
e768aea
Parents:
b59318e
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-25 19:28:19)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-26 17:34:48)
Message:

Simplify the interaction between async_futex and fibril_switch().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril.c

    rb59318e rab6edb6  
    7171static void fibril_main(void)
    7272{
    73         /* fibril_futex is locked when a fibril is first started. */
    74         futex_unlock(&fibril_futex);
     73        /* fibril_futex and async_futex are locked when a fibril is started. */
     74        futex_unlock(&fibril_futex);
     75        futex_unlock(&async_futex);
    7576
    7677        fibril_t *fibril = fibril_self();
     
    127128/** Switch from the current fibril.
    128129 *
    129  * If stype is FIBRIL_TO_MANAGER or FIBRIL_FROM_DEAD, the async_futex must
    130  * be held.
     130 * The async_futex must be held when entering this function,
     131 * and is still held on return.
    131132 *
    132133 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
     
    140141int fibril_switch(fibril_switch_type_t stype)
    141142{
     143        /* Make sure the async_futex is held. */
     144        futex_assert_is_locked(&async_futex);
     145
    142146        futex_lock(&fibril_futex);
    143147
     
    146150
    147151        /* Choose a new fibril to run */
    148         switch (stype) {
    149         case FIBRIL_TO_MANAGER:
    150         case FIBRIL_FROM_DEAD:
    151                 /* Make sure the async_futex is held. */
    152                 futex_assert_is_locked(&async_futex);
     152        if (list_empty(&ready_list)) {
     153                if (stype == FIBRIL_PREEMPT) {
     154                        // FIXME: This means that as long as there is a fibril
     155                        // that only yields, IPC messages are never retrieved.
     156                        futex_unlock(&fibril_futex);
     157                        return 0;
     158                }
    153159
    154160                /* If we are going to manager and none exists, create it */
     
    161167                dstf = list_get_instance(list_first(&manager_list),
    162168                    fibril_t, link);
    163 
    164                 /* Bookkeeping. */
    165                 futex_give_to(&async_futex, dstf);
    166 
    167                 if (stype == FIBRIL_FROM_DEAD)
    168                         dstf->clean_after_me = srcf;
    169                 break;
    170         case FIBRIL_PREEMPT:
    171         case FIBRIL_FROM_MANAGER:
    172                 futex_assert_is_not_locked(&async_futex);
    173 
    174                 if (list_empty(&ready_list)) {
    175                         futex_unlock(&fibril_futex);
    176                         return 0;
    177                 }
    178 
     169        } else {
    179170                dstf = list_get_instance(list_first(&ready_list), fibril_t,
    180171                    link);
    181                 break;
    182         }
     172        }
     173
    183174        list_remove(&dstf->link);
     175        if (stype == FIBRIL_FROM_DEAD)
     176                dstf->clean_after_me = srcf;
    184177
    185178        /* Put the current fibril into the correct run list */
     
    192185                break;
    193186        case FIBRIL_FROM_DEAD:
     187        case FIBRIL_FROM_BLOCKED:
    194188                // Nothing.
    195189                break;
    196         case FIBRIL_TO_MANAGER:
    197                 /*
    198                  * Don't put the current fibril into any list, it should
    199                  * already be somewhere, or it will be lost.
    200                  */
    201                 break;
    202190        }
    203191
    204192        /* Bookkeeping. */
    205193        futex_give_to(&fibril_futex, dstf);
     194        futex_give_to(&async_futex, dstf);
    206195
    207196        /* Swap to the next fibril. */
     
    350339void fibril_yield(void)
    351340{
    352         fibril_switch(FIBRIL_PREEMPT);
     341        futex_lock(&async_futex);
     342        (void) fibril_switch(FIBRIL_PREEMPT);
     343        futex_unlock(&async_futex);
    353344}
    354345
Note: See TracChangeset for help on using the changeset viewer.