-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchan.h
252 lines (229 loc) · 5.78 KB
/
chan.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
* pthreadChannel - an implementation of channels for pthreads
* Copyright (C) 2016-2024 G. David Butler <gdb@dbSystems.com>
*
* This file is part of pthreadChannel
*
* pthreadChannel is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* pthreadChannel is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __CHAN_H__
#define __CHAN_H__
/*
* Channel Store
*/
/* Channel Store state */
typedef enum chanSs { /* bit map */
chanSsCanPut = 1 /* not full */
,chanSsCanGet = 2 /* not empty */
} chanSs_t;
/* Channel Store deallocation
* called during last (deallocating) chanClose
*
* takes:
* a pointer to a Store closure,
*/
typedef void
(*chanSd_t)(
void *storeClosure
,chanSs_t state
);
/* Channel Store operation */
typedef enum chanSo {
chanSoGet
,chanSoPut
} chanSo_t;
/* Channel Store wait */
typedef enum chanSw { /* bit map */
chanSwNoGet = 1 /* no waiting Gets */
,chanSwNoPut = 2 /* no waiting Puts */
} chanSw_t;
/* Channel Store implementation
* called to perform Store operation and release begin stablity
*
* takes:
* a pointer to a Store closure,
* the operation the Channel wants to perform on the Store
* indication of waiting Gets and Puts
* and a value pointer
* Return the state of the Store as it relates to Get and Put.
* if zero, shutdown the channel
*/
typedef chanSs_t
(*chanSi_t)(
void *storeClosure
,chanSo_t oper
,chanSw_t wait
,void **val
);
/* Channel Store allocation
* called to allocate a Channel Store
*
* receives:
* a realloc() like function (from chanCreate)
* a free() like function (from chanCreate)
* a Store item dequeue function (from chanCreate)
* a wake function
* a wake closure
*
* provides:
* a Store deallocation function or zero
* a Store implementation function
* a Store closure
*
* takes additioal specific arguments
*
* Return a Store state
* if zero, failed
*/
typedef chanSs_t
(*chanSa_t)(
void *(*realloc)(void *, unsigned long)
,void (*free)(void *)
,void (*dequeue)(void *)
,int (*wake)(void *, chanSs_t)
,void *wakeClosure
,chanSd_t *deallocation
,chanSi_t *implementation
,void **storeClosure
,va_list
);
/*
* Channel Init
*
* Must be called to provide thread safe realloc and free implementations
*/
void
chanInit(
void *(*realloc)(void *, unsigned long)
,void (*free)(void *)
);
/*
* Channel
*/
typedef struct chan chan_t;
/*
* A Store can be provided at Channel allocation.
* If none is provided, a Channel stores a single item.
* This works best (providing low latency) when threads work more and talk less.
*
* When allocating the Channel, supply:
* a Store item dequeue function (0 if none)
* a Store allocation function (0 if none)
* additional allocation parameters
*
* Return 0 on error (memory allocation)
* Returned Channel is Open.
*/
chan_t *
chanCreate(
void (*dequeue)(void *)
,chanSa_t allocation
,...
);
/* Channel (re)Open, to keep a Channel from being deallocated till chanClose */
/* Calling with 0 is a harmless no-op */
/* Return chn as a convience to allow: chanDup = chanOpen(chan) */
chan_t *
chanOpen(
chan_t *chn
);
/* Channel shutdown */
/* then chanOpPut returns chanOsSht and chanOpGet is non-blocking */
/* Calling with 0 is a harmless no-op */
void
chanShut(
chan_t *chn
);
/* Channel close, on last close, deallocate */
/* calling with 0 is a harmless no-op */
void
chanClose(
chan_t *chn
);
/* Channel number of chanOpen not yet chanClose (chanClose at zero deallocates) */
unsigned int
chanOpenCnt(
chan_t *chn
);
/* Channel operation */
typedef enum chanOp {
chanOpNop = 0 /* no operation, skip */
,chanOpSht /* monitor for Shutdown */
,chanOpGet /* Get or Get demand (queued Puts on full store) */
,chanOpPut /* Put or Put demand (queued Gets on empty store) */
} chanOp_t;
/* Channel operation status */
typedef enum chanOs {
chanOsNop = 0 /* None of the below */
,chanOsSht /* Shutdown */
,chanOsGet /* Get */
,chanOsPut /* Put */
,chanOsTmo /* Timeout */
} chanOs_t;
/*
* Operate on a Channel based on nsTimeout:
* >0 timeout in nanoseconds
* 0 block
* -1 non-blocking
* val is where to get/put an item or 0 for monitor
*/
chanOs_t
chanOp(
long nsTimeout
,chan_t *chan
,void **val
,chanOp_t op
);
/* Channel array */
typedef struct chanArr {
chan_t *c; /* channel to operate on, 0 == chanOpNop */
void **v; /* where to get/put or 0 for monitor */
void *x; /* application closure - not used by channels */
chanOp_t o;
chanOs_t s;
} chanArr_t;
/*
* Operate on one (first capable) Channal of a Channal array based on nsTimeout:
* >0 timeout in nanoseconds
* 0 block
* -1 non-blocking
* Return 0 on error (memory allocation failure).
* Otherwise the offset into the list is one less than the return value.
*/
unsigned int
chanOne(
long nsTimeout
,unsigned int count
,chanArr_t *array
);
/* chanAll status */
typedef enum chanAl {
chanAlErr = 0 /* memory allocation failure */
,chanAlEvt /* Event - check chanOs_t */
,chanAlOp /* Operation - check chanOs_t */
,chanAlTmo /* timeout */
} chanAl_t;
/*
* Operate on all Channals of a Channal array based on nsTimeout:
* >0 timeout in nanoseconds
* 0 block
* -1 non-blocking
*/
chanAl_t
chanAll(
long nsTimeout
,unsigned int count
,chanArr_t *array
);
#endif /* __CHAN_H__ */