Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/include/futex.h

    r156b6406 r9d58539  
    3838#include <atomic.h>
    3939#include <sys/types.h>
    40 #include <libc.h>
    4140
    42 typedef struct futex {
    43         atomic_t val;
    44 #ifdef FUTEX_UPGRADABLE
    45         int upgraded;
    46 #endif
    47 } futex_t;
     41#define FUTEX_INITIALIZER  {1}
    4842
     43typedef atomic_t futex_t;
    4944
    5045extern void futex_initialize(futex_t *futex, int value);
    51 
    52 #ifdef FUTEX_UPGRADABLE
    53 #include <rcu.h>
    54 
    55 #define FUTEX_INITIALIZE(val) {{ (val) }, 0}
    56 
    57 #define futex_lock(fut) \
    58 ({ \
    59         rcu_read_lock(); \
    60         (fut)->upgraded = rcu_access(_upgrade_futexes); \
    61         if ((fut)->upgraded) \
    62                 (void) futex_down((fut)); \
    63 })
    64 
    65 #define futex_trylock(fut) \
    66 ({ \
    67         rcu_read_lock(); \
    68         int _upgraded = rcu_access(_upgrade_futexes); \
    69         if (_upgraded) { \
    70                 int _acquired = futex_trydown((fut)); \
    71                 if (!_acquired) { \
    72                         rcu_read_unlock(); \
    73                 } else { \
    74                         (fut)->upgraded = true; \
    75                 } \
    76                 _acquired; \
    77         } else { \
    78                 (fut)->upgraded = false; \
    79                 1; \
    80         } \
    81 })
    82                
    83 #define futex_unlock(fut) \
    84 ({ \
    85         if ((fut)->upgraded) \
    86                 (void) futex_up((fut)); \
    87         rcu_read_unlock(); \
    88 })
    89 
    90 extern int _upgrade_futexes;
    91 
    92 extern void futex_upgrade_all_and_wait(void);
    93                
    94 #else
    95 
    96 #define FUTEX_INITIALIZE(val) {{ (val) }}
    97 
    98 #define futex_lock(fut)     (void) futex_down((fut))
    99 #define futex_trylock(fut)  futex_trydown((fut))
    100 #define futex_unlock(fut)   (void) futex_up((fut))
    101                
    102 #endif
    103 
    104 #define FUTEX_INITIALIZER     FUTEX_INITIALIZE(1)
    105 
    106 /** Try to down the futex.
    107  *
    108  * @param futex Futex.
    109  *
    110  * @return Non-zero if the futex was acquired.
    111  * @return Zero if the futex was not acquired.
    112  *
    113  */
    114 static inline int futex_trydown(futex_t *futex)
    115 {
    116         return cas(&futex->val, 1, 0);
    117 }
    118 
    119 /** Down the futex.
    120  *
    121  * @param futex Futex.
    122  *
    123  * @return ENOENT if there is no such virtual address.
    124  * @return Zero in the uncontended case.
    125  * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
    126  *
    127  */
    128 static inline int futex_down(futex_t *futex)
    129 {
    130         if ((atomic_signed_t) atomic_predec(&futex->val) < 0)
    131                 return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->val.count);
    132        
    133         return 0;
    134 }
    135 
    136 /** Up the futex.
    137  *
    138  * @param futex Futex.
    139  *
    140  * @return ENOENT if there is no such virtual address.
    141  * @return Zero in the uncontended case.
    142  *
    143  */
    144 static inline int futex_up(futex_t *futex)
    145 {
    146         if ((atomic_signed_t) atomic_postinc(&futex->val) < 0)
    147                 return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->val.count);
    148        
    149         return 0;
    150 }
     46extern int futex_down(futex_t *futex);
     47extern int futex_trydown(futex_t *futex);
     48extern int futex_up(futex_t *futex);
    15149
    15250#endif
Note: See TracChangeset for help on using the changeset viewer.