File: locking.xml

package info (click to toggle)
kamailio 6.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 70,472 kB
  • sloc: ansic: 859,394; xml: 203,514; makefile: 9,688; sh: 9,105; sql: 8,571; yacc: 4,121; python: 3,086; perl: 2,955; java: 449; cpp: 289; javascript: 270; php: 258; ruby: 248; awk: 27
file content (289 lines) | stat: -rw-r--r-- 9,102 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<section id="locking" xmlns:xi="http://www.w3.org/2001/XInclude">
    <sectioninfo>
	<revhistory>
	    <revision>
		<revnumber>$Revision$</revnumber>
		<date>$Date$</date>
	    </revision>
	</revhistory>
    </sectioninfo>

    <title>Locking Interface</title>

    <section id="why">
	<title>Why use it ?</title>
	<para>
	    The main reason in creating it was to have a single transparent
	    interface to various locking methods. For example right now SER
	    uses the following locking methods, depending on their availability
	    on the target system.
	</para>
	<itemizedlist>
	    <listitem>
		<simpara><emphasis>FAST_LOCK</emphasis></simpara>
		<simpara>
		    Fast inline assembly locks, defined in
		    <filename>fast_lock.h</filename>. They are currently
		    available for x86, sparc64, strong-arm (amv4l) and ppc
		    (external untested contributed code). In general if the
		    assembly code exists for a given architecture and the
		    compiler knows inline assembly (for example sun cc does
		    not) FAST_LOCK is preferred. The main advantage of using
		    FAST_LOCK is very low memory overhead and extremely fast
		    lock/unlock operations (like 20 times faster than SYSV
		    semaphores on linux &amp; 40 times on solaris). The only thing
		    that comes close to them are pthread mutexes (which are
		    about 3-4 times slower).
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><emphasis>PTHREAD_MUTEX</emphasis></simpara>
		<simpara>
		    Uses pthread_mutex_lock/unlock. They are quite fast but
		    they work between processes only on some systems (they do
		    not work on linux).
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><emphasis>POSIX_SEM</emphasis></simpara>
		<simpara>
		    Uses posix semaphores
		    (<function>sem_wait</function>/<function>sem_post</function>). They
		    are slower than the previous methods but still way faster
		    then SYSV semaphores. Unfortunately they also do not work
		    on all the systems (e.g. linux).
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><emphasis>SYSV_SEM</emphasis></simpara>
		<simpara>
		    This is the most portable but also the slowest locking
		    method. Another problem is that the number of semaphores
		    that can be allocated by a process is limited. One also has
		    to free them before exiting.
		</simpara>
	    </listitem>
	</itemizedlist>
    </section>

    <section id="how">
	<title>How to use it ?</title>
	<simpara>
	    First of all you have to include
	    <filename>locking.h</filename>. Then when compiling the code one or
	    all of FAST_LOCK, USE_PTHREAD_MUTEX, USE_PTHREAD_SEM or
	    USE_SYSV_SEM must be defined (the ser
	    <filename>Makefile.defs</filename> takes care of this, you should
	    need to change it only for new architectures or
	    compilers). <filename>locking.h</filename> defines 2 new types:
	    <structname>gen_lock_t</structname> and
	    <structname>lock_set_t</structname>.
	</simpara>
    </section>
    
    <section id="simple_locks">
	<title>Simple Locks</title>
	<simpara>
	    The simple locks are simple mutexes. The type is
	    <structname>gen_lock_t</structname>.
	</simpara>
	<warning>
	    <simpara>
		Do not make any assumptions on
		<structname>gen_lock_t</structname> base type, it does not have
		to be always an int.
	    </simpara>
	</warning>
	
	<section id="allocation_and_initialization">
	    <title>Allocation And Initialization</title>
	    <simpara>
		The locks are allocated with: <function>gen_lock_t*
		    lock_alloc()</function> and initialized with
		    <function>gen_lock_t* lock_init(gen_lock_t*
		    lock)</function>. Both functions return 0 on failure. The
		    locks must be initialized before use. A proper alloc/init
		    sequence looks like:
	    </simpara>
	    <programlisting>
gen_lock_t* lock;

lock=lock_alloc();
if (lock==0) goto error;
if (lock_init(lock)==0){
   lock_dealloc(lock);
   goto error; /* could not init lock*/
}
...
	    </programlisting>
	    <simpara>
		Lock allocation can be skipped in some cases: if the lock is
		already in shared memory you don't need to allocate it again,
		you can initialize it directly, but keep in mind that the lock
		<emphasis>MUST</emphasis> be in shared memory.
	    </simpara>
	    <simpara>
		Example:
	    </simpara>
	    <programlisting>
struct s {
    int foo;
    gen_lock_t lock;
} bar;

bar=shm_malloc(sizeof struct s); /* we allocate it in the shared memory */
if (lock_init(&amp;bar->lock)==0){
 /* error initializing the lock */
 ...
}
	    </programlisting>
	</section>
	
	<section id="destroying">
	    <title>Destroying And Deallocating the Locks</title>
	    <funcsynopsis>
		<funcprototype>
		    <funcdef>void <function>lock_destroy</function></funcdef>
		    <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
		</funcprototype>
		<funcprototype>
		    <funcdef>void <function>lock_dealloc</function></funcdef>
		    <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
		</funcprototype>
	    </funcsynopsis>
	    <simpara>
		The <function>lock_destroy</function> function must be called
		first. It removes the resources associated with the lock, but
		it does not also free the lock shared memory part. Think of
		sysv <command>rmid</command>.  Please don't forget to call this
		function, or you can leave allocated resources in some cases
		(e.g sysv semaphores). Be careful to call it in your module
		destroy function if you use any global module locks.
	    </simpara>
	    <simpara>
		Example:
	    </simpara>
	    <programlisting>
lock_destroy(lock);
lock_dealloc(lock);
	    </programlisting>
	    <simpara>
		Of course you don't need to call
		<function>lock_dealloc</function> if your lock was not
		allocated with <function>lock_alloc</function>.
	    </simpara>
	</section>
	
	<section id="locking_unlocking">
	    <title>Locking And Unlocking</title>
	    <funcsynopsis>
		<funcprototype>
		    <funcdef>void <function>lock_get</function></funcdef>
		    <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
		</funcprototype>
		<funcprototype>
		    <funcdef>void <function>lock_release</function></funcdef>
		    <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
		</funcprototype>
	    </funcsynopsis>
	</section>
	
	<section id="lock_sets">
	    <title>Lock Sets</title>
	    <simpara>
		The lock sets are kind of sysv semaphore sets equivalent. The
		type is <structname>lock_set_t</structname>.  Use them when you
		need a lot of mutexes. In some cases they waste less system
		resources than arrays of <structname>gen_lock_t</structname>
		(e.g. sys v semaphores).
	    </simpara>

	    <section id="sets.allocating">
		<title>Allocating And Initializing</title>
		<funcsynopsis>
		    <funcprototype>
			<funcdef>lock_set_t* lock_set_alloc</funcdef>
			<paramdef><parameter>int no</parameter></paramdef>
		    </funcprototype>
		    <funcprototype>
			<funcdef>lock_set_t* lock_set_init</funcdef>
			<paramdef><parameter>lock_set_t* set</parameter></paramdef>
		    </funcprototype>
		</funcsynopsis>
		<simpara>
		    Both functions return 0 on failure.
		</simpara>
		<warning>
		    <simpara>
			Expect the allocation function to fail for large
			numbers. It depends on the locking method used and the
			system available resources (again the sysv semaphores
			example).
		    </simpara>
		</warning>
		<simpara>
		    Example:
		</simpara>
		<programlisting>
lock_set_t *lock_set;

lock_set=lock_set_alloc(100);
if (lock_set==0) goto error;
if (lock_set_init(lock_set)==0){
   lock_set_dealloc(lock_set);
   goto error;
}
		</programlisting>
	    </section>

	    <section id="sets.destroying">
		<title>Destroying And Deallocating</title>
		<funcsynopsis>
		    <funcprototype>
			<funcdef>void <function>lock_set_destroy</function></funcdef>
			<paramdef><parameter>lock_set_t* s</parameter></paramdef>
		    </funcprototype>
		    <funcprototype>
			<funcdef>void <function>lock_set_dealloc</function></funcdef>
			<paramdef><parameter>lock_set_t* s</parameter></paramdef>
		    </funcprototype>
		</funcsynopsis>
		<simpara>
		    Again don't forget to "destroy" the locks.
		</simpara>
	    </section>
	    
	    <section id="sets.locking">
		<title>Locking And Unlocking</title>
		<funcsynopsis>
		    <funcprototype>
			<funcdef>void <function>lock_set_get</function></funcdef>
			<paramdef>
			    <parameter>lock_set_t* s</parameter>
			    <parameter>int i</parameter>
			</paramdef>
		    </funcprototype>
		    <funcprototype>
			<funcdef>void <function>lock_set_release</function></funcdef>
			<paramdef>
			    <parameter>lock_set_t* s</parameter>
			    <parameter>int i</parameter>
			</paramdef>
		    </funcprototype>
		</funcsynopsis>
		<simpara>
		    Example:
		</simpara>
		<programlisting>
lock_set_get(lock_set, 2);
/* do something */
lock_set_release(lock_set, 2);
		</programlisting>
	    </section>
	</section>
    </section>
</section>