@@ -17,18 +17,24 @@ int equeue_create(equeue_t *q, size_t size) {
1717    }
1818
1919    int  err  =  equeue_create_inplace (q , size , buffer );
20-     q -> buffer  =  buffer ;
20+     q -> allocated  =  buffer ;
2121    return  err ;
2222}
2323
2424int  equeue_create_inplace (equeue_t  * q , size_t  size , void  * buffer ) {
25+     q -> buffer  =  buffer ;
26+     q -> allocated  =  0 ;
27+ 
28+     q -> npw2  =  0 ;
29+     for  (unsigned  s  =  size ; s ; s  >>= 1 ) {
30+         q -> npw2 ++ ;
31+     }
32+ 
33+     q -> chunks  =  0 ;
2534    q -> slab .size  =  size ;
2635    q -> slab .data  =  buffer ;
27-     q -> chunks  =  0 ;
28-     q -> buffer  =  0 ;
2936
3037    q -> queue  =  0 ;
31-     q -> next_id  =  42 ;
3238    q -> break_  =  (struct  equeue_event ){
3339        .id  =  0 ,
3440        .period  =  -1 ,
@@ -45,7 +51,7 @@ int equeue_create_inplace(equeue_t *q, size_t size, void *buffer) {
4551        return  err ;
4652    }
4753
48-     err  =  equeue_mutex_create (& q -> freelock );
54+     err  =  equeue_mutex_create (& q -> memlock );
4955    if  (err  <  0 ) {
5056        return  err ;
5157    }
@@ -60,21 +66,18 @@ void equeue_destroy(equeue_t *q) {
6066        equeue_dealloc (q , e + 1 );
6167    }
6268
63-     equeue_mutex_destroy (& q -> freelock );
69+     equeue_mutex_destroy (& q -> memlock );
6470    equeue_mutex_destroy (& q -> queuelock );
6571    equeue_sema_destroy (& q -> eventsema );
66-     free (q -> buffer );
72+     free (q -> allocated );
6773}
6874
69- // equeue allocation functions 
70- static  void  * equeue_mem_alloc (equeue_t  * q , size_t  size ) {
71-     size  =  size  +  sizeof (unsigned );
72-     size  =  (size  +  sizeof (unsigned )-1 ) &  ~(sizeof (unsigned )-1 );
73-     if  (size  <  sizeof (struct  equeue_chunk )) {
74-         size  =  sizeof (struct  equeue_chunk );
75-     }
75+ // equeue chunk allocation functions 
76+ static  struct  equeue_event  * equeue_mem_alloc (equeue_t  * q , size_t  size ) {
77+     size  +=  sizeof (struct  equeue_event );
78+     size  =  (size  +  sizeof (void * )-1 ) &  ~(sizeof (void * )-1 );
7679
77-     equeue_mutex_lock (& q -> freelock );
80+     equeue_mutex_lock (& q -> memlock );
7881
7982    for  (struct  equeue_chunk  * * p  =  & q -> chunks ; * p ; p  =  & (* p )-> nchunk ) {
8083        if  ((* p )-> size  >= size ) {
@@ -85,8 +88,14 @@ static void *equeue_mem_alloc(equeue_t *q, size_t size) {
8588            } else  {
8689                * p  =  c -> nchunk ;
8790            }
88-             equeue_mutex_unlock (& q -> freelock );
89-             return  (unsigned  * )c  +  1 ;
91+ 
92+             c -> id  +=  1 ;
93+             if  (c -> id  >> (8 * sizeof (int )-1  -  q -> npw2 )) {
94+                 c -> id  =  1 ;
95+             }
96+ 
97+             equeue_mutex_unlock (& q -> memlock );
98+             return  (struct  equeue_event  * )c ;
9099        }
91100    }
92101
@@ -95,18 +104,20 @@ static void *equeue_mem_alloc(equeue_t *q, size_t size) {
95104        q -> slab .data  +=  size ;
96105        q -> slab .size  -=  size ;
97106        c -> size  =  size ;
98-         equeue_mutex_unlock (& q -> freelock );
99-         return  (unsigned  * )c  +  1 ;
107+         c -> id  =  1 ;
108+ 
109+         equeue_mutex_unlock (& q -> memlock );
110+         return  (struct  equeue_event  * )c ;
100111    }
101112
102-     equeue_mutex_unlock (& q -> freelock );
113+     equeue_mutex_unlock (& q -> memlock );
103114    return  0 ;
104115}
105116
106- static  void  equeue_mem_dealloc (equeue_t  * q , void  * e ) {
107-     struct  equeue_chunk  * c  =  (struct  equeue_chunk  * )(( unsigned   * ) e   -   1 ) ;
117+ static  void  equeue_mem_dealloc (equeue_t  * q , struct   equeue_event  * e ) {
118+     struct  equeue_chunk  * c  =  (struct  equeue_chunk  * )e ;
108119
109-     equeue_mutex_lock (& q -> freelock );
120+     equeue_mutex_lock (& q -> memlock );
110121
111122    struct  equeue_chunk  * * p  =  & q -> chunks ;
112123    while  (* p  &&  (* p )-> size  <  c -> size ) {
@@ -121,27 +132,17 @@ static void equeue_mem_dealloc(equeue_t *q, void *e) {
121132        c -> nchunk  =  * p ;
122133    }
123134    * p  =  c ;
124-     
125-     equeue_mutex_unlock (& q -> freelock );
126- }
127135
128- // event allocation functions 
129- static  inline  int  equeue_next_id (equeue_t  * q ) {
130-     int  id  =  q -> next_id ++ ;
131-     if  (q -> next_id  <  0 ) {
132-         q -> next_id  =  42 ;
133-     }
134-     return  id ;
136+     equeue_mutex_unlock (& q -> memlock );
135137}
136138
139+ // equeue allocation functions 
137140void  * equeue_alloc (equeue_t  * q , size_t  size ) {
138-     struct  equeue_event  * e  =  equeue_mem_alloc (q ,
139-             sizeof (struct  equeue_event ) +  size );
141+     struct  equeue_event  * e  =  equeue_mem_alloc (q , size );
140142    if  (!e ) {
141143        return  0 ;
142144    }
143145
144-     e -> id  =  equeue_next_id (q );
145146    e -> target  =  0 ;
146147    e -> period  =  -1 ;
147148    e -> dtor  =  0 ;
@@ -172,24 +173,23 @@ static void equeue_enqueue(equeue_t *q, struct equeue_event *e, unsigned ms) {
172173        p  =  & (* p )-> next ;
173174    }
174175
176+     e -> ref  =  p ;
175177    e -> next  =  * p ;
178+     if  (* p ) {
179+         (* p )-> ref  =  & e -> next ;
180+     }
176181    * p  =  e ;
177182}
178183
179- static  struct  equeue_event  * equeue_dequeue (equeue_t  * q , int  id ) {
180-     for  (struct  equeue_event  * * p  =  & q -> queue ; * p ; p  =  & (* p )-> next ) {
181-         if  ((* p )-> id  ==  id ) {
182-             struct  equeue_event  * e  =  * p ;
183-             * p  =  (* p )-> next ;
184-             return  e ;
185-         }
184+ static  void  equeue_dequeue (equeue_t  * q , struct  equeue_event  * e ) {
185+     if  (e -> next ) {
186+         e -> next -> ref  =  e -> ref ;
186187    }
187- 
188-     return  0 ;
188+     * e -> ref  =  e -> next ;
189189}
190190
191191static  int  equeue_post_in (equeue_t  * q , struct  equeue_event  * e , int  ms ) {
192-     int  id  =  e -> id ;
192+     int  id  =  ( e -> id  <<  q -> npw2 ) | (( unsigned  char   * ) e   -   q -> buffer ) ;
193193    if  (ms  <  0 ) {
194194        equeue_dealloc (q , e + 1 );
195195        return  id ;
@@ -211,13 +211,19 @@ int equeue_post(equeue_t *q, void (*cb)(void*), void *p) {
211211}
212212
213213void  equeue_cancel (equeue_t  * q , int  id ) {
214+     struct  equeue_event  * e  =  (struct  equeue_event  * )
215+             & q -> buffer [id  &  ((1  << q -> npw2 )- 1 )];
216+ 
214217    equeue_mutex_lock (& q -> queuelock );
215-     struct  equeue_event  * e  =  equeue_dequeue (q , id );
218+     if  (e -> id  !=  id  >> q -> npw2 ) {
219+         equeue_mutex_unlock (& q -> queuelock );
220+         return ;
221+     }
222+ 
223+     equeue_dequeue (q , e );
216224    equeue_mutex_unlock (& q -> queuelock );
217225
218-     if  (e ) {
219-         equeue_dealloc (q , e + 1 );
220-     }
226+     equeue_dealloc (q , e + 1 );
221227}
222228
223229void  equeue_break (equeue_t  * q ) {
@@ -248,6 +254,7 @@ void equeue_dispatch(equeue_t *q, int ms) {
248254            }
249255
250256            struct  equeue_event  * e  =  q -> queue ;
257+             e -> id  +=  1 ;
251258            q -> queue  =  e -> next ;
252259
253260            if  (e -> period  >= 0 ) {
0 commit comments