source: src/tests/init_once.c@ e4d3ceb

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since e4d3ceb was 6e4b913, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

allow 32-bit compilation of cfa-cpp, and 32-bit compilation of CFA programs (including CFA libraries)

  • Property mode set to 100644
File size: 3.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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// init_once.c --
8//
9// Author : Rob Schluntz
10// Created On : Tue Jun 14 15:43:35 2016
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Jul 9 11:30:29 2016
13// Update Count : 3
14//
15
16// want to ensure ctor/dtor called at most once per object.
17// whole point of ctor/dtor is that you don't know what's in
18// memory when it's first called, so can't rely on member to
19// determine if this is true. instead, keep an array
20// of addresses that have been constructed and remove the element
21// when it's destructed (and vice-versa)
22
23//*** setup
24extern "C" {
25#define NULL 0
26void * malloc(size_t);
27void free(void *);
28#define assert(cond) if (! (cond)) { printf("Assertion failed: (%s) at %s:%d\n", #cond, __FILE__, __LINE__); abort(); }
29void *memset(void *s, int c, size_t n);
30}
31
32// dummy type
33struct init_once { int * x; };
34
35// array and operations
36// const int size = 1024;
37#define size 1024
38struct array {
39 init_once * elems[size];
40 int length;
41};
42void remove(array * arr, init_once * x) {
43 for (int i = 0; i < arr->length; i++) {
44 if ( arr->elems[i] == x ) {
45 arr->elems[i] = arr->elems[--arr->length];
46 return;
47 }
48 }
49}
50void insert(array * arr, init_once * x) {
51 assert( arr->length < size );
52 arr->elems[arr->length++] = x;
53}
54int find(array * arr, init_once * x) {
55 for (int i = 0; i < arr->length; i++) {
56 if ( arr->elems[i] == x ) {
57 return i;
58 }
59 }
60 return -1;
61}
62void ?{}(array * arr) {
63 memset(arr->elems, 0, sizeof(arr->elems));
64 arr->length = 0;
65}
66array constructed;
67array destructed;
68
69void ?{}(init_once * x) {
70 assert( find( &constructed, x ) == -1 );
71 remove( &destructed, x );
72 insert( &constructed, x );
73
74 x->x = malloc(sizeof(int));
75}
76
77void ?{}(init_once * x, init_once other) {
78 x{}; // reuse default ctor
79}
80
81void ^?{}(init_once * x) {
82 assert( find( &destructed, x ) == -1 );
83 remove( &constructed, x );
84 insert( &destructed, x );
85
86 free(x->x);
87}
88//*** end setup
89
90// test globals
91init_once x;
92init_once y = x;
93
94int main() {
95 // local variables
96 init_once x;
97 init_once y = x;
98
99 // block scoped variables
100 {
101 init_once x;
102 init_once y = x;
103 }
104
105 // loop variables
106 for (int i = 0 ; i < 10; i++) {
107 init_once x;
108 init_once y = x;
109 }
110 int i = 0;
111 while (i < 10) {
112 init_once x;
113 init_once y = x;
114 i++;
115 }
116
117 // declared in a switch block with a break
118 for (int i = 0; i < 10; i++) {
119 switch (10) {
120 case 1: {
121 init_once x;
122 init_once y = x;
123 (&x) {}; // ensure this doesn't execute
124 break;
125 }
126 case 10: {
127 init_once x;
128 init_once y = x;
129 } // fall through
130 default: {
131 init_once x;
132 init_once y = x;
133 break;
134 }
135 }
136 }
137
138 // labeled break/continue
139 L3: for (int k = 0; k < 10; k++) {
140 init_once x;
141 init_once y = x;
142 L1: for (int i = 0; i < 10; i++){
143 init_once x;
144 init_once y = x;
145 L2: for (int j = 0; j < 10; j++) {
146 init_once x;
147 init_once y = x;
148
149 if (i == 0) continue L1;
150 if (i == 1) continue L2;
151 if (i == 2) break L2;
152 if (i == 3) break L1;
153 if (i == 4) continue L3;
154 if (i == 9) break L3;
155 // if (i == 5) goto ;
156 }
157 }
158 }
159
160 // labeled break/continue with if
161 LL1: for (int k = 0; k < 10; k++) {
162 init_once x;
163 init_once y = x;
164 LL2: for (int i = 0; i < 10; i++){
165 init_once x;
166 init_once y = x;
167 LL3: if( i < 5) {
168 init_once x;
169 init_once y = x;
170
171 if (i == 0) continue LL2;
172 if (i == 2) break LL3;
173 if (i == 3) break LL2;
174 if (i == 4) continue LL1;
175 } else {
176 if (i == 9) break LL1;
177 // if (i == 5) goto ;
178 }
179 }
180 }
181}
182
183// Local Variables: //
184// tab-width: 4 //
185// compile-command: "cfa init_once.c" //
186// End: //
Note: See TracBrowser for help on using the repository browser.