Changeset 05208d9 in mainline for uspace/lib/c/generic/fibril.c


Ignore:
Timestamp:
2018-07-20T18:33:14Z (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:
64ffd83
Parents:
514d561
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-09 19:49:07)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-20 18:33:14)
Message:

Single-threaded optimization for ready_semaphore performance.

File:
1 edited

Legend:

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

    r514d561 r05208d9  
    5454
    5555#define DPRINTF(...) ((void)0)
     56#undef READY_DEBUG
    5657
    5758/** Member of timeout_list. */
     
    8788static futex_t fibril_futex = FUTEX_INITIALIZER;
    8889static futex_t ready_semaphore = FUTEX_INITIALIZE(0);
     90static long ready_st_count;
    8991
    9092static LIST_INITIALIZE(ready_list);
     
    103105#define _EVENT_TRIGGERED (&_fibril_event_triggered)
    104106#define _EVENT_TIMED_OUT (&_fibril_event_timed_out)
     107
     108static inline void _ready_debug_check(void)
     109{
     110#ifdef READY_DEBUG
     111        assert(!multithreaded);
     112        long count = (long) list_count(&ready_list) +
     113            (long) list_count(&ipc_buffer_free_list);
     114        assert(ready_st_count == count);
     115#endif
     116}
     117
     118static inline long _ready_count(void)
     119{
     120        /*
     121         * The number of available tokens is always equal to the number
     122         * of fibrils in the ready list + the number of free IPC buffer
     123         * buckets.
     124         */
     125
     126        if (multithreaded)
     127                return atomic_get(&ready_semaphore.val);
     128
     129        _ready_debug_check();
     130        return ready_st_count;
     131}
     132
     133static inline void _ready_up(void)
     134{
     135        if (multithreaded) {
     136                futex_up(&ready_semaphore);
     137        } else {
     138                ready_st_count++;
     139                _ready_debug_check();
     140        }
     141}
     142
     143static inline errno_t _ready_down(const struct timeval *expires)
     144{
     145        if (multithreaded)
     146                return futex_down_timeout(&ready_semaphore, expires);
     147
     148        _ready_debug_check();
     149        ready_st_count--;
     150        return EOK;
     151}
    105152
    106153static atomic_t threads_in_ipc_wait = { 0 };
     
    238285        }
    239286
    240         if (!multithreaded) {
    241                 /*
    242                  * The number of available tokens is always equal to the number
    243                  * of fibrils in the ready list + the number of free IPC buffer
    244                  * buckets.
    245                  */
    246 
    247                 assert(atomic_get(&ready_semaphore.val) ==
    248                     list_count(&ready_list) + list_count(&ipc_buffer_free_list));
    249         }
    250 
    251         errno_t rc = futex_down_timeout(&ready_semaphore, expires);
    252 
     287        errno_t rc = _ready_down(expires);
    253288        if (rc != EOK)
    254289                return NULL;
     
    284319        if (rc != EOK && rc != ENOENT) {
    285320                /* Return token. */
    286                 futex_up(&ready_semaphore);
     321                _ready_up();
    287322                return NULL;
    288323        }
     
    316351
    317352                /* Return token. */
    318                 futex_up(&ready_semaphore);
     353                _ready_up();
    319354        } else {
    320355                _ipc_buffer_t *buf = list_pop(&ipc_buffer_free_list, _ipc_buffer_t, link);
     
    347382        /* Enqueue in ready_list. */
    348383        list_append(&f->link, &ready_list);
    349         futex_up(&ready_semaphore);
     384        _ready_up();
    350385
    351386        if (atomic_get(&threads_in_ipc_wait)) {
     
    370405                list_append(&buf->link, &ipc_buffer_free_list);
    371406                /* Return IPC wait token. */
    372                 futex_up(&ready_semaphore);
     407                _ready_up();
    373408
    374409                futex_unlock(&ipc_lists_futex);
     
    754789int fibril_test_spawn_runners(int n)
    755790{
    756         if (!multithreaded)
     791        if (!multithreaded) {
     792                _ready_debug_check();
     793                atomic_set(&ready_semaphore.val, ready_st_count);
    757794                multithreaded = true;
     795        }
    758796
    759797        errno_t rc;
     
    829867        for (int i = 0; i < IPC_BUFFER_COUNT; i++) {
    830868                list_append(&buffers[i].link, &ipc_buffer_free_list);
    831                 futex_up(&ready_semaphore);
     869                _ready_up();
    832870        }
    833871}
Note: See TracChangeset for help on using the changeset viewer.