3 Copyright (C) 2013 Paweł Dziepak
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "spsc_queue.h"
30 struct spsc_queue_block
{
31 struct spsc_queue_block
* next
;
36 static struct spsc_queue_block
* new_block()
38 struct spsc_queue_block
* block
;
40 = sizeof(struct spsc_queue_block
) + BLOCK_SIZE
* sizeof(void*);
43 retval
= posix_memalign((void**)&block
, sizeof(void*), block_size
);
54 int spsc_queue_init(struct spsc_queue
* queue
)
56 struct spsc_queue_block
* block
= new_block();
62 queue
->consumer
= block
;
63 queue
->producer
= block
;
68 void spsc_queue_destroy(struct spsc_queue
* queue
)
70 struct spsc_queue_block
* block
= queue
->consumer
;
71 struct spsc_queue_block
* next
;
79 queue
->consumer
= NULL
;
80 queue
->producer
= NULL
;
83 int spsc_queue_enqueue(struct spsc_queue
* queue
, void* object
)
85 struct spsc_queue_block
* block
;
89 block
= queue
->producer
;
90 consumer
= block
->consumer
;
92 if (block
->producer
- consumer
>= BLOCK_SIZE
) {
100 array
= (void**)&block
[1];
102 array
[block
->producer
& (BLOCK_SIZE
- 1)] = object
;
106 if (block
!= queue
->producer
) {
108 queue
->producer
->next
= block
;
109 queue
->producer
= block
;
115 void* spsc_queue_dequeue(struct spsc_queue
* queue
)
117 struct spsc_queue_block
* block
;
118 struct spsc_queue_block
* next
;
123 block
= queue
->consumer
;
127 producer
= block
->producer
;
129 if (producer
== block
->consumer
&& !next
)
132 if (producer
== block
->consumer
) {
133 queue
->consumer
= next
;
135 block
= queue
->consumer
;
138 array
= (void**)&block
[1];
139 object
= array
[block
->consumer
& (BLOCK_SIZE
- 1)];