Line data Source code
1 : /* Copyright 2017 noseglasses <shinynoseglasses@gmail.com>
2 : *
3 : * This program is free software: you can redistribute it and/or modify
4 : * it under the terms of the GNU Lesser General Public License as published by
5 : * the Free Software Foundation, either version 3 of the License, or
6 : * (at your option) any later version.
7 : *
8 : * This program is distributed in the hope that it will be useful,
9 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 : * GNU Lesser General Public License for more details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 : */
16 :
17 : #include "detail/ppg_aggregate_detail.h"
18 : #include "detail/ppg_input_detail.h"
19 : #include "detail/ppg_context_detail.h"
20 : #include "detail/ppg_malloc_detail.h"
21 :
22 : #include <stddef.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 :
26 38 : void *ppg_aggregate_new(void *aggregate__) {
27 :
28 : /* Explict call to parent constructor
29 : */
30 38 : ppg_token_new((PPG_Token__*)aggregate__);
31 :
32 38 : PPG_Aggregate *aggregate = (PPG_Aggregate*)aggregate__;
33 :
34 : /* Initialize the aggregate
35 : */
36 38 : aggregate->n_members = 0;
37 38 : aggregate->inputs = NULL;
38 :
39 38 : ppg_bitfield_init(&aggregate->member_active);
40 :
41 38 : aggregate->n_inputs_active = 0;
42 :
43 38 : return aggregate;
44 : }
45 :
46 135 : void ppg_aggregate_reset(PPG_Aggregate *aggregate)
47 : {
48 135 : ppg_token_reset_control_state((PPG_Token__*)aggregate);
49 :
50 135 : aggregate->n_inputs_active = 0;
51 :
52 540 : for(PPG_Count i = 0; i < aggregate->n_members; ++i) {
53 405 : ppg_bitfield_set_bit(&aggregate->member_active,
54 : i,
55 : false);
56 : }
57 :
58 : // Clear the activation state
59 : //
60 : aggregate->super.misc.flags
61 135 : &= (PPG_Count)~PPG_Aggregate_All_Active;
62 135 : }
63 :
64 76 : static void ppg_aggregate_deallocate_member_storage(PPG_Aggregate *aggregate) {
65 :
66 76 : if(aggregate->inputs) {
67 38 : free(aggregate->inputs);
68 38 : aggregate->inputs = NULL;
69 : }
70 :
71 76 : ppg_bitfield_destroy(&aggregate->member_active);
72 76 : }
73 :
74 38 : static void ppg_aggregate_resize(PPG_Aggregate *aggregate,
75 : PPG_Count n_members)
76 : {
77 38 : ppg_aggregate_deallocate_member_storage(aggregate);
78 :
79 38 : aggregate->n_members = n_members;
80 :
81 38 : aggregate->inputs = (PPG_Input_Id *)PPG_MALLOC(n_members*sizeof(PPG_Input_Id));
82 :
83 38 : ppg_bitfield_resize(&aggregate->member_active,
84 : n_members,
85 : false /*drop old bits*/);
86 :
87 38 : aggregate->n_inputs_active = 0;
88 :
89 152 : for(PPG_Count i = 0; i < n_members; ++i) {
90 114 : ppg_global_init_input(&aggregate->inputs[i]);
91 : }
92 38 : }
93 :
94 38 : PPG_Aggregate* ppg_aggregate_destroy(PPG_Aggregate *aggregate) {
95 :
96 38 : ppg_aggregate_deallocate_member_storage(aggregate);
97 :
98 38 : ppg_token_destroy((PPG_Token__*)aggregate);
99 :
100 38 : return aggregate;
101 : }
102 :
103 20 : PPG_Aggregate *ppg_aggregate_alloc(void) {
104 20 : return (PPG_Aggregate*)PPG_MALLOC(sizeof(PPG_Aggregate));
105 : }
106 :
107 33 : bool ppg_aggregates_equal(PPG_Aggregate *c1, PPG_Aggregate *c2)
108 : {
109 33 : if(c1->n_members != c2->n_members) { return false; }
110 :
111 33 : PPG_Count n_equalities = 0;
112 :
113 132 : for(PPG_Count i = 0; i < c1->n_members; ++i) {
114 366 : for(PPG_Count j = 0; j < c1->n_members; ++j) {
115 279 : if(c1->inputs[i] == c2->inputs[j]) {
116 12 : ++n_equalities;
117 12 : break;
118 : }
119 : }
120 : }
121 :
122 33 : return n_equalities == c1->n_members;
123 : }
124 :
125 38 : PPG_Token ppg_global_initialize_aggregate(
126 : PPG_Aggregate *aggregate,
127 : PPG_Count n_inputs,
128 : PPG_Input_Id inputs[])
129 : {
130 38 : ppg_aggregate_resize(aggregate, n_inputs);
131 :
132 152 : for(PPG_Count i = 0; i < n_inputs; ++i) {
133 114 : aggregate->inputs[i] = inputs[i];
134 : }
135 :
136 : /* Return the new end of the pattern
137 : */
138 38 : return aggregate;
139 : }
140 :
141 24 : size_t ppg_aggregate_dynamic_member_size(PPG_Aggregate *aggregate)
142 : {
143 48 : return ppg_token_dynamic_member_size((PPG_Token__*)aggregate)
144 24 : + aggregate->n_members*sizeof(PPG_Input_Id)
145 24 : + ppg_bitfield_get_num_cells(&aggregate->member_active)
146 24 : *sizeof(PPG_Bitfield_Storage_Type);
147 : }
148 :
149 24 : char *ppg_aggregate_copy_dynamic_members(PPG_Token__ *source,
150 : PPG_Token__ *target,
151 : char *buffer)
152 : {
153 24 : PPG_Aggregate *aggregate = (PPG_Aggregate *)source;
154 :
155 24 : PPG_Aggregate *copy_of_aggregate = (PPG_Aggregate *)target;
156 :
157 24 : buffer = ppg_token_copy_dynamic_members(source, buffer);
158 :
159 24 : size_t n_bytes = aggregate->n_members*sizeof(PPG_Input_Id);
160 :
161 24 : memcpy(buffer, (void*)aggregate->inputs, n_bytes);
162 :
163 24 : copy_of_aggregate->inputs = (PPG_Input_Id *)buffer;
164 :
165 24 : buffer += n_bytes;
166 :
167 24 : n_bytes = ppg_bitfield_get_num_cells(&aggregate->member_active)
168 : *sizeof(PPG_Bitfield_Storage_Type);
169 :
170 24 : memcpy(buffer, (void*)aggregate->member_active.bitarray, n_bytes);
171 :
172 24 : copy_of_aggregate->member_active.bitarray = (PPG_Bitfield_Storage_Type *)buffer;
173 :
174 24 : return buffer + n_bytes;
175 : }
176 :
177 24 : void ppg_aggregate_addresses_to_relative( PPG_Token__ *token,
178 : void *begin_of_buffer
179 : )
180 : {
181 24 : ppg_token_addresses_to_relative(token, begin_of_buffer);
182 :
183 24 : PPG_Aggregate *aggregate = (PPG_Aggregate *)token;
184 :
185 48 : aggregate->inputs = (PPG_Input_Id *)((char*)aggregate->inputs
186 24 : - (char*)begin_of_buffer);
187 :
188 24 : aggregate->member_active.bitarray = (PPG_Bitfield_Storage_Type *)
189 24 : ((char*)aggregate->member_active.bitarray
190 24 : - (char*)begin_of_buffer);
191 24 : }
192 :
193 12 : void ppg_aggregate_addresses_to_absolute( PPG_Token__ *token,
194 : void *begin_of_buffer
195 : )
196 : {
197 12 : ppg_token_addresses_to_absolute(token, begin_of_buffer);
198 :
199 12 : PPG_Aggregate *aggregate = (PPG_Aggregate *)token;
200 :
201 12 : aggregate->inputs = (PPG_Input_Id *)((char*)begin_of_buffer
202 12 : + (size_t)aggregate->inputs);
203 :
204 12 : aggregate->member_active.bitarray = (PPG_Bitfield_Storage_Type *)
205 : ((char*)begin_of_buffer
206 12 : + (size_t)aggregate->member_active.bitarray);
207 12 : }
208 :
209 : #if PPG_HAVE_DEBUGGING
210 0 : bool ppg_aggregate_check_initialized(PPG_Token__ *token)
211 : {
212 0 : PPG_Aggregate *aggregate = (PPG_Aggregate*)token;
213 :
214 0 : bool assertion_failed = false;
215 :
216 0 : assertion_failed |= ppg_token_check_initialized(token);
217 :
218 0 : PPG_ASSERT_WARN((aggregate->super.misc.flags
219 : & PPG_Aggregate_All_Active) == 0);
220 :
221 0 : PPG_ASSERT_WARN(aggregate->n_inputs_active == 0);
222 :
223 0 : for(PPG_Count i = 0; i < aggregate->n_members; ++i) {
224 0 : PPG_ASSERT_WARN(ppg_bitfield_get_bit(&aggregate->member_active,
225 : i) == false);
226 : }
227 :
228 0 : return assertion_failed;
229 : }
230 : #endif
|