#define HA_RWLOCK_SKUNLOCK(lbl,l) do { /* do nothing */ } while(0)
#define HA_RWLOCK_TRYSKLOCK(lbl,l) ({ 0; })
#define HA_RWLOCK_TRYRDTOSK(lbl,l) ({ 0; })
+#define HA_RWLOCK_TRYRDTOWR(lbl,l) ({ 0; })
#define ha_sigmask(how, set, oldset) sigprocmask(how, set, oldset)
#define HA_RWLOCK_SKUNLOCK(lbl,l) pl_drop_s(l) /* S --> N */
#define HA_RWLOCK_TRYSKLOCK(lbl,l) (!pl_try_s(l)) /* N -?> S */
#define HA_RWLOCK_TRYRDTOSK(lbl,l) (!pl_try_rtos(l)) /* R -?> S */
+#define HA_RWLOCK_TRYRDTOWR(lbl, l) (!pl_try_rtow(l)) /* R -?> W */
#else /* !defined(DEBUG_THREAD) && !defined(DEBUG_FULL) */
#define __RWLOCK_SKUNLOCK(l) pl_drop_s(l) /* S --> N */
#define __RWLOCK_TRYSKLOCK(l) (!pl_try_s(l)) /* N -?> S */
#define __RWLOCK_TRYRDTOSK(l) (!pl_try_rtos(l)) /* R -?> S */
+#define __RWLOCK_TRYRDTOWR(l) (!pl_try_rtow(l)) /* R -?> W */
#define HA_SPIN_INIT(l) __spin_init(l)
#define HA_SPIN_DESTROY(l) __spin_destroy(l)
#define HA_RWLOCK_SKUNLOCK(lbl,l) __ha_rwlock_skunlock(lbl, l, __func__, __FILE__, __LINE__)
#define HA_RWLOCK_TRYSKLOCK(lbl,l) __ha_rwlock_trysklock(lbl, l, __func__, __FILE__, __LINE__)
#define HA_RWLOCK_TRYRDTOSK(lbl,l) __ha_rwlock_tryrdtosk(lbl, l, __func__, __FILE__, __LINE__)
+#define HA_RWLOCK_TRYRDTOWR(lbl,l) __ha_rwlock_tryrdtowr(lbl, l, __func__, __FILE__, __LINE__)
/* Following functions are used to collect some stats about locks. We wrap
* pthread functions to known how much time we wait in a lock. */
const char *func, const char *file, int line);
int __ha_rwlock_tryrdtosk(enum lock_label lbl, struct ha_rwlock *l,
const char *func, const char *file, int line);
+int __ha_rwlock_tryrdtowr(enum lock_label lbl, struct ha_rwlock *l,
+ const char *func, const char *file, int line);
void __spin_init(struct ha_spinlock *l);
void __spin_destroy(struct ha_spinlock *l);
void __spin_lock(enum lock_label lbl, struct ha_spinlock *l,
return r;
}
+int __ha_rwlock_tryrdtowr(enum lock_label lbl, struct ha_rwlock *l,
+ const char *func, const char *file, int line)
+{
+ ulong tbit = (ti && ti->ltid_bit) ? ti->ltid_bit : 1;
+ struct ha_rwlock_state *st = &l->info.st[tgid-1];
+ uint64_t start_time;
+ uint bucket;
+ int r;
+
+ if ((st->cur_writer | st->cur_seeker) & tbit)
+ abort();
+
+ if (!(st->cur_readers & tbit))
+ abort();
+
+ HA_ATOMIC_OR(&st->wait_writers, tbit);
+
+ start_time = -now_mono_time();
+ r = __RWLOCK_TRYRDTOWR(&l->lock);
+ start_time += now_mono_time();
+
+ if (likely(!r)) {
+ /* got the lock ! */
+ HA_ATOMIC_ADD(&lock_stats_sk[lbl].nsec_wait, start_time);
+
+ start_time &= 0x3fffffff; // keep values below 1 billion only
+ bucket = flsnz((uint32_t)start_time ? (uint32_t)start_time : 1) - 1;
+ HA_ATOMIC_INC(&lock_stats_sk[lbl].buckets[bucket]);
+ HA_ATOMIC_OR(&st->cur_writer, tbit);
+ HA_ATOMIC_AND(&st->cur_readers, ~tbit);
+ l->info.last_location.function = func;
+ l->info.last_location.file = file;
+ l->info.last_location.line = line;
+ }
+
+ HA_ATOMIC_AND(&st->wait_writers, ~tbit);
+ return r;
+}
+
+
void __spin_init(struct ha_spinlock *l)
{
memset(l, 0, sizeof(struct ha_spinlock));