summaryrefslogtreecommitdiffstats
path: root/include/haproxy/thread-t.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/haproxy/thread-t.h')
-rw-r--r--include/haproxy/thread-t.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/include/haproxy/thread-t.h b/include/haproxy/thread-t.h
new file mode 100644
index 0000000..f3552c2
--- /dev/null
+++ b/include/haproxy/thread-t.h
@@ -0,0 +1,165 @@
+/*
+ * include/haproxy/thread-t.h
+ * Definitions and types for thread support.
+ *
+ * Copyright (C) 2017 Christopher Faulet - cfaulet@haproxy.com
+ * Copyright (C) 2020 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _HAPROXY_THREAD_T_H
+#define _HAPROXY_THREAD_T_H
+
+#include <haproxy/defaults.h>
+
+/* Note: this file mainly contains 3 sections:
+ * - one used solely when USE_THREAD is *not* set
+ * - one used solely when USE_THREAD is set
+ * - a common one.
+ */
+
+#ifndef USE_THREAD
+
+/********************** THREADS DISABLED ************************/
+
+/* These macros allow to make some struct fields or local variables optional */
+#define __decl_spinlock(lock)
+#define __decl_aligned_spinlock(lock)
+#define __decl_rwlock(lock)
+#define __decl_aligned_rwlock(lock)
+
+#elif !defined(DEBUG_THREAD) && !defined(DEBUG_FULL)
+
+/************** THREADS ENABLED WITHOUT DEBUGGING **************/
+
+/* declare a self-initializing spinlock */
+#define __decl_spinlock(lock) \
+ HA_SPINLOCK_T (lock) = 0;
+
+/* declare a self-initializing spinlock, aligned on a cache line */
+#define __decl_aligned_spinlock(lock) \
+ HA_SPINLOCK_T (lock) __attribute__((aligned(64))) = 0;
+
+/* declare a self-initializing rwlock */
+#define __decl_rwlock(lock) \
+ HA_RWLOCK_T (lock) = 0;
+
+/* declare a self-initializing rwlock, aligned on a cache line */
+#define __decl_aligned_rwlock(lock) \
+ HA_RWLOCK_T (lock) __attribute__((aligned(64))) = 0;
+
+#else /* !USE_THREAD */
+
+/**************** THREADS ENABLED WITH DEBUGGING ***************/
+
+/* declare a self-initializing spinlock */
+#define __decl_spinlock(lock) \
+ HA_SPINLOCK_T (lock); \
+ INITCALL1(STG_LOCK, ha_spin_init, &(lock))
+
+/* declare a self-initializing spinlock, aligned on a cache line */
+#define __decl_aligned_spinlock(lock) \
+ HA_SPINLOCK_T (lock) __attribute__((aligned(64))); \
+ INITCALL1(STG_LOCK, ha_spin_init, &(lock))
+
+/* declare a self-initializing rwlock */
+#define __decl_rwlock(lock) \
+ HA_RWLOCK_T (lock); \
+ INITCALL1(STG_LOCK, ha_rwlock_init, &(lock))
+
+/* declare a self-initializing rwlock, aligned on a cache line */
+#define __decl_aligned_rwlock(lock) \
+ HA_RWLOCK_T (lock) __attribute__((aligned(64))); \
+ INITCALL1(STG_LOCK, ha_rwlock_init, &(lock))
+
+#endif /* USE_THREAD */
+
+
+/*** Common parts below ***/
+
+/* storage types used by spinlocks and RW locks */
+#define __HA_SPINLOCK_T unsigned long
+#define __HA_RWLOCK_T unsigned long
+
+
+/* When thread debugging is enabled, we remap HA_SPINLOCK_T and HA_RWLOCK_T to
+ * complex structures which embed debugging info.
+ */
+#if !defined(DEBUG_THREAD) && !defined(DEBUG_FULL)
+
+#define HA_SPINLOCK_T __HA_SPINLOCK_T
+#define HA_RWLOCK_T __HA_RWLOCK_T
+
+#else /* !DEBUG_THREAD */
+
+#define HA_SPINLOCK_T struct ha_spinlock
+#define HA_RWLOCK_T struct ha_rwlock
+
+/* Debugging information that is only used when thread debugging is enabled */
+
+struct lock_stat {
+ uint64_t nsec_wait_for_write;
+ uint64_t nsec_wait_for_read;
+ uint64_t nsec_wait_for_seek;
+ uint64_t num_write_locked;
+ uint64_t num_write_unlocked;
+ uint64_t num_read_locked;
+ uint64_t num_read_unlocked;
+ uint64_t num_seek_locked;
+ uint64_t num_seek_unlocked;
+};
+
+struct ha_spinlock_state {
+ unsigned long owner; /* a bit is set to 1 << tid for the lock owner */
+ unsigned long waiters; /* a bit is set to 1 << tid for waiting threads */
+};
+
+struct ha_rwlock_state {
+ unsigned long cur_writer; /* a bit is set to 1 << tid for the lock owner */
+ unsigned long wait_writers; /* a bit is set to 1 << tid for waiting writers */
+ unsigned long cur_readers; /* a bit is set to 1 << tid for current readers */
+ unsigned long wait_readers; /* a bit is set to 1 << tid for waiting waiters */
+ unsigned long cur_seeker; /* a bit is set to 1 << tid for the lock seekers */
+ unsigned long wait_seekers; /* a bit is set to 1 << tid for waiting seekers */
+};
+
+struct ha_spinlock {
+ __HA_SPINLOCK_T lock;
+ struct {
+ struct ha_spinlock_state st[MAX_TGROUPS];
+ struct {
+ const char *function;
+ const char *file;
+ int line;
+ } last_location; /* location of the last owner */
+ } info;
+};
+
+struct ha_rwlock {
+ __HA_RWLOCK_T lock;
+ struct {
+ struct ha_rwlock_state st[MAX_TGROUPS];
+ struct {
+ const char *function;
+ const char *file;
+ int line;
+ } last_location; /* location of the last write owner */
+ } info;
+};
+
+#endif /* DEBUG_THREAD */
+
+#endif /* _HAPROXY_THREAD_T_H */