Libevhtp  1.2.13
refcount.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <pthread.h>
4 
5 static void (* REF_free)(void *) = free;
6 static void * (* REF_realloc)(void *, size_t) = realloc;
7 static void * (* REF_malloc)(size_t) = malloc;
8 
9 struct refcount_ {
10  pthread_mutex_t mux;
11  unsigned int count;
12  char data[];
13 };
14 
15 #define ref_upcast(DAT) \
16  (struct refcount_ *)((char *)(DAT - offsetof(struct refcount_, data)))
17 
18 #define ref_barrier(CODE) \
19  pthread_mutex_lock(&refc->mux); \
20  CODE \
21  pthread_mutex_unlock(&refc->mux)
22 
23 
24 static inline void
25 ref_init_functions(void *(*mallocf)(size_t),
26  void * (*callocf)(size_t, size_t),
27  void *(*reallocf)(void *, size_t),
28  void (* freef)(void *))
29 {
30  REF_malloc = mallocf;
31  REF_realloc = reallocf;
32  REF_free = freef;
33 }
34 
35 static unsigned int
36 ref_inc(void * buf)
37 {
38  struct refcount_ * refc = ref_upcast(buf);
39  unsigned int refs;
40 
41  ref_barrier({ refs = ++refc->count; });
42 
43  return refs;
44 }
45 
46 static unsigned int
47 ref_dec(void * buf)
48 {
49  struct refcount_ * refc = ref_upcast(buf);
50  unsigned int refs;
51 
52  ref_barrier({ refc->count -= 1; refs = refc->count; });
53 
54  return refs;
55 }
56 
57 static inline void *
58 ref_malloc(size_t size)
59 {
60  struct refcount_ * refc;
61  pthread_mutexattr_t attr;
62 
63  refc = REF_malloc(sizeof(*refc) + size);
64  refc->count = 1;
65 
66  pthread_mutexattr_init(&attr);
67  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
68  pthread_mutex_init(&refc->mux, &attr);
69 
70  return refc->data;
71 }
72 
73 static void
74 ref_free(void * buf)
75 {
76  struct refcount_ * refc = ref_upcast(buf);
77 
78  ref_barrier({
79  if (--refc->count == 0)
80  {
81  pthread_mutex_unlock(&refc->mux);
82  return REF_free(refc);
83  }
84  });
85 }
static void *(* REF_malloc)(size_t)
Definition: refcount.h:7
static unsigned int ref_inc(void *buf)
Definition: refcount.h:36
static void *(* REF_realloc)(void *, size_t)
Definition: refcount.h:6
static void(* REF_free)(void *)
Definition: refcount.h:5
#define ref_barrier(CODE)
Definition: refcount.h:18
static void * ref_malloc(size_t size)
Definition: refcount.h:58
char data[]
Definition: refcount.h:12
static void ref_free(void *buf)
Definition: refcount.h:74
static unsigned int ref_dec(void *buf)
Definition: refcount.h:47
static void ref_init_functions(void *(*mallocf)(size_t), void *(*callocf)(size_t, size_t), void *(*reallocf)(void *, size_t), void(*freef)(void *))
Definition: refcount.h:25
#define ref_upcast(DAT)
Definition: refcount.h:15
unsigned int count
Definition: refcount.h:11
pthread_mutex_t mux
Definition: refcount.h:10