locking.xml 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
  4. <section id="locking" xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <sectioninfo>
  6. <revhistory>
  7. <revision>
  8. <revnumber>$Revision$</revnumber>
  9. <date>$Date$</date>
  10. </revision>
  11. </revhistory>
  12. </sectioninfo>
  13. <title>Locking Interface</title>
  14. <section id="why">
  15. <title>Why use it ?</title>
  16. <para>
  17. The main reason in creating it was to have a single transparent
  18. interface to various locking methods. For example right now SER
  19. uses the following locking methods, depending on their availability
  20. on the target system.
  21. </para>
  22. <itemizedlist>
  23. <listitem>
  24. <simpara><emphasis>FAST_LOCK</emphasis></simpara>
  25. <simpara>
  26. Fast inline assembly locks, defined in
  27. <filename>fast_lock.h</filename>. They are currently
  28. available for x86, sparc64, strong-arm (amv4l) and ppc
  29. (external untested contributed code). In general if the
  30. assembly code exists for a given architecture and the
  31. compiler knows inline assembly (for example sun cc does
  32. not) FAST_LOCK is preferred. The main advantage of using
  33. FAST_LOCK is very low memory overhead and extremely fast
  34. lock/unlock operations (like 20 times faster then SYSV
  35. semaphores on linux &amp; 40 times on solaris). The only thing
  36. that comes close to them are pthread mutexes (which are
  37. about 3-4 times slower).
  38. </simpara>
  39. </listitem>
  40. <listitem>
  41. <simpara><emphasis>PHTREAD_MUTEX</emphasis></simpara>
  42. <simpara>
  43. Uses pthread_mutex_lock/unlock. They are quite fast but
  44. they work between processes only on some systems (they do
  45. not work on linux).
  46. </simpara>
  47. </listitem>
  48. <listitem>
  49. <simpara><emphasis>POSIX_SEM</emphasis></simpara>
  50. <simpara>
  51. Uses posix semaphores
  52. (<function>sem_wait</function>/<function>sem_post</function>). They
  53. are slower then the previous methods but still way faster
  54. then SYSV semaphores. Unfortunately they also do not work
  55. on all the systems (e.g. linux).
  56. </simpara>
  57. </listitem>
  58. <listitem>
  59. <simpara><emphasis>SYSV_SEM</emphasis></simpara>
  60. <simpara>
  61. This is the most portable but also the slowest locking
  62. method. Another problem is that the number of semaphores
  63. that can be allocated by a process is limited. One also has
  64. to free them before exiting.
  65. </simpara>
  66. </listitem>
  67. </itemizedlist>
  68. </section>
  69. <section id="how">
  70. <title>How to use it ?</title>
  71. <simpara>
  72. First of all you have to include
  73. <filename>locking.h</filename>. Then when compiling the code one or
  74. all of FAST_LOCK, USE_PTHREAD_MUTEX, USE_PTHREAD_SEM or
  75. USE_SYSV_SEM must be defined (the ser
  76. <filename>Makefile.defs</filename> takes care of this, you should
  77. need to change it only for new architectures or
  78. compilers). <filename>locking.h</filename> defines 2 new types:
  79. <structname>gen_lock_t</structname> and
  80. <structname>lock_set_t</structname>.
  81. </simpara>
  82. </section>
  83. <section id="simple_locks">
  84. <title>Simple Locks</title>
  85. <simpara>
  86. The simple locks are simple mutexes. The type is
  87. <structname>gen_lock_t</structname>.
  88. </simpara>
  89. <warning>
  90. <simpara>
  91. Do not make any assumptions on
  92. <structname>gen_lock_t</structname> base type, it does not have
  93. to be always an int.
  94. </simpara>
  95. </warning>
  96. <section id="allocation_and_initialization">
  97. <title>Allocation And Initialization</title>
  98. <simpara>
  99. The locks are allocated with: <function>gen_lock_t*
  100. lock_alloc()</function> and initialized with
  101. <function>gen_lock_t* lock_init(gen_lock_t*
  102. lock)</function>. Both functions return 0 on failure. The
  103. locks must be initialized before use. A proper alloc/init
  104. sequence looks like:
  105. </simpara>
  106. <programlisting>
  107. gen_lock_t* lock;
  108. lock=lock_alloc();
  109. if (lock==0) goto error;
  110. if (lock_init(lock)==0){
  111. lock_dealloc(lock);
  112. goto error; /* could not init lock*/
  113. }
  114. ...
  115. </programlisting>
  116. <simpara>
  117. Lock allocation can be skipped in some cases: if the lock is
  118. already in shared memory you don't need to allocate it again,
  119. you can initialize it directly, but keep in mind that the lock
  120. <emphasis>MUST</emphasis> be in shared memory.
  121. </simpara>
  122. <simpara>
  123. Example:
  124. </simpara>
  125. <programlisting>
  126. struct s {
  127. int foo;
  128. gen_lock_t lock;
  129. } bar;
  130. bar=shm_malloc(sizeof struct s); /* we allocate it in the shared memory */
  131. if (lock_init(&amp;bar->lock)==0){
  132. /* error initializing the lock */
  133. ...
  134. }
  135. </programlisting>
  136. </section>
  137. <section id="destroying">
  138. <title>Destroying And Deallocating the Locks</title>
  139. <funcsynopsis>
  140. <funcprototype>
  141. <funcdef>void <function>lock_destroy</function></funcdef>
  142. <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
  143. </funcprototype>
  144. <funcprototype>
  145. <funcdef>void <function>lock_dealloc</function></funcdef>
  146. <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
  147. </funcprototype>
  148. </funcsynopsis>
  149. <simpara>
  150. The <function>lock_destroy</function> function must be called
  151. first. It removes the resources associated with the lock, but
  152. it does not also free the lock shared memory part. Think of
  153. sysv <command>rmid</command>. Please don't forget to call this
  154. function, or you can leave allocated resources in some cases
  155. (e.g sysv semaphores). Be careful to call it in your module
  156. destroy function if you use any global module locks.
  157. </simpara>
  158. <simpara>
  159. Example:
  160. </simpara>
  161. <programlisting>
  162. lock_destroy(lock);
  163. lock_dealloc(lock);
  164. </programlisting>
  165. <simpara>
  166. Of course you don't need to call
  167. <function>lock_dealloc</function> if your lock was not
  168. allocated with <function>lock_alloc</function>.
  169. </simpara>
  170. </section>
  171. <section id="locking_unlocking">
  172. <title>Locking And Unlocking</title>
  173. <funcsynopsis>
  174. <funcprototype>
  175. <funcdef>void <function>lock_get</function></funcdef>
  176. <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
  177. </funcprototype>
  178. <funcprototype>
  179. <funcdef>void <function>lock_release</function></funcdef>
  180. <paramdef><parameter>gen_lock_t* lock</parameter></paramdef>
  181. </funcprototype>
  182. </funcsynopsis>
  183. </section>
  184. <section id="lock_sets">
  185. <title>Lock Sets</title>
  186. <simpara>
  187. The lock sets are kind of sysv semaphore sets equivalent. The
  188. type is <structname>lock_set_t</structname>. Use them when you
  189. need a lot of mutexes. In some cases they waste less system
  190. resources than arrays of <structname>gen_lock_t</structname>
  191. (e.g. sys v semaphores).
  192. </simpara>
  193. <section id="sets.allocating">
  194. <title>Allocating And Initializing</title>
  195. <funcsynopsis>
  196. <funcprototype>
  197. <funcdef>lock_set_t* lock_set_alloc</funcdef>
  198. <paramdef><parameter>int no</parameter></paramdef>
  199. </funcprototype>
  200. <funcprototype>
  201. <funcdef>lock_set_t* lock_set_init</funcdef>
  202. <paramdef><parameter>lock_set_t* set</parameter></paramdef>
  203. </funcprototype>
  204. </funcsynopsis>
  205. <simpara>
  206. Both functions return 0 on failure.
  207. </simpara>
  208. <warning>
  209. <simpara>
  210. Expect the allocation function to fail for large
  211. numbers. It depends on the locking method used and the
  212. system available resources (again the sysv semaphores
  213. example).
  214. </simpara>
  215. </warning>
  216. <simpara>
  217. Example:
  218. </simpara>
  219. <programlisting>
  220. lock_set_t *lock_set;
  221. lock_set=lock_set_alloc(100);
  222. if (lock_set==0) goto error;
  223. if (lock_set_init(lock_set)==0){
  224. lock_set_dealloc(lock_set);
  225. goto error;
  226. }
  227. </programlisting>
  228. </section>
  229. <section id="sets.destroying">
  230. <title>Destroying And Deallocating</title>
  231. <funcsynopsis>
  232. <funcprototype>
  233. <funcdef>void <function>lock_set_destroy</function></funcdef>
  234. <paramdef><parameter>lock_set_t* s</parameter></paramdef>
  235. </funcprototype>
  236. <funcprototype>
  237. <funcdef>void <function>lock_set_dealloc</function></funcdef>
  238. <paramdef><parameter>lock_set_t* s</parameter></paramdef>
  239. </funcprototype>
  240. </funcsynopsis>
  241. <simpara>
  242. Again don't forget to "destroy" the locks.
  243. </simpara>
  244. </section>
  245. <section id="sets.locking">
  246. <title>Locking And Unlocking</title>
  247. <funcsynopsis>
  248. <funcprototype>
  249. <funcdef>void <function>lock_set_get</function></funcdef>
  250. <paramdef>
  251. <parameter>lock_set_t* s</parameter>
  252. <parameter>int i</parameter>
  253. </paramdef>
  254. </funcprototype>
  255. <funcprototype>
  256. <funcdef>void <function>lock_set_release</function></funcdef>
  257. <paramdef>
  258. <parameter>lock_set_t* s</parameter>
  259. <parameter>int i</parameter>
  260. </paramdef>
  261. </funcprototype>
  262. </funcsynopsis>
  263. <simpara>
  264. Example:
  265. </simpara>
  266. <programlisting>
  267. lock_set_get(lock_set, 2);
  268. /* do something */
  269. lock_set_release(lock_set, 2);
  270. </programlisting>
  271. </section>
  272. </section>
  273. </section>
  274. </section>