mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-15 21:59:41 -04:00
MINOR: thread: define cshared type
Define a new type "struct cshared". This can be used as a tool to manipulate a global counter with thread-safety ensured. Each thread would declare its thread-local cshared type, which would point to a global counter. Each thread can then add/substract value to their owned thread-local cshared instance via cshared_add(). If the difference exceed a configured limit, either positively or negatively, the global counter is updated and thread-local instance is reset to 0. Each thread can safely read the global counter value using cshared_read().
This commit is contained in:
parent
7bad88c35c
commit
3891456d20
2 changed files with 58 additions and 0 deletions
|
|
@ -94,6 +94,20 @@
|
|||
#define __HA_SPINLOCK_T unsigned long
|
||||
#define __HA_RWLOCK_T unsigned long
|
||||
|
||||
/* Type used as a shared value from a global counter. Manipulation to the
|
||||
* global value is thread-safe. Share counter can be increased/decreased
|
||||
* without modifying the global value to reduce contention. The global value is
|
||||
* modified only when the configured limit is reached.
|
||||
*
|
||||
* Typically a cshared is declared as a thread-local variable, with a reference
|
||||
* to a process global value.
|
||||
*/
|
||||
struct cshared {
|
||||
uint64_t *global;
|
||||
int diff;
|
||||
int lim;
|
||||
};
|
||||
|
||||
|
||||
/* When thread debugging is enabled, we remap HA_SPINLOCK_T and HA_RWLOCK_T to
|
||||
* complex structures which embed debugging info.
|
||||
|
|
|
|||
|
|
@ -173,6 +173,23 @@ static inline unsigned long long ha_get_pthread_id(unsigned int thr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void cshared_init(struct cshared *ctr, uint64_t *var, int lim)
|
||||
{
|
||||
ctr->global = var;
|
||||
ctr->diff = 0;
|
||||
ctr->lim = 0;
|
||||
}
|
||||
|
||||
static inline void cshared_add(struct cshared *ctr, int diff)
|
||||
{
|
||||
ctr->global += diff;
|
||||
}
|
||||
|
||||
static inline uint64_t cshared_read(struct cshared *ctr)
|
||||
{
|
||||
return *ctr->global;
|
||||
}
|
||||
|
||||
#else /* !USE_THREAD */
|
||||
|
||||
/********************** THREADS ENABLED ************************/
|
||||
|
|
@ -332,6 +349,33 @@ static inline unsigned long thread_isolated()
|
|||
|
||||
#endif
|
||||
|
||||
/* Init a shared counter <ctr> which references global value <var>. Update are
|
||||
* performed each time the shared counter exceed <lim>, either on the positive
|
||||
* or negative value.
|
||||
*/
|
||||
static inline void cshared_init(struct cshared *ctr, uint64_t *var, int lim)
|
||||
{
|
||||
ctr->global = var;
|
||||
ctr->diff = 0;
|
||||
ctr->lim = lim;
|
||||
}
|
||||
|
||||
/* Add <diff>, which may be positive or negative, to <ctr> shared counter. */
|
||||
static inline void cshared_add(struct cshared *ctr, int diff)
|
||||
{
|
||||
ctr->diff += diff;
|
||||
if (ctr->diff <= -(ctr->lim) || ctr->diff >= ctr->lim) {
|
||||
HA_ATOMIC_ADD(ctr->global, ctr->diff);
|
||||
ctr->diff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Atomically get current global value from <ctr> shared counter. */
|
||||
static inline uint64_t cshared_read(struct cshared *ctr)
|
||||
{
|
||||
return HA_ATOMIC_LOAD(ctr->global);
|
||||
}
|
||||
|
||||
#if (DEBUG_THREAD < 2) && !defined(DEBUG_FULL)
|
||||
|
||||
/* Thread debugging is DISABLED, these are the regular locking functions */
|
||||
|
|
|
|||
Loading…
Reference in a new issue