jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

439 lines
11KB

  1. /*
  2. Copyright (C) 2000 Paul Davis
  3. Copyright (C) 2003 Rohan Drape
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. ISO/POSIX C version of Paul Davis's lock free ringbuffer C++ code.
  16. This is safe for the case of one read thread and one write thread.
  17. */
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #ifdef USE_MLOCK
  21. #include <sys/mman.h>
  22. #endif /* USE_MLOCK */
  23. #include "JackCompilerDeps.h"
  24. /* Portable definitions for acquire and release fences */
  25. #if defined(_MSC_VER) && !defined(_M_AMD64) && !defined(_M_IX86) && !defined(_M_X64)
  26. /* Acquire and release fences are only necessary for
  27. * non-x86 systems. In fact, gcc will generate no
  28. * instructions for acq/rel fences on x86. Hence, we only
  29. * use MemoryBarrier() for non-x86 systems with msvc */
  30. #include <windows.h>
  31. #define JACK_ACQ_FENCE() MemoryBarrier()
  32. #define JACK_REL_FENCE() MemoryBarrier()
  33. #elif defined(__GNUC__)
  34. #ifdef __ATOMIC_ACQUIRE
  35. #define JACK_ACQ_FENCE() __atomic_thread_fence(__ATOMIC_ACQUIRE)
  36. #define JACK_REL_FENCE() __atomic_thread_fence(__ATOMIC_RELEASE)
  37. #else
  38. /* Fallback to the legacy __sync builtin (full memory fence) */
  39. #define JACK_ACQ_FENCE() __sync_synchronize()
  40. #define JACK_REL_FENCE() __sync_synchronize()
  41. #endif
  42. #else
  43. #define JACK_ACQ_FENCE()
  44. #define JACK_REL_FENCE()
  45. #endif
  46. typedef struct {
  47. char *buf;
  48. size_t len;
  49. }
  50. jack_ringbuffer_data_t ;
  51. typedef struct {
  52. char *buf;
  53. volatile size_t write_ptr;
  54. volatile size_t read_ptr;
  55. size_t size;
  56. size_t size_mask;
  57. int mlocked;
  58. }
  59. jack_ringbuffer_t ;
  60. LIB_EXPORT jack_ringbuffer_t *jack_ringbuffer_create(size_t sz);
  61. LIB_EXPORT void jack_ringbuffer_free(jack_ringbuffer_t *rb);
  62. LIB_EXPORT void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb,
  63. jack_ringbuffer_data_t *vec);
  64. LIB_EXPORT void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb,
  65. jack_ringbuffer_data_t *vec);
  66. LIB_EXPORT size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt);
  67. LIB_EXPORT size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt);
  68. LIB_EXPORT void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt);
  69. LIB_EXPORT size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb);
  70. LIB_EXPORT int jack_ringbuffer_mlock(jack_ringbuffer_t *rb);
  71. LIB_EXPORT void jack_ringbuffer_reset(jack_ringbuffer_t *rb);
  72. LIB_EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz);
  73. LIB_EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src,
  74. size_t cnt);
  75. void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt);
  76. size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb);
  77. /* Create a new ringbuffer to hold at least `sz' bytes of data. The
  78. actual buffer size is rounded up to the next power of two. */
  79. LIB_EXPORT jack_ringbuffer_t *
  80. jack_ringbuffer_create (size_t sz)
  81. {
  82. int power_of_two;
  83. jack_ringbuffer_t *rb;
  84. if ((rb = (jack_ringbuffer_t *) malloc (sizeof (jack_ringbuffer_t))) == NULL) {
  85. return NULL;
  86. }
  87. for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++);
  88. rb->size = 1 << power_of_two;
  89. rb->size_mask = rb->size;
  90. rb->size_mask -= 1;
  91. rb->write_ptr = 0;
  92. rb->read_ptr = 0;
  93. if ((rb->buf = (char *) malloc (rb->size)) == NULL) {
  94. free (rb);
  95. return NULL;
  96. }
  97. rb->mlocked = 0;
  98. return rb;
  99. }
  100. /* Free all data associated with the ringbuffer `rb'. */
  101. LIB_EXPORT void
  102. jack_ringbuffer_free (jack_ringbuffer_t * rb)
  103. {
  104. #ifdef USE_MLOCK
  105. if (rb->mlocked) {
  106. munlock (rb->buf, rb->size);
  107. }
  108. #endif /* USE_MLOCK */
  109. free (rb->buf);
  110. free (rb);
  111. }
  112. /* Lock the data block of `rb' using the system call 'mlock'. */
  113. LIB_EXPORT int
  114. jack_ringbuffer_mlock (jack_ringbuffer_t * rb)
  115. {
  116. #ifdef USE_MLOCK
  117. if (mlock (rb->buf, rb->size)) {
  118. return -1;
  119. }
  120. #endif /* USE_MLOCK */
  121. rb->mlocked = 1;
  122. return 0;
  123. }
  124. /* Reset the read and write pointers to zero. This is not thread
  125. safe. */
  126. LIB_EXPORT void
  127. jack_ringbuffer_reset (jack_ringbuffer_t * rb)
  128. {
  129. rb->read_ptr = 0;
  130. rb->write_ptr = 0;
  131. memset(rb->buf, 0, rb->size);
  132. }
  133. /* Reset the read and write pointers to zero. This is not thread
  134. safe. */
  135. LIB_EXPORT void
  136. jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz)
  137. {
  138. rb->size = sz;
  139. rb->size_mask = rb->size;
  140. rb->size_mask -= 1;
  141. rb->read_ptr = 0;
  142. rb->write_ptr = 0;
  143. }
  144. /* Return the number of bytes available for reading. This is the
  145. number of bytes in front of the read pointer and behind the write
  146. pointer. */
  147. LIB_EXPORT size_t
  148. jack_ringbuffer_read_space (const jack_ringbuffer_t * rb)
  149. {
  150. size_t w, r;
  151. w = rb->write_ptr; JACK_ACQ_FENCE();
  152. r = rb->read_ptr;
  153. if (w > r) {
  154. return w - r;
  155. } else {
  156. return (w - r + rb->size) & rb->size_mask;
  157. }
  158. }
  159. /* Return the number of bytes available for writing. This is the
  160. number of bytes in front of the write pointer and behind the read
  161. pointer. */
  162. LIB_EXPORT size_t
  163. jack_ringbuffer_write_space (const jack_ringbuffer_t * rb)
  164. {
  165. size_t w, r;
  166. w = rb->write_ptr;
  167. r = rb->read_ptr; JACK_ACQ_FENCE();
  168. if (w > r) {
  169. return ((r - w + rb->size) & rb->size_mask) - 1;
  170. } else if (w < r) {
  171. return (r - w) - 1;
  172. } else {
  173. return rb->size - 1;
  174. }
  175. }
  176. /* The copying data reader. Copy at most `cnt' bytes from `rb' to
  177. `dest'. Returns the actual number of bytes copied. */
  178. LIB_EXPORT size_t
  179. jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt)
  180. {
  181. size_t free_cnt;
  182. size_t cnt2;
  183. size_t to_read;
  184. size_t n1, n2;
  185. if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) {
  186. return 0;
  187. }
  188. to_read = cnt > free_cnt ? free_cnt : cnt;
  189. /* note: relaxed load here, rb->read_ptr cannot be
  190. * modified from writing thread */
  191. cnt2 = rb->read_ptr + to_read;
  192. if (cnt2 > rb->size) {
  193. n1 = rb->size - rb->read_ptr;
  194. n2 = cnt2 & rb->size_mask;
  195. } else {
  196. n1 = to_read;
  197. n2 = 0;
  198. }
  199. memcpy (dest, &(rb->buf[rb->read_ptr]), n1);
  200. JACK_REL_FENCE(); /* ensure pointer increment happens after copy */
  201. rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask;
  202. if (n2) {
  203. memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2);
  204. JACK_REL_FENCE(); /* ensure pointer increment happens after copy */
  205. rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask;
  206. }
  207. return to_read;
  208. }
  209. /* The copying data reader w/o read pointer advance. Copy at most
  210. `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes
  211. copied. */
  212. LIB_EXPORT size_t
  213. jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt)
  214. {
  215. size_t free_cnt;
  216. size_t cnt2;
  217. size_t to_read;
  218. size_t n1, n2;
  219. size_t tmp_read_ptr;
  220. tmp_read_ptr = rb->read_ptr;
  221. if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) {
  222. return 0;
  223. }
  224. to_read = cnt > free_cnt ? free_cnt : cnt;
  225. cnt2 = tmp_read_ptr + to_read;
  226. if (cnt2 > rb->size) {
  227. n1 = rb->size - tmp_read_ptr;
  228. n2 = cnt2 & rb->size_mask;
  229. } else {
  230. n1 = to_read;
  231. n2 = 0;
  232. }
  233. memcpy (dest, &(rb->buf[tmp_read_ptr]), n1);
  234. tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask;
  235. if (n2) {
  236. memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2);
  237. }
  238. return to_read;
  239. }
  240. /* The copying data writer. Copy at most `cnt' bytes to `rb' from
  241. `src'. Returns the actual number of bytes copied. */
  242. LIB_EXPORT size_t
  243. jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt)
  244. {
  245. size_t free_cnt;
  246. size_t cnt2;
  247. size_t to_write;
  248. size_t n1, n2;
  249. if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) {
  250. return 0;
  251. }
  252. to_write = cnt > free_cnt ? free_cnt : cnt;
  253. /* note: relaxed load here, rb->write_ptr cannot be
  254. * modified from reading thread */
  255. cnt2 = rb->write_ptr + to_write;
  256. if (cnt2 > rb->size) {
  257. n1 = rb->size - rb->write_ptr;
  258. n2 = cnt2 & rb->size_mask;
  259. } else {
  260. n1 = to_write;
  261. n2 = 0;
  262. }
  263. memcpy (&(rb->buf[rb->write_ptr]), src, n1);
  264. JACK_REL_FENCE(); /* ensure pointer increment happens after copy */
  265. rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask;
  266. if (n2) {
  267. memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2);
  268. JACK_REL_FENCE(); /* ensure pointer increment happens after copy */
  269. rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask;
  270. }
  271. return to_write;
  272. }
  273. /* Advance the read pointer `cnt' places. */
  274. LIB_EXPORT void
  275. jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt)
  276. {
  277. size_t tmp = (rb->read_ptr + cnt) & rb->size_mask;
  278. JACK_REL_FENCE(); /* ensure pointer increment happens after copy (by user) */
  279. rb->read_ptr = tmp;
  280. }
  281. /* Advance the write pointer `cnt' places. */
  282. LIB_EXPORT void
  283. jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt)
  284. {
  285. size_t tmp = (rb->write_ptr + cnt) & rb->size_mask;
  286. JACK_REL_FENCE(); /* ensure pointer increment happens after copy (by user) */
  287. rb->write_ptr = tmp;
  288. }
  289. /* The non-copying data reader. `vec' is an array of two places. Set
  290. the values at `vec' to hold the current readable data at `rb'. If
  291. the readable data is in one segment the second segment has zero
  292. length. */
  293. LIB_EXPORT void
  294. jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb,
  295. jack_ringbuffer_data_t * vec)
  296. {
  297. size_t free_cnt;
  298. size_t cnt2;
  299. size_t w, r;
  300. w = rb->write_ptr; JACK_ACQ_FENCE();
  301. r = rb->read_ptr;
  302. if (w > r) {
  303. free_cnt = w - r;
  304. } else {
  305. free_cnt = (w - r + rb->size) & rb->size_mask;
  306. }
  307. cnt2 = r + free_cnt;
  308. if (cnt2 > rb->size) {
  309. /* Two part vector: the rest of the buffer after the current write
  310. ptr, plus some from the start of the buffer. */
  311. vec[0].buf = &(rb->buf[r]);
  312. vec[0].len = rb->size - r;
  313. vec[1].buf = rb->buf;
  314. vec[1].len = cnt2 & rb->size_mask;
  315. } else {
  316. /* Single part vector: just the rest of the buffer */
  317. vec[0].buf = &(rb->buf[r]);
  318. vec[0].len = free_cnt;
  319. vec[1].len = 0;
  320. }
  321. }
  322. /* The non-copying data writer. `vec' is an array of two places. Set
  323. the values at `vec' to hold the current writeable data at `rb'. If
  324. the writeable data is in one segment the second segment has zero
  325. length. */
  326. LIB_EXPORT void
  327. jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb,
  328. jack_ringbuffer_data_t * vec)
  329. {
  330. size_t free_cnt;
  331. size_t cnt2;
  332. size_t w, r;
  333. w = rb->write_ptr;
  334. r = rb->read_ptr; JACK_ACQ_FENCE();
  335. if (w > r) {
  336. free_cnt = ((r - w + rb->size) & rb->size_mask) - 1;
  337. } else if (w < r) {
  338. free_cnt = (r - w) - 1;
  339. } else {
  340. free_cnt = rb->size - 1;
  341. }
  342. cnt2 = w + free_cnt;
  343. if (cnt2 > rb->size) {
  344. /* Two part vector: the rest of the buffer after the current write
  345. ptr, plus some from the start of the buffer. */
  346. vec[0].buf = &(rb->buf[w]);
  347. vec[0].len = rb->size - w;
  348. vec[1].buf = rb->buf;
  349. vec[1].len = cnt2 & rb->size_mask;
  350. } else {
  351. vec[0].buf = &(rb->buf[w]);
  352. vec[0].len = free_cnt;
  353. vec[1].len = 0;
  354. }
  355. }