source: libcfa/src/bits/containers.hfa @ ecfe574

ADTast-experimental
Last change on this file since ecfe574 was be5f0a5, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Changed monitors to use the user_link instead of the ready_link

  • Property mode set to 100644
File size: 6.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// bits/containers.hfa -- Intrusive generic containers.hfa
8//
9// Author           : Thierry Delisle
10// Created On       : Tue Oct 31 16:38:50 2017
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Jan 15 07:42:35 2020
13// Update Count     : 28
14
15#pragma once
16
17#include "bits/align.hfa"
18#include "bits/defs.hfa"
19#include <stdio.h>
20//-----------------------------------------------------------------------------
21// Array
22//-----------------------------------------------------------------------------
23
24#ifdef __cforall
25        forall(T &)
26#else
27        #define T void
28#endif
29struct __small_array {
30        T *           data;
31        __lock_size_t size;
32};
33#undef T
34
35#ifdef __cforall
36        #define __small_array_t(T) __small_array(T)
37#else
38        #define __small_array_t(T) __small_array
39#endif
40
41#ifdef __cforall
42        // forall(T | sized(T))
43        // static inline void ?{}(__small_array(T) & this) {}
44
45        forall(T & | sized(T))
46        static inline T & ?[?]( __small_array(T) & this, __lock_size_t idx ) {
47                return ((typeof(this.data))this.data)[idx];
48        }
49
50        forall(T & | sized(T))
51        static inline T & ?[?]( const __small_array(T) & this, __lock_size_t idx ) {
52                return ((typeof(this.data))this.data)[idx];
53        }
54
55        forall(T &)
56        static inline T * begin( const __small_array(T) & this ) {
57                return ((typeof(this.data))this.data);
58        }
59
60        forall(T & | sized(T))
61        static inline T * end( const __small_array(T) & this ) {
62                return ((typeof(this.data))this.data) + this.size;
63        }
64#endif
65
66//-----------------------------------------------------------------------------
67// Node Base
68//-----------------------------------------------------------------------------
69
70#ifdef __cforall
71        trait is_node(T &) {
72                T *& get_next( T & );
73        };
74#endif
75
76//-----------------------------------------------------------------------------
77// Stack
78//-----------------------------------------------------------------------------
79#ifdef __cforall
80        forall(TYPE &)
81        #define T TYPE
82#else
83        #define T void
84#endif
85struct __stack {
86        T * top;
87};
88#undef T
89
90#ifdef __cforall
91#define __stack_t(T) __stack(T)
92#else
93#define __stack_t(T) struct __stack
94#endif
95
96#ifdef __cforall
97        forall(T &)
98        static inline void ?{}( __stack(T) & this ) {
99                (this.top){ 0p };
100        }
101
102        static inline forall( T & | is_node(T) ) {
103                void push( __stack(T) & this, T * val ) {
104                        verify( !get_next( *val ) );
105                        get_next( *val ) = this.top;
106                        this.top = val;
107                }
108
109                T * pop( __stack(T) & this ) {
110                        T * top = this.top;
111                        if( top ) {
112                                this.top = get_next( *top );
113                                get_next( *top ) = 0p;
114                        }
115                        return top;
116                }
117
118                int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
119                        return this.top != 0;
120                }
121        }
122#endif
123
124//-----------------------------------------------------------------------------
125// Queue
126//-----------------------------------------------------------------------------
127#ifdef __cforall
128        forall(TYPE &)
129        #define T TYPE
130#else
131        #define T void
132#endif
133struct __queue {
134        T * head;
135        T ** tail;
136};
137#undef T
138
139#ifdef __cforall
140#define __queue_t(T) __queue(T)
141#else
142#define __queue_t(T) struct __queue
143#endif
144
145#ifdef __cforall
146        static inline forall( T & | is_node(T) ) {
147                void ?{}( __queue(T) & this ) with( this ) {
148                        (this.head){ 1p };
149                        (this.tail){ &this.head };
150                        verify(*this.tail == 1p);
151                }
152
153                void append( __queue(T) & this, T * val ) with(this) {
154                        verify(get_next( *val ) == 0p);
155                        verify(this.tail != 0p);
156                        verify(*this.tail == 1p);
157                        *this.tail = val;
158                        this.tail = &get_next( *val );
159                        *this.tail = 1p;
160                }
161
162                T * peek( __queue(T) & this ) {
163                        verify(*this.tail == 1p);
164                        T * frontnode = this.head;
165                        if( frontnode != 1p ) {
166                                verify(*this.tail == 1p);
167                                return frontnode;
168                        }
169                        verify(*this.tail == 1p);
170                        return 0p;
171                }
172
173                T * pop_head( __queue(T) & this ) {
174                        verify(*this.tail == 1p);
175                        T * _head = this.head;
176                        if( _head != 1p ) {
177                                this.head = get_next( *_head );
178                                if( get_next( *_head ) == 1p ) {
179                                        this.tail = &this.head;
180                                }
181                                get_next( *_head ) = 0p;
182                                verify(*this.tail == 1p);
183                                verify( get_next(*_head) == 0p );
184                                return _head;
185                        }
186                        verify(*this.tail == 1p);
187                        return 0p;
188                }
189
190                T * remove( __queue(T) & this, T ** it ) with( this ) {
191                        T * val = *it;
192                        verify( val );
193
194                        (*it) = get_next( *val );
195
196                        if( this.tail == &get_next( *val ) ) {
197                                this.tail = it;
198                        }
199
200                        get_next( *val ) = 0p;
201
202                        verify( (this.head == 1p) == (&this.head == this.tail) );
203                        verify( *this.tail == 1p );
204                        return val;
205                }
206
207                int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
208                        return this.head != 1p;
209                }
210        }
211#endif
212
213
214//-----------------------------------------------------------------------------
215// Doubly Linked List
216//-----------------------------------------------------------------------------
217#ifdef __cforall
218        forall(TYPE &)
219        #define T TYPE
220        #define __getter_t * [T * & next, T * & prev] ( T & )
221#else
222        typedef void (*__generit_c_getter_t)();
223        #define T void
224        #define __getter_t __generit_c_getter_t
225#endif
226struct __dllist {
227        T * head;
228        __getter_t __get;
229};
230#undef T
231#undef __getter_t
232
233#ifdef __cforall
234#define __dllist_t(T) __dllist(T)
235#else
236#define __dllist_t(T) struct __dllist
237#endif
238
239#ifdef __cforall
240        forall(T & )
241        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
242                (this.head){ 0p };
243                this.__get = __get;
244        }
245
246        #define next 0
247        #define prev 1
248        static inline forall(T &) {
249                void push_front( __dllist(T) & this, T & node ) with( this ) {
250                        verify(__get);
251                        if ( this.head ) {
252                                __get( node ).next = this.head;
253                                __get( node ).prev = __get( *this.head ).prev;
254                                // inserted node must be consistent before it is seen
255                                // prevent code movement across barrier
256                                asm( "" : : : "memory" );
257                                __get( *this.head ).prev = &node;
258                                T & _prev = *__get( node ).prev;
259                                __get( _prev ).next = &node;
260                        } else {
261                                __get( node ).next = &node;
262                                __get( node ).prev = &node;
263                        }
264
265                        // prevent code movement across barrier
266                        asm( "" : : : "memory" );
267                        this.head = &node;
268                }
269
270                void remove( __dllist(T) & this, T & node ) with( this ) {
271                        verify(__get);
272                        if ( &node == this.head ) {
273                                if ( __get( *this.head ).next == this.head ) {
274                                        this.head = 0p;
275                                } else {
276                                        this.head = __get( *this.head ).next;
277                                }
278                        }
279                        __get( *__get( node ).next ).prev = __get( node ).prev;
280                        __get( *__get( node ).prev ).next = __get( node ).next;
281                        __get( node ).next = 0p;
282                        __get( node ).prev = 0p;
283                }
284
285                int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
286                        return this.head != 0;
287                }
288
289                void move_to_front( __dllist(T) & src, __dllist(T) & dst, T & node ) {
290                        remove    (src, node);
291                        push_front(dst, node);
292                }
293        }
294        #undef next
295        #undef prev
296#endif
297
298//-----------------------------------------------------------------------------
299// Tools
300//-----------------------------------------------------------------------------
301#ifdef __cforall
302
303#endif
304
305// Local Variables: //
306// tab-width: 4 //
307// End: //
Note: See TracBrowser for help on using the repository browser.