1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #include "vchiq_util.h" |
29 | |
30 | #if !defined(__KERNEL__) |
31 | #include <stdlib.h> |
32 | #endif |
33 | |
34 | static __inline int is_pow2(int i) |
35 | { |
36 | return i && !(i & (i - 1)); |
37 | } |
38 | |
39 | int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size) |
40 | { |
41 | vcos_assert(is_pow2(size)); |
42 | |
43 | queue->size = size; |
44 | queue->read = 0; |
45 | queue->write = 0; |
46 | |
47 | vcos_event_create(&queue->pop, "vchiu" ); |
48 | vcos_event_create(&queue->push, "vchiu" ); |
49 | |
50 | queue->storage = vcos_malloc(size * sizeof(VCHIQ_HEADER_T *), VCOS_FUNCTION); |
51 | if (queue->storage == NULL) |
52 | { |
53 | vchiu_queue_delete(queue); |
54 | return 0; |
55 | } |
56 | return 1; |
57 | } |
58 | |
59 | void vchiu_queue_delete(VCHIU_QUEUE_T *queue) |
60 | { |
61 | vcos_event_delete(&queue->pop); |
62 | vcos_event_delete(&queue->push); |
63 | if (queue->storage != NULL) |
64 | vcos_free(queue->storage); |
65 | } |
66 | |
67 | int vchiu_queue_is_empty(VCHIU_QUEUE_T *queue) |
68 | { |
69 | return queue->read == queue->write; |
70 | } |
71 | |
72 | int vchiu_queue_is_full(VCHIU_QUEUE_T *queue) |
73 | { |
74 | return queue->write == queue->read + queue->size; |
75 | } |
76 | |
77 | void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *) |
78 | { |
79 | while (queue->write == queue->read + queue->size) |
80 | vcos_event_wait(&queue->pop); |
81 | |
82 | queue->storage[queue->write & (queue->size - 1)] = header; |
83 | |
84 | queue->write++; |
85 | |
86 | vcos_event_signal(&queue->push); |
87 | } |
88 | |
89 | VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue) |
90 | { |
91 | while (queue->write == queue->read) |
92 | vcos_event_wait(&queue->push); |
93 | |
94 | return queue->storage[queue->read & (queue->size - 1)]; |
95 | } |
96 | |
97 | VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue) |
98 | { |
99 | VCHIQ_HEADER_T *; |
100 | |
101 | while (queue->write == queue->read) |
102 | vcos_event_wait(&queue->push); |
103 | |
104 | header = queue->storage[queue->read & (queue->size - 1)]; |
105 | |
106 | queue->read++; |
107 | |
108 | vcos_event_signal(&queue->pop); |
109 | |
110 | return header; |
111 | } |
112 | |