Merge kamailio modules into sip-router master branch
[sip-router] / lib / cds / ref_cntr.c
1 #include <cds/ref_cntr.h>
2 #include <cds/logger.h>
3 #include <cds/memory.h>
4
5 /* functions for initialization and destruction */
6
7 reference_counter_group_t *create_reference_counter_group(int mutex_cnt)
8 {
9         reference_counter_group_t *g;
10         int i;
11
12         g = cds_malloc(sizeof(*g) + mutex_cnt * sizeof(cds_mutex_t));
13         if (!g) {
14                 ERROR_LOG("can't allocate memory\n");
15                 return NULL;
16         }
17
18         for (i = 0; i < mutex_cnt; i++) {
19                 cds_mutex_init(&g->mutexes[i]);
20         }
21         g->mutex_to_assign = 0;
22         g->mutex_cnt = mutex_cnt;
23
24         return g;
25 }
26
27 void free_reference_counter_group(reference_counter_group_t *grp)
28 {
29         int i;
30         if (grp) {
31                 for (i = 0; i < grp->mutex_cnt; i++) {
32                         cds_mutex_destroy(&grp->mutexes[i]);
33                 }
34                 cds_free(grp);
35         }
36 }
37
38 /* -------------------------------------------------------------------- */
39
40 void init_reference_counter(reference_counter_group_t *grp, reference_counter_data_t *ref)
41 {
42         int m;
43         if (ref && grp) {
44                 m = grp->mutex_to_assign;
45                 ref->cntr = 1;
46                 ref->mutex = grp->mutexes + m;
47                 m = (m + 1) % grp->mutex_cnt; /* can't be less than zero */
48                 grp->mutex_to_assign = m;
49         }
50 }
51
52 void add_reference(reference_counter_data_t *ref)
53 {
54         if (ref) {
55                 if (ref->mutex) cds_mutex_lock(ref->mutex);
56                 ref->cntr++;
57                 if (ref->mutex) cds_mutex_unlock(ref->mutex);
58         }
59 }
60
61 int get_reference_count(reference_counter_data_t *ref)
62 {
63         int res = 0;
64         if (ref) {
65                 if (ref->mutex) cds_mutex_lock(ref->mutex);
66                 res = ref->cntr;
67                 if (ref->mutex) cds_mutex_unlock(ref->mutex);
68         }
69         return res;
70 }
71
72 int remove_reference(reference_counter_data_t *ref)
73 {
74         int res = 0;
75         if (ref) {
76                 if (ref->mutex) cds_mutex_lock(ref->mutex);
77                 if (ref->cntr > 0) ref->cntr--;
78                 if (ref->cntr == 0) res = 1;
79                 if (ref->mutex) cds_mutex_unlock(ref->mutex);
80         }
81         return res;
82 }
83