Download
cyberslak
/lightsout
/channel.c
(View History)
cyberslak remove unused channel code | Latest amendment: 21 on 2025-03-15 |
1 | #include <stdlib.h> |
2 | #include "channel.h" |
3 | #include "util.h" |
4 | |
5 | struct channel { |
6 | Ptr* ringbuf; |
7 | size_t reader; |
8 | size_t writer; |
9 | size_t size; |
10 | size_t count; |
11 | }; |
12 | |
13 | channel* channel_open(size_t bufsize) { |
14 | channel* ch = xmalloc(sizeof(*ch)); |
15 | ch->ringbuf = xmalloc(bufsize * sizeof(Ptr)); |
16 | ch->reader = ch->writer = 0; |
17 | ch->size = bufsize; |
18 | ch->count = 0; |
19 | return ch; |
20 | } |
21 | |
22 | void channel_close(channel* ch) { |
23 | if (!ch) return; |
24 | free(ch->ringbuf); |
25 | free(ch); |
26 | } |
27 | |
28 | /* A channel is full if it is not empty and the reader |
29 | * and writer are at the same cell. */ |
30 | static inline bool channel_full(channel* ch) |
31 | { |
32 | return (ch->count && ch->reader == ch->writer); |
33 | } |
34 | |
35 | /* A channel is empty if count==0. */ |
36 | static inline bool channel_empty(channel* ch) |
37 | { |
38 | return ch->count == 0; |
39 | } |
40 | |
41 | short channel_send(channel* ch, Ptr data) |
42 | { |
43 | if (channel_full(ch)) |
44 | return -1; |
45 | |
46 | ch->ringbuf[ch->writer++] = data; |
47 | ch->count++; |
48 | |
49 | ch->writer %= ch->size; |
50 | |
51 | return 0; |
52 | } |
53 | |
54 | short channel_recv(channel* ch, Ptr* data) |
55 | { |
56 | if (channel_empty(ch)) |
57 | return -1; |
58 | |
59 | if (!data) |
60 | die("channel_recv: data == NULL"); |
61 | |
62 | *data = ch->ringbuf[ch->reader++]; |
63 | ch->count--; |
64 | ch->reader %= ch->size; |
65 | |
66 | return 0; |
67 | } |