MultiPseudoStack.h (1768B)
1 /* 2 ZynAddSubFX - a software synthesizer 3 4 MultiPseudoStack.h - Multiple-Writer Lock Free Datastructure 5 Copyright (C) 2016 Mark McCurry 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License 9 as published by the Free Software Foundation; either version 2 10 of the License, or (at your option) any later version. 11 */ 12 #pragma once 13 #include <atomic> 14 15 namespace zyn { 16 17 //XXX rename this thing 18 typedef struct QueueListItem qli_t; 19 //! Queue item for LockFreeQueue 20 struct QueueListItem 21 { 22 QueueListItem(void); 23 char *memory; 24 uint32_t size; 25 }; 26 27 28 //! Many reader many writer queue of fixed size memory chunks 29 class LockFreeQueue 30 { 31 qli_t *const data; 32 const int elms; 33 std::atomic<uint32_t> *tag; 34 std::atomic<int32_t> next_r; 35 std::atomic<int32_t> next_w; 36 std::atomic<int32_t> avail; 37 public: 38 LockFreeQueue(qli_t *data_, int n); 39 ~LockFreeQueue(void); 40 qli_t *read(void); 41 void write(qli_t *Q); 42 }; 43 44 45 /** 46 * Many reader many writer capiable queue of fixed size memory chunks 47 * 48 * - lock free 49 * - allocation free (post initialization) 50 */ 51 class MultiQueue 52 { 53 qli_t *pool; //!< actual storage 54 LockFreeQueue m_free; //!< queue of unused items 55 LockFreeQueue m_msgs; //!< actual queue 56 57 public: 58 MultiQueue(void); 59 ~MultiQueue(void); 60 //! return a fresh item, e.g. to write to 61 qli_t *alloc(void) { return m_free.read(); } 62 //! free an item 63 void free(qli_t *q) { m_free.write(q); } 64 //! write item into the queue 65 void write(qli_t *q) { m_msgs.write(q); } 66 //! take an item from the queue, must be freed 67 qli_t *read(void) { return m_msgs.read(); } 68 }; 69 70 }