Changeset 45c8eea in mainline for uspace/lib/c/generic/private/futex.h


Ignore:
Timestamp:
2018-11-11T15:47:39Z (5 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f4cb6c5f
Parents:
269bc459
git-author:
Jakub Jermar <jakub@…> (2018-11-10 17:49:44)
git-committer:
Jakub Jermar <jakub@…> (2018-11-11 15:47:39)
Message:

Preallocate waitq handle during initialization

Do not clutter futex_down_composable() with the preallocation of the
wait queue handle and do it single-threadedly in futex_initialize().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/private/futex.h

    r269bc459 r45c8eea  
    4646typedef struct futex {
    4747        volatile atomic_int val;
    48         volatile atomic_int lock;
    4948        volatile cap_waitq_handle_t whandle;
    5049
     
    5453} futex_t;
    5554
    56 extern void futex_initialize(futex_t *futex, int value);
     55extern errno_t futex_initialize(futex_t *futex, int value);
    5756
    5857static inline errno_t futex_destroy(futex_t *futex)
     
    6463
    6564#ifdef CONFIG_DEBUG_FUTEX
    66 
    67 #define FUTEX_INITIALIZE(val) { (val), 0, CAP_NIL, NULL }
    68 #define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    6965
    7066void __futex_assert_is_locked(futex_t *, const char *);
     
    8581#else
    8682
    87 #define FUTEX_INITIALIZE(val) { (val), 0, CAP_NIL }
    88 #define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    89 
    9083#define futex_lock(fut)     (void) futex_down((fut))
    9184#define futex_trylock(fut)  futex_trydown((fut))
     
    9891#endif
    9992
    100 static errno_t allocate_waitq(futex_t *futex)
    101 {
    102         int expected = 0;
    103         while (!atomic_compare_exchange_weak_explicit(&futex->lock, &expected,
    104             1, memory_order_acquire, memory_order_relaxed))
    105                 expected = 0;
    106 
    107         if (futex->whandle == CAP_NIL) {
    108                 errno_t rc = __SYSCALL1(SYS_WAITQ_CREATE,
    109                     (sysarg_t) &futex->whandle);
    110                 if (rc != EOK) {
    111                         atomic_store_explicit(&futex->lock, 0,
    112                             memory_order_release);
    113                         return rc;
    114                 }
    115         }
    116 
    117         atomic_store_explicit(&futex->lock, 0, memory_order_release);
    118         return EOK;
     93static inline errno_t futex_allocate_waitq(futex_t *futex)
     94{
     95        return __SYSCALL1(SYS_WAITQ_CREATE, (sysarg_t) &futex->whandle);
    11996}
    12097
     
    140117        // TODO: Add tests for this.
    141118
    142         // Preallocate the waitq handle so that we don't need to risk a failure
    143         // during wakeup
    144         if (futex->whandle == CAP_NIL) {
    145                 errno_t rc = allocate_waitq(futex);
    146                 if (rc != EOK)
    147                         return rc;
    148         }
     119        assert(futex->whandle != CAP_NIL);
    149120
    150121        if (atomic_fetch_sub_explicit(&futex->val, 1, memory_order_acquire) > 0)
Note: See TracChangeset for help on using the changeset viewer.