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:
Amaury Denoyelle 2025-04-25 11:37:07 +02:00
parent 7bad88c35c
commit 3891456d20
2 changed files with 58 additions and 0 deletions

View file

@ -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.

View file

@ -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 */