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

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since e6cfa8ff was 3381ed7, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Added park/unpark primitives thread and removed BlockInternal.
Converted monitors to use park unpark.
Intrusive Queue now mark next field when thread is inside queue.
Added several asserts to kernel and monitor.
Added a few tests for park and unpark.

  • Property mode set to 100644
File size: 6.4 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"
[ea7d2b0]19
[0cf5b79]20//-----------------------------------------------------------------------------
21// Array
22//-----------------------------------------------------------------------------
23
24#ifdef __cforall
25 forall(dtype 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) struct __small_array
39#endif
40
41#ifdef __cforall
42 // forall(otype T | sized(T))
43 // static inline void ?{}(__small_array(T) & this) {}
44
45 forall(dtype 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
50 forall(dtype 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
[768bd556]55 forall(dtype T)
56 static inline T * begin( const __small_array(T) & this ) {
[0cf5b79]57 return ((typeof(this.data))this.data);
58 }
59
60 forall(dtype 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
[ea7d2b0]71 trait is_node(dtype T) {
[768bd556]72 T *& get_next( T & );
[ea7d2b0]73 };
74#endif
75
76//-----------------------------------------------------------------------------
77// Stack
78//-----------------------------------------------------------------------------
[0cf5b79]79#ifdef __cforall
[3623f9d]80 forall(dtype 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
[3623f9d]97 forall(dtype T)
[0cf5b79]98 static inline void ?{}( __stack(T) & this ) {
[768bd556]99 (this.top){ 0p };
[ea7d2b0]100 }
101
[768bd556]102 static inline forall( dtype 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 }
[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
[3623f9d]128 forall(dtype 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
[768bd556]146 static inline forall( dtype T | is_node(T) ) {
147 void ?{}( __queue(T) & this ) with( this ) {
[3381ed7]148 head{ 1p };
[768bd556]149 tail{ &head };
[3381ed7]150 verify(*tail == 1p);
[768bd556]151 }
[65deb18]152
[768bd556]153 void append( __queue(T) & this, T * val ) with( this ) {
154 verify(tail != 0p);
[3381ed7]155 verify(*tail == 1p);
[768bd556]156 *tail = val;
157 tail = &get_next( *val );
[3381ed7]158 *tail = 1p;
[768bd556]159 }
[ea7d2b0]160
[768bd556]161 T * pop_head( __queue(T) & this ) {
[3381ed7]162 verify(*this.tail == 1p);
[768bd556]163 T * head = this.head;
[3381ed7]164 if( head != 1p ) {
[768bd556]165 this.head = get_next( *head );
[3381ed7]166 if( get_next( *head ) == 1p ) {
[768bd556]167 this.tail = &this.head;
168 }
169 get_next( *head ) = 0p;
[3381ed7]170 verify(*this.tail == 1p);
171 return head;
[ea7d2b0]172 }
[3381ed7]173 verify(*this.tail == 1p);
174 return 0p;
[ea7d2b0]175 }
176
[768bd556]177 T * remove( __queue(T) & this, T ** it ) with( this ) {
178 T * val = *it;
179 verify( val );
[ea7d2b0]180
[768bd556]181 (*it) = get_next( *val );
[ea7d2b0]182
[768bd556]183 if( tail == &get_next( *val ) ) {
184 tail = it;
185 }
[ea7d2b0]186
[768bd556]187 get_next( *val ) = 0p;
[ea7d2b0]188
[3381ed7]189 verify( (head == 1p) == (&head == tail) );
190 verify( *tail == 1p );
[768bd556]191 return val;
192 }
[8ebbfc4]193
[768bd556]194 int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
195 return this.head != 0;
196 }
[8ebbfc4]197 }
[ea7d2b0]198#endif
[65deb18]199
[14a61b5]200
201//-----------------------------------------------------------------------------
202// Doubly Linked List
203//-----------------------------------------------------------------------------
204#ifdef __cforall
[ffe2fad]205 forall(dtype TYPE)
[14a61b5]206 #define T TYPE
[705e612]207 #define __getter_t * [T * & next, T * & prev] ( T & )
[14a61b5]208#else
[705e612]209 typedef void (*__generit_c_getter_t)();
[14a61b5]210 #define T void
[705e612]211 #define __getter_t __generit_c_getter_t
[14a61b5]212#endif
213struct __dllist {
214 T * head;
[705e612]215 __getter_t __get;
[14a61b5]216};
217#undef T
[705e612]218#undef __getter_t
[14a61b5]219
220#ifdef __cforall
221#define __dllist_t(T) __dllist(T)
222#else
223#define __dllist_t(T) struct __dllist
224#endif
225
226#ifdef __cforall
[768bd556]227 forall(dtype T )
[de94a60]228 static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
[768bd556]229 this.head{ 0p };
[de94a60]230 this.__get = __get;
231 }
232
[639991a]233 #define next 0
234 #define prev 1
[768bd556]235 static inline forall(dtype T) {
236 void push_front( __dllist(T) & this, T & node ) with( this ) {
237 verify(__get);
238 if ( head ) {
239 __get( node ).next = head;
240 __get( node ).prev = __get( *head ).prev;
241 // inserted node must be consistent before it is seen
242 // prevent code movement across barrier
243 asm( "" : : : "memory" );
244 __get( *head ).prev = &node;
245 T & _prev = *__get( node ).prev;
246 __get( _prev ).next = &node;
247 } else {
248 __get( node ).next = &node;
249 __get( node ).prev = &node;
250 }
251
[de94a60]252 // prevent code movement across barrier
253 asm( "" : : : "memory" );
[768bd556]254 head = &node;
[de94a60]255 }
256
[768bd556]257 void remove( __dllist(T) & this, T & node ) with( this ) {
258 verify(__get);
259 if ( &node == head ) {
260 if ( __get( *head ).next == head ) {
261 head = 0p;
262 } else {
263 head = __get( *head ).next;
264 }
[de94a60]265 }
[768bd556]266 __get( *__get( node ).next ).prev = __get( node ).prev;
267 __get( *__get( node ).prev ).next = __get( node ).next;
268 __get( node ).next = 0p;
269 __get( node ).prev = 0p;
[de94a60]270 }
[0c674e8]271
[768bd556]272 int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
273 return this.head != 0;
274 }
[0c674e8]275 }
[639991a]276 #undef next
277 #undef prev
[14a61b5]278#endif
279
[65deb18]280//-----------------------------------------------------------------------------
281// Tools
282//-----------------------------------------------------------------------------
283#ifdef __cforall
284
[2233ad4]285#endif
[768bd556]286
287// Local Variables: //
288// tab-width: 4 //
289// End: //
Note: See TracBrowser for help on using the repository browser.