00001 /* 00002 * $Id: hslot.c 5241 2008-11-21 12:52:25Z henningw $ 00003 * 00004 * Copyright (C) 2001-2003 FhG Fokus 00005 * 00006 * This file is part of Kamailio, a free SIP server. 00007 * 00008 * Kamailio is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version 00012 * 00013 * Kamailio is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 /*! \file 00024 * \brief USRLOC - Hash table collision slot related functions 00025 * \ingroup usrloc 00026 * 00027 * - Module: \ref usrloc 00028 */ 00029 00030 00031 00032 #include "hslot.h" 00033 00034 /*! number of locks */ 00035 int ul_locks_no=4; 00036 /*! global list of locks */ 00037 gen_lock_set_t* ul_locks=0; 00038 00039 00040 /*! 00041 * \brief Initialize locks for the hash table 00042 * \return 0 on success, -1 on failure 00043 */ 00044 int ul_init_locks(void) 00045 { 00046 int i; 00047 i = ul_locks_no; 00048 do { 00049 if ((( ul_locks=lock_set_alloc(i))!=0)&& 00050 (lock_set_init(ul_locks)!=0)) 00051 { 00052 ul_locks_no = i; 00053 LM_INFO("locks array size %d\n", ul_locks_no); 00054 return 0; 00055 00056 } 00057 if (ul_locks){ 00058 lock_set_dealloc(ul_locks); 00059 ul_locks=0; 00060 } 00061 i--; 00062 if(i==0) 00063 { 00064 LM_ERR("failed to allocate locks\n"); 00065 return -1; 00066 } 00067 } while (1); 00068 } 00069 00070 00071 /*! 00072 * \brief Unlock all locks on the list 00073 */ 00074 void ul_unlock_locks(void) 00075 { 00076 unsigned int i; 00077 00078 if (ul_locks==0) 00079 return; 00080 00081 for (i=0;i<ul_locks_no;i++) { 00082 #ifdef GEN_LOCK_T_PREFERED 00083 lock_release(&ul_locks->locks[i]); 00084 #else 00085 ul_release_idx(i); 00086 #endif 00087 }; 00088 } 00089 00090 00091 /*! 00092 * \brief Destroy all locks on the list 00093 */ 00094 void ul_destroy_locks(void) 00095 { 00096 if (ul_locks !=0){ 00097 lock_set_destroy(ul_locks); 00098 lock_set_dealloc(ul_locks); 00099 }; 00100 } 00101 00102 #ifndef GEN_LOCK_T_PREFERED 00103 /*! 00104 * \brief Lock a lock with a certain index 00105 * \param idx lock index 00106 */ 00107 void ul_lock_idx(int idx) 00108 { 00109 lock_set_get(ul_locks, idx); 00110 } 00111 00112 00113 /*! 00114 * \brief Release a lock with a certain index 00115 * \param idx lock index 00116 */ 00117 void ul_release_idx(int idx) 00118 { 00119 lock_set_release(ul_locks, idx); 00120 } 00121 #endif 00122 00123 /*! 00124 * \brief Initialize cache slot structure 00125 * \param _d domain for the hash slot 00126 * \param _s hash slot 00127 * \param n used to get the slot number (modulo number or locks) 00128 */ 00129 void init_slot(struct udomain* _d, hslot_t* _s, int n) 00130 { 00131 _s->n = 0; 00132 _s->first = 0; 00133 _s->last = 0; 00134 _s->d = _d; 00135 00136 #ifdef GEN_LOCK_T_PREFERED 00137 _s->lock = &ul_locks->locks[n%ul_locks_no]; 00138 #else 00139 _s->lockidx = n%ul_locks_no; 00140 #endif 00141 } 00142 00143 00144 /*! 00145 * \brief Deinitialize given slot structure 00146 * \param _s hash slot 00147 */ 00148 void deinit_slot(hslot_t* _s) 00149 { 00150 struct urecord* ptr; 00151 00152 /* Remove all elements */ 00153 while(_s->first) { 00154 ptr = _s->first; 00155 _s->first = _s->first->next; 00156 free_urecord(ptr); 00157 } 00158 00159 _s->n = 0; 00160 _s->last = 0; 00161 _s->d = 0; 00162 } 00163 00164 00165 /*! 00166 * \brief Add an element to an slot's linked list 00167 * \param _s hash slot 00168 * \param _r added record 00169 */ 00170 void slot_add(hslot_t* _s, struct urecord* _r) 00171 { 00172 if (_s->n == 0) { 00173 _s->first = _s->last = _r; 00174 } else { 00175 _r->prev = _s->last; 00176 _s->last->next = _r; 00177 _s->last = _r; 00178 } 00179 _s->n++; 00180 _r->slot = _s; 00181 } 00182 00183 00184 /*! 00185 * \brief Remove an element from slot linked list 00186 * \param _s hash slot 00187 * \param _r removed record 00188 */ 00189 void slot_rem(hslot_t* _s, struct urecord* _r) 00190 { 00191 if (_r->prev) { 00192 _r->prev->next = _r->next; 00193 } else { 00194 _s->first = _r->next; 00195 } 00196 00197 if (_r->next) { 00198 _r->next->prev = _r->prev; 00199 } else { 00200 _s->last = _r->prev; 00201 } 00202 00203 _r->prev = _r->next = 0; 00204 _r->slot = 0; 00205 _s->n--; 00206 }
1.5.6