all
@@ -81,6 +81,7 @@ | ||
81 | 81 | throw(); |
82 | 82 | #endif |
83 | 83 | |
84 | +#define COMMA , | |
84 | 85 | #define NEW new (__FILE__,__LINE__) |
85 | 86 | #define thNEW(__type,__arg) (stdObject::refLock(),sPtr<__type>(NEW __type __arg,1)) |
86 | 87 |
@@ -48,6 +48,11 @@ | ||
48 | 48 | return (ptr != inp); |
49 | 49 | } |
50 | 50 | */ |
51 | + bool is_clear() { | |
52 | + if ( ptr == 0 ) | |
53 | + return 1; | |
54 | + return 0; | |
55 | + } | |
51 | 56 | operator __TYPE *() const { |
52 | 57 | return ptr; |
53 | 58 | } |
@@ -4,70 +4,430 @@ | ||
4 | 4 | #ifndef ___stdArrayQueue_cpp_H___ |
5 | 5 | #define ___stdArrayQueue_cpp_H___ |
6 | 6 | |
7 | +#include <pthread.h> | |
7 | 8 | |
9 | +#define AQE_OK 0 | |
10 | +#define AQE_ERROR (-1) | |
11 | + | |
12 | +#define AQ_EMPTY (-1) | |
13 | +#define AQ_INS (-2) | |
14 | + | |
15 | +#define AQ_SIZE (sizeof(int)*8) | |
16 | + | |
17 | + | |
18 | +#define sAQ_INIT 0 | |
19 | +#define sAQ_DETACH 1 | |
20 | +#define sAQ_ATTACH 2 | |
21 | + | |
8 | 22 | template <class __TYPE> |
23 | +class sAQindex; | |
24 | + | |
25 | + | |
26 | +template <class __TYPE> | |
9 | 27 | class stdArrayQueue : public stdObject { |
28 | + | |
29 | + friend class sAQindex<__TYPE>; | |
10 | 30 | public: |
11 | 31 | stdArrayQueue(int len) { |
12 | - REF_SET(a,(NEW stdArray<__TYPE,false>(len))); | |
13 | - head = tail = 0; | |
32 | + initial(len); | |
14 | 33 | } |
34 | + stdArrayQueue(stdArrayQueue<__TYPE> * inp) { | |
35 | + initial(inp->length()); | |
36 | + | |
37 | + int i; | |
38 | + lock(); | |
39 | + tail = inp->tail; | |
40 | + head = inp->head; | |
41 | + for ( i = 0 ; i < a->length() ; i ++ ) { | |
42 | + a->ary[i] = inp->a->ary[i]; | |
43 | + ix->ary[i] = inp->ix->ary[i]; | |
44 | + } | |
45 | + unlock(); | |
46 | + } | |
15 | 47 | ~stdArrayQueue() { |
16 | - REF_SET(a,0); | |
48 | + a = 0; | |
49 | + ix = 0; | |
50 | + pthread_mutex_destroy(&mu); | |
51 | + pthread_cond_destroy(&cond); | |
17 | 52 | } |
53 | + | |
54 | + int count() { | |
55 | + int ret; | |
56 | + lock(); | |
57 | + ret = i_count(); | |
58 | + unlock(); | |
59 | + return ret; | |
60 | + } | |
61 | + void length(int len) { | |
62 | + lock(); | |
63 | + i_length(len); | |
64 | + unlock(); | |
65 | + } | |
18 | 66 | int length() { |
19 | 67 | return a->length(); |
20 | 68 | } |
21 | - int count() { | |
22 | - return _count; | |
69 | + | |
70 | +protected: | |
71 | + int i_count() { | |
72 | + return head - tail; | |
23 | 73 | } |
24 | - void length(int len) { | |
74 | + void i_length(int len) { | |
25 | 75 | int i,j,ncount; |
26 | - n = NEW stdArray<__TYPE,false>(len); | |
27 | - if ( count < len ) | |
28 | - ncount = _count(); | |
29 | - else ncount = len; | |
30 | - j = 0; | |
31 | - i = -ncount; | |
32 | - for ( ; i < 0 ; i ++ , j ++ ) | |
33 | - n->ary[j] = get(i); | |
34 | - REF_SET(a,n); | |
35 | - tail = 0; | |
36 | - head = ncount; | |
37 | - _count = ncount; | |
76 | + sPtr<stdArray<__TYPE,false> > n; | |
77 | + sPtr<stdArray<int,false> > nix; | |
78 | + len = regular_length(len); | |
79 | + n = thNEW(stdArray<__TYPE COMMA false>, (len)); | |
80 | + nix = thNEW(stdArray<int COMMA false>, (len)); | |
81 | + if ( count() < len ) | |
82 | + ncount = count(); | |
83 | + else { | |
84 | + ncount = len; | |
85 | + for ( ; count() > len ; ) | |
86 | + del(); | |
87 | + } | |
88 | + for ( i = tail ; i != head ; ) { | |
89 | + n->ary[i%n->length()] = a->ary[i%a->length()]; | |
90 | + nix->ary[i%n->length()] = ix->ary[i%a->length()]; | |
91 | + i ++; | |
92 | + } | |
93 | + a = n; | |
94 | + ix = nix; | |
38 | 95 | } |
39 | - __TYPE * ins() { | |
40 | - __TYPE ret; | |
41 | - _count ++; | |
42 | - ret = &a->ary[head++]; | |
43 | - if ( head >= a->length() ) | |
44 | - head = 0; | |
45 | - if ( head != tail ) { | |
46 | - return ret; | |
47 | - } | |
48 | - del(); | |
96 | + int regular_length(int len) { | |
97 | + int i; | |
98 | + for ( i = 0 ; i < AQ_SIZE-1 ; i ++ ) | |
99 | + if ( len <= (1<<i) ) | |
100 | + break; | |
101 | + return 1<<i; | |
102 | + } | |
103 | + void initial(int len) { | |
104 | + int i; | |
105 | + len = regular_length(len); | |
106 | + a = thNEW(stdArray<__TYPE COMMA false> , (len)); | |
107 | + ix = thNEW(stdArray<int COMMA false>, (len)); | |
108 | + for ( i = 0 ; i < len ; i ++ ) | |
109 | + ix->ary[i] = AQ_EMPTY; | |
110 | + head = tail = 0; | |
111 | + | |
112 | + pthread_mutex_init(&mu,0); | |
113 | + pthread_cond_init(&cond,0); | |
114 | + } | |
115 | + __TYPE * get(unsigned int pos) { | |
116 | + return &a->ary[pos%a->length()]; | |
117 | + } | |
118 | + | |
119 | + | |
120 | + unsigned int ins() { | |
121 | + int ret; | |
122 | + if ( count() == a->length() ) | |
123 | + del(); | |
124 | + ret = head ++; | |
125 | + ix->ary[ret] = AQ_INS; | |
49 | 126 | return ret; |
50 | 127 | } |
51 | - void del() { | |
52 | - _count --; | |
128 | + int del() { | |
129 | + if ( count() == 0 ) | |
130 | + return AQE_ERROR; | |
131 | + for ( ; ix->ary[tail] ; ) { | |
132 | + wait_count ++; | |
133 | + pthread_cond_wait(&cond,&mu); | |
134 | + lock(); | |
135 | + } | |
53 | 136 | tail ++; |
54 | - if ( tail >= a->length() ) | |
55 | - tail = 0; | |
137 | + return 0; | |
56 | 138 | } |
57 | - __TYPE * get(int pos=-1) { | |
58 | - if ( pos >= 0 ) | |
139 | + int attach(unsigned int p) { | |
140 | + for ( ; ; ) { | |
141 | + if ( head < tail ) { | |
142 | + if ( head <= p && p < tail ) | |
143 | + return AQE_ERROR; | |
144 | + } | |
145 | + else if ( !(head <= p && p < tail) ) | |
146 | + return AQE_ERROR; | |
147 | + if ( ix->ary[p] >= 0 ) | |
148 | + break; | |
149 | + wait_count ++; | |
150 | + pthread_cond_wait(&cond,&mu); | |
151 | + lock(); | |
152 | + } | |
153 | + ix->ary[p] ++; | |
154 | + return 0; | |
155 | + } | |
156 | + int detach(unsigned int p) { | |
157 | + if ( p < 0 ) | |
59 | 158 | return 0; |
60 | - if ( pos < -_count ) | |
159 | + if ( head < tail ) { | |
160 | + if ( head <= p && p < tail ) | |
161 | + return AQE_ERROR; | |
162 | + } | |
163 | + else if ( !(head <= p && p < tail) ) | |
164 | + return AQE_ERROR; | |
165 | + if ( ix->ary[p] == 0 ) | |
166 | + return AQE_ERROR; | |
167 | + if ( ix->ary[p] == AQ_INS ) { | |
168 | + ix->ary[p] = 0; | |
169 | + } | |
170 | + else { | |
171 | + ix->ary[p] --; | |
172 | + } | |
173 | + if ( ix->ary[p] == 0 ) { | |
174 | + for ( ; wait_count > 0 ; wait_count -- ) | |
175 | + pthread_cond_signal(&cond); | |
176 | + } | |
177 | + return 0; | |
178 | + } | |
179 | + | |
180 | + void lock() { | |
181 | + pthread_mutex_lock(&mu); | |
182 | + } | |
183 | + void unlock() { | |
184 | + pthread_mutex_unlock(&mu); | |
185 | + } | |
186 | + | |
187 | + sPtr<stdArray<__TYPE,false> > a; | |
188 | + sPtr<stdArray<int,false> > ix; | |
189 | + unsigned int head; | |
190 | + unsigned int tail; | |
191 | + | |
192 | + pthread_mutex_t mu; | |
193 | + pthread_cond_t cond; | |
194 | + int wait_count; | |
195 | +}; | |
196 | + | |
197 | + | |
198 | +template <class __TYPE> | |
199 | +class sAQindex : public sObject { | |
200 | +public: | |
201 | + sAQindex() { | |
202 | + pos = 0; | |
203 | + ptr = 0; | |
204 | + } | |
205 | + sAQindex(sPtr<stdArrayQueue<__TYPE> > aa) { | |
206 | + pos = 0; | |
207 | + ptr = 0; | |
208 | + a = aa; | |
209 | + } | |
210 | + sAQindex(const sAQindex & inp) { | |
211 | + a = inp.a; | |
212 | + pos = 0; | |
213 | + ptr = 0; | |
214 | + a->lock(); | |
215 | + pos = inp.pos; | |
216 | + attach(); | |
217 | + a->unlock(); | |
218 | + } | |
219 | + ~sAQindex() { | |
220 | + a->lock(); | |
221 | + detach(); | |
222 | + a->unlock(); | |
223 | + } | |
224 | + int status() { | |
225 | + if ( a.is_clear() ) | |
226 | + return sAQ_INIT; | |
227 | + if ( ptr == 0 ) | |
228 | + return sAQ_DETACH; | |
229 | + return sAQ_ATTACH; | |
230 | + } | |
231 | + void set(sPtr<stdArrayQueue<__TYPE> > aa) { | |
232 | + a = aa; | |
233 | + } | |
234 | + | |
235 | + __TYPE * get_ptr() { | |
236 | + return ptr; | |
237 | + } | |
238 | + void clear() { | |
239 | + a->lock(); | |
240 | + detach(); | |
241 | + a->unlock(); | |
242 | + } | |
243 | + int is_tail() { | |
244 | + if ( pos == a->tail ) | |
245 | + return 1; | |
246 | + return 0; | |
247 | + } | |
248 | + int is_head() { | |
249 | + if ( pos == a->head ) | |
250 | + return 1; | |
251 | + return 0; | |
252 | + } | |
253 | + int number() { | |
254 | + return pos - a->tail; | |
255 | + } | |
256 | + | |
257 | + int tail() { | |
258 | + int ret; | |
259 | + a->lock(); | |
260 | + ret = i_tail(); | |
261 | + a->unlock(); | |
262 | + return ret; | |
263 | + } | |
264 | + int i_tail() { | |
265 | + detach(); | |
266 | + pos = a->tail; | |
267 | + attach(); | |
268 | + return 0; | |
269 | + } | |
270 | + int head() { | |
271 | + int ret; | |
272 | + a->lock(); | |
273 | + ret = i_head(); | |
274 | + a->unlock(); | |
275 | + return ret; | |
276 | + } | |
277 | + int i_head() { | |
278 | + if ( a->count() == 0 ) | |
279 | + return AQE_ERROR; | |
280 | + detach(); | |
281 | + pos = a->head-1; | |
282 | + attach(); | |
283 | + return 0; | |
284 | + } | |
285 | + int ins() { | |
286 | + int ret; | |
287 | + a->lock(); | |
288 | + ret = i_ins(); | |
289 | + a->unlock(); | |
290 | + return ret; | |
291 | + } | |
292 | + int i_ins() { | |
293 | + int ret; | |
294 | + ret = a->ins(); | |
295 | + if ( ret < 0 ) | |
296 | + return AQE_ERROR; | |
297 | + detach(); | |
298 | + pos = a->head; | |
299 | + return 0; | |
300 | + } | |
301 | + int del() { | |
302 | + int ret; | |
303 | + a->lock(); | |
304 | + ret = i_del(); | |
305 | + a->unlock(); | |
306 | + return ret; | |
307 | + } | |
308 | + int i_del() { | |
309 | + int ret; | |
310 | + if ( pos == a->tail ) | |
311 | + detach(); | |
312 | + return a->del(); | |
313 | + } | |
314 | + sAQindex& operator=(sAQindex inp) { | |
315 | + a = inp.a; | |
316 | + a->lock(); | |
317 | + pos = inp.pos; | |
318 | + attach(); | |
319 | + a->unlock(); | |
320 | + return *this; | |
321 | + } | |
322 | + int operator - (sAQindex inp) const { | |
323 | + return pos - inp.pos; | |
324 | + } | |
325 | + sAQindex operator + (int inp) const { | |
326 | + sAQindex ret(a); | |
327 | + ret.pos = pos + inp; | |
328 | + a->lock(); | |
329 | + ret.attach(); | |
330 | + a->unlock(); | |
331 | + return ret; | |
332 | + } | |
333 | + sAQindex operator - (int inp) const { | |
334 | + sAQindex ret(a); | |
335 | + ret.pos = pos - inp; | |
336 | + a->lock(); | |
337 | + ret.attach(); | |
338 | + a->unlock(); | |
339 | + return ret; | |
340 | + } | |
341 | + sAQindex & operator += (int inp) { | |
342 | + a->lock(); | |
343 | + detach(); | |
344 | + pos += inp; | |
345 | + attach(); | |
346 | + a->unlock(); | |
347 | + return *this; | |
348 | + } | |
349 | + sAQindex & operator ++ () { | |
350 | + a->lock(); | |
351 | + detach(); | |
352 | + pos ++; | |
353 | + attach(); | |
354 | + a->unlock(); | |
355 | + return *this; | |
356 | + } | |
357 | + sAQindex operator ++ (int) { | |
358 | + sAQindex<__TYPE> ret; | |
359 | + ret = *this; | |
360 | + a->lock(); | |
361 | + detach(); | |
362 | + pos ++; | |
363 | + attach(); | |
364 | + a->unlock(); | |
365 | + return ret; | |
366 | + } | |
367 | + sAQindex & operator -= (int inp) { | |
368 | + a->lock(); | |
369 | + detach(); | |
370 | + pos -= inp; | |
371 | + attach(); | |
372 | + a->unlock(); | |
373 | + return *this; | |
374 | + } | |
375 | + sAQindex & operator -- (int inp) { | |
376 | + a->lock(); | |
377 | + detach(); | |
378 | + pos --; | |
379 | + attach(); | |
380 | + a->unlock(); | |
381 | + return *this; | |
382 | + } | |
383 | + bool operator == (sAQindex inp) const { | |
384 | + return (pos == inp.pos); | |
385 | + } | |
386 | + bool operator != (sAQindex inp) const { | |
387 | + return (pos != inp.pos); | |
388 | + } | |
389 | + bool operator <= (sAQindex inp) const { | |
390 | + return (pos - a->tail <= inp.pos - a->tail); | |
391 | + } | |
392 | + bool operator < (sAQindex inp) const { | |
393 | + return (pos - a->tail < inp.pos - a->tail); | |
394 | + } | |
395 | + bool operator >= (sAQindex inp) const { | |
396 | + return (pos - a->tail >= inp.pos - a->tail); | |
397 | + } | |
398 | + bool operator > (sAQindex inp) const { | |
399 | + return (pos - a->tail > inp.pos - a->tail); | |
400 | + } | |
401 | + __TYPE * operator -> () const { | |
402 | + return ptr; | |
403 | + } | |
404 | + __TYPE & operator * () const { | |
405 | + return *ptr; | |
406 | + } | |
407 | +protected: | |
408 | + sPtr<stdArrayQueue<__TYPE> > a; | |
409 | + int pos; | |
410 | + __TYPE * ptr; | |
411 | + | |
412 | + int attach() { | |
413 | + int ret; | |
414 | + if ( ptr ) | |
61 | 415 | return 0; |
62 | - pos = head + pos; | |
63 | - for ( ; pos < 0 ; pos += a->length() ); | |
64 | - return a->ary[pos]; | |
416 | + ret = a->attach(pos); | |
417 | + if ( ret == 0 ) | |
418 | + ptr = a->get(pos); | |
419 | + else ptr = 0; | |
420 | + return ret; | |
65 | 421 | } |
66 | -protected: | |
67 | - stdArray<__TYPE,false> * a; | |
68 | - int head; | |
69 | - int tail; | |
70 | - int _count; | |
422 | + int detach() { | |
423 | + if ( ptr == 0 ) | |
424 | + return 0; | |
425 | + a->detach(pos); | |
426 | + ptr = 0; | |
427 | + return 0; | |
428 | + } | |
71 | 429 | }; |
72 | 430 | |
431 | + | |
432 | + | |
73 | 433 | #endif |