74 lines
2.0 KiB
C
74 lines
2.0 KiB
C
#ifndef SNC_H
|
|
#define SNC_H
|
|
|
|
/* ========================== *
|
|
* Mutex
|
|
* ========================== */
|
|
|
|
struct snc_lock {
|
|
struct snc_mutex *mutex;
|
|
b32 exclusive;
|
|
};
|
|
|
|
struct alignas(64) snc_mutex {
|
|
/* Bit 31 = Exclusive lock is held
|
|
* Bit 30 = Exclusive lock is pending
|
|
* Bit 0-30 = Shared locks count
|
|
*/
|
|
struct atomic32 v;
|
|
|
|
#if RTC
|
|
struct atomic32 exclusive_fiber_id;
|
|
u8 _pad[56];
|
|
#else
|
|
u8 _pad[60];
|
|
#endif
|
|
};
|
|
STATIC_ASSERT(sizeof(struct snc_mutex) == 64); /* Padding validation */
|
|
STATIC_ASSERT(alignof(struct snc_mutex) == 64); /* Prevent false sharing */
|
|
|
|
struct snc_lock snc_lock_spin_e(struct snc_mutex *m, i32 spin);
|
|
struct snc_lock snc_lock_spin_s(struct snc_mutex *m, i32 spin);
|
|
struct snc_lock snc_lock_e(struct snc_mutex *m);
|
|
struct snc_lock snc_lock_s(struct snc_mutex *m);
|
|
void snc_unlock(struct snc_lock *lock);
|
|
|
|
#if RTC
|
|
# define snc_assert_locked_e(l, m) ASSERT((l)->mutex == (m) && (l)->exclusive == 1)
|
|
# define snc_assert_locked_e_or_s(l, m) ASSERT((l)->mutex == (m))
|
|
#else
|
|
# define snc_assert_locked_e(l, m) (UNUSED)l
|
|
# define snc_assert_locked_e_or_s(l, m) (UNUSED)l
|
|
#endif
|
|
|
|
/* ========================== *
|
|
* Condition variable
|
|
* ========================== */
|
|
|
|
struct alignas(64) snc_cv {
|
|
struct atomic64 wake_gen;
|
|
u8 _pad[56];
|
|
};
|
|
STATIC_ASSERT(sizeof(struct snc_cv) == 64); /* Padding validation */
|
|
STATIC_ASSERT(alignof(struct snc_cv) == 64); /* Prevent false sharing */
|
|
|
|
void snc_cv_wait(struct snc_cv *cv, struct snc_lock *lock);
|
|
void snc_cv_wait_time(struct snc_cv *cv, struct snc_lock *l, i64 timeout_ns);
|
|
void snc_cv_signal(struct snc_cv *cv, i32 count);
|
|
|
|
/* ========================== *
|
|
* Counter
|
|
* ========================== */
|
|
|
|
struct alignas(64) snc_counter {
|
|
struct atomic64 v;
|
|
u8 _pad[56];
|
|
};
|
|
STATIC_ASSERT(sizeof(struct snc_counter) == 64); /* Padding validation */
|
|
STATIC_ASSERT(alignof(struct snc_counter) == 64); /* Prevent false sharing */
|
|
|
|
void snc_counter_add(struct snc_counter *counter, i64 x);
|
|
void snc_counter_wait(struct snc_counter *counter);
|
|
|
|
#endif
|