#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.
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 ************************/
#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 */