blob: d2bf8d365a04d2200dec27ed45cdadbeb8589233 [file] [log] [blame]
Willy Tarreau3f567e42020-05-28 15:29:19 +02001/*
2 * include/haproxy/thread-t.h
3 * Definitions and types for thread support.
4 *
5 * Copyright (C) 2017 Christopher Faulet - cfaulet@haproxy.com
6 * Copyright (C) 2020 Willy Tarreau - w@1wt.eu
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation, version 2.1
11 * exclusively.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef _HAPROXY_THREAD_T_H
24#define _HAPROXY_THREAD_T_H
25
26#ifdef USE_THREAD
27#include <pthread.h>
28#endif
Willy Tarreau3f567e42020-05-28 15:29:19 +020029
Willy Tarreauca8b0692020-06-11 08:14:01 +020030#include <haproxy/defaults.h>
Willy Tarreau3f567e42020-05-28 15:29:19 +020031
32/* Note: this file mainly contains 3 sections:
33 * - one used solely when USE_THREAD is *not* set
34 * - one used solely when USE_THREAD is set
35 * - a common one.
36 */
37
38#ifndef USE_THREAD
39
40/********************** THREADS DISABLED ************************/
41
Willy Tarreau3f567e42020-05-28 15:29:19 +020042/* These macros allow to make some struct fields or local variables optional */
Willy Tarreau3f567e42020-05-28 15:29:19 +020043#define __decl_spinlock(lock)
44#define __decl_aligned_spinlock(lock)
45#define __decl_rwlock(lock)
46#define __decl_aligned_rwlock(lock)
47
48#else /* !USE_THREAD */
49
50/********************** THREADS ENABLED ************************/
51
Willy Tarreau3f567e42020-05-28 15:29:19 +020052/* declare a self-initializing spinlock */
53#define __decl_spinlock(lock) \
54 HA_SPINLOCK_T (lock); \
55 INITCALL1(STG_LOCK, ha_spin_init, &(lock))
56
57/* declare a self-initializing spinlock, aligned on a cache line */
58#define __decl_aligned_spinlock(lock) \
59 HA_SPINLOCK_T (lock) __attribute__((aligned(64))); \
60 INITCALL1(STG_LOCK, ha_spin_init, &(lock))
61
62/* declare a self-initializing rwlock */
63#define __decl_rwlock(lock) \
64 HA_RWLOCK_T (lock); \
65 INITCALL1(STG_LOCK, ha_rwlock_init, &(lock))
66
67/* declare a self-initializing rwlock, aligned on a cache line */
68#define __decl_aligned_rwlock(lock) \
69 HA_RWLOCK_T (lock) __attribute__((aligned(64))); \
70 INITCALL1(STG_LOCK, ha_rwlock_init, &(lock))
71
72#endif /* USE_THREAD */
73
74
75/*** Common parts below ***/
76
Willy Tarreau3f567e42020-05-28 15:29:19 +020077/* storage types used by spinlocks and RW locks */
78#define __HA_SPINLOCK_T unsigned long
79#define __HA_RWLOCK_T unsigned long
80
81
82/* When thread debugging is enabled, we remap HA_SPINLOCK_T and HA_RWLOCK_T to
83 * complex structures which embed debugging info.
84 */
85#if !defined(DEBUG_THREAD) && !defined(DEBUG_FULL)
86
87#define HA_SPINLOCK_T __HA_SPINLOCK_T
88#define HA_RWLOCK_T __HA_RWLOCK_T
89
90#else /* !DEBUG_THREAD */
91
92#define HA_SPINLOCK_T struct ha_spinlock
93#define HA_RWLOCK_T struct ha_rwlock
94
95/* Debugging information that is only used when thread debugging is enabled */
96
97struct lock_stat {
98 uint64_t nsec_wait_for_write;
99 uint64_t nsec_wait_for_read;
100 uint64_t num_write_locked;
101 uint64_t num_write_unlocked;
102 uint64_t num_read_locked;
103 uint64_t num_read_unlocked;
104};
105
106struct ha_spinlock {
107 __HA_SPINLOCK_T lock;
108 struct {
109 unsigned long owner; /* a bit is set to 1 << tid for the lock owner */
110 unsigned long waiters; /* a bit is set to 1 << tid for waiting threads */
111 struct {
112 const char *function;
113 const char *file;
114 int line;
115 } last_location; /* location of the last owner */
116 } info;
117};
118
119struct ha_rwlock {
120 __HA_RWLOCK_T lock;
121 struct {
122 unsigned long cur_writer; /* a bit is set to 1 << tid for the lock owner */
123 unsigned long wait_writers; /* a bit is set to 1 << tid for waiting writers */
124 unsigned long cur_readers; /* a bit is set to 1 << tid for current readers */
125 unsigned long wait_readers; /* a bit is set to 1 << tid for waiting waiters */
126 struct {
127 const char *function;
128 const char *file;
129 int line;
130 } last_location; /* location of the last write owner */
131 } info;
132};
133
134#endif /* DEBUG_THREAD */
135
136#endif /* _HAPROXY_THREAD_T_H */