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

ADT ast-experimental
Last change on this file since a805100 was be5f0a5, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Changed monitors to use the user_link instead of the ready_link

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