1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 /*! \file
22  *  \brief USRLOC - Hash table collision slot related functions
23  *  \ingroup usrloc
24  *
25  * - Module: \ref usrloc
26  */
27 
28 
29 
30 #include "hslot.h"
31 
32 /*! number of locks */
33 int ul_locks_no=4;
34 /*! global list of locks */
35 gen_lock_set_t* ul_locks=0;
36 
37 
38 /*!
39  * \brief Initialize locks for the hash table
40  * \return 0 on success, -1 on failure
41  */
ul_init_locks(void)42 int ul_init_locks(void)
43 {
44 	int i;
45 	i = ul_locks_no;
46 	do {
47 		if ((( ul_locks=lock_set_alloc(i))!=0)&&
48 				(lock_set_init(ul_locks)!=0))
49 		{
50 			ul_locks_no = i;
51 			LM_INFO("locks array size %d\n", ul_locks_no);
52 			return 0;
53 
54 		}
55 		if (ul_locks){
56 			lock_set_dealloc(ul_locks);
57 			ul_locks=0;
58 		}
59 		i--;
60 		if(i==0)
61 		{
62 			LM_ERR("failed to allocate locks\n");
63 			return -1;
64 		}
65 	} while (1);
66 }
67 
68 
69 /*!
70  * \brief Unlock all locks on the list
71  */
ul_unlock_locks(void)72 void ul_unlock_locks(void)
73 {
74 	unsigned int i;
75 
76 	if (ul_locks==0)
77 		return;
78 
79 	for (i=0;i<ul_locks_no;i++) {
80 #ifdef GEN_LOCK_T_PREFERED
81 		lock_release(&ul_locks->locks[i]);
82 #else
83 		ul_release_idx(i);
84 #endif
85 	};
86 }
87 
88 
89 /*!
90  * \brief Destroy all locks on the list
91  */
ul_destroy_locks(void)92 void ul_destroy_locks(void)
93 {
94 	if (ul_locks !=0){
95 		lock_set_destroy(ul_locks);
96 		lock_set_dealloc(ul_locks);
97 	};
98 }
99 
100 #ifndef GEN_LOCK_T_PREFERED
101 /*!
102  * \brief Lock a lock with a certain index
103  * \param idx lock index
104  */
ul_lock_idx(int idx)105 void ul_lock_idx(int idx)
106 {
107 	lock_set_get(ul_locks, idx);
108 }
109 
110 
111 /*!
112  * \brief Release a lock with a certain index
113  * \param idx lock index
114  */
ul_release_idx(int idx)115 void ul_release_idx(int idx)
116 {
117 	lock_set_release(ul_locks, idx);
118 }
119 #endif
120 
121 /*!
122  * \brief Initialize cache slot structure
123  * \param _d domain for the hash slot
124  * \param _s hash slot
125  * \param n used to get the slot number (modulo number or locks)
126  */
init_slot(struct udomain * _d,hslot_t * _s,int n)127 void init_slot(struct udomain* _d, hslot_t* _s, int n)
128 {
129 	_s->n = 0;
130 	_s->first = 0;
131 	_s->last = 0;
132 	_s->d = _d;
133 
134 #ifdef GEN_LOCK_T_PREFERED
135 	_s->lock = &ul_locks->locks[n%ul_locks_no];
136 #else
137 	_s->lockidx = n%ul_locks_no;
138 #endif
139 }
140 
141 
142 /*!
143  * \brief Deinitialize given slot structure
144  * \param _s hash slot
145  */
deinit_slot(hslot_t * _s)146 void deinit_slot(hslot_t* _s)
147 {
148 	struct urecord* ptr;
149 
150 	     /* Remove all elements */
151 	while(_s->first) {
152 		ptr = _s->first;
153 		_s->first = _s->first->next;
154 		free_urecord(ptr);
155 	}
156 
157 	_s->n = 0;
158 	_s->last = 0;
159     _s->d = 0;
160 }
161 
162 
163 /*!
164  * \brief Add an element to an slot's linked list
165  * \param _s hash slot
166  * \param _r added record
167  */
slot_add(hslot_t * _s,struct urecord * _r)168 void slot_add(hslot_t* _s, struct urecord* _r)
169 {
170 	if (_s->n == 0) {
171 		_s->first = _s->last = _r;
172 	} else {
173 		_r->prev = _s->last;
174 		_s->last->next = _r;
175 		_s->last = _r;
176 	}
177 	_s->n++;
178 	_r->slot = _s;
179 }
180 
181 
182 /*!
183  * \brief Remove an element from slot linked list
184  * \param _s hash slot
185  * \param _r removed record
186  */
slot_rem(hslot_t * _s,struct urecord * _r)187 void slot_rem(hslot_t* _s, struct urecord* _r)
188 {
189 	if (_r->prev) {
190 		_r->prev->next = _r->next;
191 	} else {
192 		_s->first = _r->next;
193 	}
194 
195 	if (_r->next) {
196 		_r->next->prev = _r->prev;
197 	} else {
198 		_s->last = _r->prev;
199 	}
200 
201 	_r->prev = _r->next = 0;
202 	_r->slot = 0;
203 	_s->n--;
204 }
205