Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
We need cmake 2.8 to compile simgrid
[simgrid.git] / win32_test_app / src / TThreadDynarray.c
1
2 #include <TThreadDynarray.h>
3
4 /*
5  * Constructs a ThreadDynarray with the specified capacity.
6  */
7 ThreadDynarray_t ThreadDynarray_new(unsigned long capacity)
8 {
9   ThreadDynarray_t ptr = calloc(1, sizeof(s_ThreadDynarray_t));
10
11   ptr->count = 0;
12   ptr->capacity = capacity;
13
14   memset(&(ptr->cs), 0, sizeof(CRITICAL_SECTION));
15   InitializeCriticalSection(&(ptr->cs));
16   ptr->is_locked = false;
17
18   if (capacity)
19     ptr->threads =
20         (ThreadEntry_t) calloc(capacity, sizeof(s_ThreadEntry_t));
21   else
22     ptr->threads = NULL;
23
24   return ptr;
25 }
26
27 /* 
28  * Destroy the ThreadDynarray 
29  */
30 void ThreadDynarray_destroy(ThreadDynarray_t ptr)
31 {
32   ThreadDynarray_clear(ptr);
33   DeleteCriticalSection(&(ptr->cs));
34   free(ptr);
35   ptr = NULL;
36 }
37
38 /*
39  * Returns an const pointer to entry pointed to by index.
40  */
41 ThreadEntry_t const ThreadDynarray_at(ThreadDynarray_t ptr,
42                                       unsigned long index)
43 {
44   ThreadEntry_t __entry;
45   ThreadDynarray_lock(ptr);
46   __entry = &(ptr->threads)[index];
47   ThreadDynarray_unlock(ptr);
48   return __entry;
49 }
50
51 /*
52  * Fill the content of the entry addressed by __entry with the content
53  * of the entry pointed to by index.
54  */
55 void ThreadDynarray_get(ThreadDynarray_t ptr, unsigned long index,
56                         ThreadEntry_t const __entry)
57 {
58   ThreadDynarray_lock(ptr);
59   ::memcpy(__entry, ThreadDynarray_at(ptr, index),
60            sizeof(s_ThreadEntry_t));
61   ThreadDynarray_unlock(ptr);
62 }
63
64 /* 
65  * Fill the content of the entry pointed to by index with the content of
66  * the entry addressed by __entry.
67  */
68 void ThreadDynarray_set(ThreadDynarray_t ptr, unsigned long index,
69                         ThreadEntry_t const __entry)
70 {
71
72   ThreadDynarray_lock(ptr);
73   memcpy(ThreadDynarray_at(ptr, index), __entry, sizeof(s_ThreadEntry_t));
74   ThreadDynarray_unlock(ptr);
75 }
76
77 /*
78  * Returns a const pointer to the first entry.
79  */
80 ThreadEntry_t const ThreadDynarray_getFront(ThreadDynarray_t ptr)
81 {
82   ThreadEntry_t __entry;
83   ThreadDynarray_lock(ptr);
84   __entry = ThreadDynarray_at(ptr, 0);
85   ThreadDynarray_unlock(ptr);
86   return __entry;
87 }
88
89 /*
90  * Returns a const pointer to the last entry.
91  */
92 ThreadEntry_t const ThreadDynarray_getBack(ThreadDynarray_t ptr)
93 {
94   ThreadEntry_t __entry;
95   ThreadDynarray_lock(ptr);
96   __entry = ThreadDynarray_at(ptr, ptr->count - 1);;
97   ThreadDynarray_unlock(ptr);
98   return __entry;
99 }
100
101 /*
102  * Inserts a copy of __entry at the front
103  */
104 void ThreadDynarray_pushFront(ThreadDynarray_t ptr,
105                               ThreadEntry_t const __entry)
106 {
107   ThreadDynarray_lock(ptr);
108
109   if (!ThreadDynarray_getCapacityAvailable(ptr))
110     ThreadDynarray_resize(ptr);
111
112   ptr->count++;
113   ThreadDynarray_move(ptr, 1, ThreadDynarray_getLowerBound(ptr),
114                       ThreadDynarray_getUpperBound(ptr));
115   ThreadDynarray_set(ptr, ThreadDynarray_getLowerBound(ptr), __entry);
116
117   ThreadDynarray_unlock(ptr);
118 }
119
120 /*
121  * Appends a copy of __entry to the end.
122  */
123 void ThreadDynarray_pushBack(ThreadDynarray_t ptr,
124                              ThreadEntry_t const __entry)
125 {
126   ThreadDynarray_lock(ptr);
127
128   if (!ThreadDynarray_getCapacityAvailable(ptr))
129     ThreadDynarray_resize(ptr);
130
131   ptr->count++;
132   ThreadDynarray_set(ptr, ThreadDynarray_getUpperBound(ptr), __entry);
133
134   ThreadDynarray_unlock(ptr);
135 }
136
137
138 /* 
139  * Inserts __entry at the position pointed to by index.
140  */
141 void ThreadDynarray_insert(ThreadDynarray_t ptr, unsigned long index,
142                            ThreadEntry_t const __entry)
143 {
144   ThreadDynarray_lock(ptr);
145
146   if (!ThreadDynarray_getCapacityAvailable(ptr))
147     ThreadDynarray_resize(ptr);
148
149   ThreadDynarray_move(ptr, index + 1, index, ptr->count - index);
150   ptr->count++;
151   ThreadDynarray_set(ptr, index, __entry);
152
153   ThreadDynarray_unlock(ptr);
154 }
155
156 /*
157  * Deletes the entry pointed to by index. If __entry is not NULL the
158  * fuction saves the entry threads at this address before.
159  */
160 void ThreadDynarray_erase(ThreadDynarray_t ptr, unsigned long index,
161                           ThreadEntry_t const __entry)
162 {
163
164   ThreadDynarray_lock(ptr);
165
166   if (__entry)
167     ThreadDynarray_set(ptr, index, __entry);
168
169   if (index != ThreadDynarray_getUpperBound(ptr))
170     ThreadDynarray_move(ptr, index, index + 1, (ptr->count - (index + 1)));
171
172   ptr->count--;
173
174   ThreadDynarray_unlock(ptr);
175 }
176
177 /*
178  * Find the first entry with the same content of the entry addressed by
179  * __entry.The function returns the index of the founded entry, -1 if
180  * no entry is founded.
181  */
182 long ThreadDynarray_getIndex(ThreadDynarray_t ptr,
183                              ThreadEntry_t const __entry)
184 {
185
186   unsigned long i;
187   ThreadDynarray_lock(ptr);
188
189   for (i = 0; i < ptr->count; i++) {
190     if (ThreadDynarray_compare(ptr, i, __entry)) {
191       ThreadDynarray_unlock(ptr);
192       return i;
193     }
194   }
195
196   ThreadDynarray_unlock(ptr);
197   return -1;
198 }
199
200 /* 
201  * Returns true if the entry exist.
202  */
203 bool ThreadDynarray_exist(ThreadDynarray_t ptr,
204                           ThreadEntry_t const __entry)
205 {
206   bool exist;
207
208   ThreadDynarray_lock(ptr);
209   exist = (-1 != ThreadDynarray_getIndex(ptr, __entry));
210   ThreadDynarray_unlock(ptr);
211   return exist;
212 }
213
214 /* Deletes the first entry with the same content of the entry addressed
215  * by __entry.The function returns true if the entry is deleted, false
216  * if no entry is founded.
217  */
218 bool ThreadDynarray_remove(ThreadDynarray_t ptr,
219                            ThreadEntry_t const __entry)
220 {
221   /* assert(!empty(ptr)); */
222
223   long __index;
224   ThreadDynarray_lock(ptr);
225   __index = ThreadDynarray_getIndex(ptr, __entry);
226
227   if (__index == -1) {
228     ThreadDynarray_unlock(ptr);
229     return false;
230   }
231
232   ThreadDynarray_set(ptr, (unsigned long) __index, NULL);
233   ThreadDynarray_unlock(ptr);
234   return true;
235 }
236
237 /*
238  * Erase all elements of the self.
239  */
240 void ThreadDynarray_clear(ThreadDynarray_t ptr)
241 {
242   ThreadDynarray_lock(ptr);
243
244   if (ptr->threads) {
245     free(ptr->threads);
246     ptr->threads = NULL;
247   }
248
249   ptr->count = 0;
250   ptr->capacity = 0;
251   ThreadDynarray_unlock(ptr);
252 }
253
254 /*
255  * Resets entry count to zero.
256  */
257 void ThreadDynarray_reset(ThreadDynarray_t ptr)
258 {
259   ThreadDynarray_lock(ptr);
260   ptr->count = 0;
261   ThreadDynarray_unlock(ptr);
262 }
263
264 /*
265  * Moves count elements from src index to dst index.
266  */
267 void ThreadDynarray_move(ThreadDynarray_t ptr, const unsigned long dst,
268                          const unsigned long src, unsigned long count)
269 {
270   ThreadDynarray_lock(ptr);
271
272   if (ptr->count)
273     memmove(ThreadDynarray_at(ptr, dst), ThreadDynarray_at(ptr, src),
274             count * sizeof(s_ThreadEntry_t));
275
276   ThreadDynarray_unlock(ptr);
277 }
278
279 /* Compare the content of the entry pointed to by index with the content of
280  * the entry addressed by __entry. The function returns true if the contents
281  * are same.
282  */
283 bool ThreadDynarray_compare(ThreadDynarray_t ptr,
284                             const unsigned long index,
285                             ThreadEntry_t const __entry)
286 {
287   bool are_equals;
288   ThreadDynarray_lock(ptr);
289   are_equals =
290       (!memcmp
291        (ThreadDynarray_at(ptr, index), __entry, sizeof(s_ThreadEntry_t)));
292   ThreadDynarray_unlock(ptr);
293   return are_equals;
294 }
295
296 /*
297  * Returns a reference to a new ThreadDynarray new set is a clone of the self.
298  */
299 ThreadDynarray_t ThreadDynarray_clone(ThreadDynarray_t ptr)
300 {
301   ThreadDynarray_t new_ptr;
302   ThreadDynarray_lock(ptr);
303   ptr = ThreadDynarray_new(ptr->capacity);
304
305   if (ptr->count) {
306     memcpy(new_ptr->threads, ptr->threads,
307            ptr->count * sizeof(s_ThreadEntry_t));
308     new_ptr->count = ThreadDynarray_getCount(ptr);
309   }
310   ThreadDynarray_unlock(ptr);
311   return new_ptr;
312 }
313
314 /*
315  * Extends the capacity when the container is full.
316  */
317 void ThreadDynarray_resize(ThreadDynarray_t ptr)
318 {
319   ThreadDynarray_lock(ptr);
320
321   ptr->capacity = (!ptr->capacity) ? 1 : (ptr->count << 1);
322   ptr->threads =
323       (ThreadEntry_t) realloc(ptr->threads,
324                               ptr->capacity * sizeof(s_ThreadEntry_t));
325
326   ThreadDynarray_unlock(ptr);
327 }
328
329
330 /*
331  * Returns the number of elements.
332  */
333 unsigned long ThreadDynarray_getCount(ThreadDynarray_t ptr)
334 {
335   unsigned count;
336   ThreadDynarray_lock(ptr);
337   count = ptr->count;
338   ThreadDynarray_unlock(ptr);
339   return count;
340 }
341
342 /*
343  * Returns the current storage capacity of the ThreadDynarray. This is guaranteed
344  * to be at least as large as count().
345  */
346 unsigned long ThreadDynarray_getCapacity(ThreadDynarray_t ptr)
347 {
348   unsigned capacity;
349   ThreadDynarray_lock(ptr);
350   capacity = ptr->capacity;
351   ThreadDynarray_unlock(ptr);
352   return capacity;
353 }
354
355
356 /*
357  * Returns upper bound of self (max index).
358  */
359 unsigned long ThreadDynarray_getUpperBound(ThreadDynarray_t ptr)
360 {
361   unsigned long upper_bound;
362   ThreadDynarray_lock(ptr);
363   upper_bound = (ptr->count - 1);
364   ThreadDynarray_unlock(ptr);
365   return upper_bound;
366 }
367
368 /*
369  * Returns lower bound of self (always zero).
370  */
371 unsigned long ThreadDynarray_getLowerBound(ThreadDynarray_t ptr)
372 {
373   return 0;
374 }
375
376 /*
377  * Returns the size of the elements.
378  */
379 unsigned long ThreadDynarray_getElementSize(ThreadDynarray_t ptr)
380 {
381   return sizeof(s_ThreadEntry_t);
382 }
383
384 /*
385  * Returns true if the size of self is zero.
386  */
387 bool ThreadDynarray_isEmpty(ThreadDynarray_t ptr)
388 {
389   bool is_empty;
390   ThreadDynarray_lock(ptr);
391   is_empty = (ptr->count == 0);
392   ThreadDynarray_unlock(ptr);
393   return is_empty;
394 }
395
396 /*
397  * Returns true if capacity available.
398  */
399 bool ThreadDynarray_getCapacityAvailable(ThreadDynarray_t ptr)
400 {
401   bool capacity_available;
402   ThreadDynarray_lock(ptr);
403   capacity_available = (ptr->capacity > ptr->count);
404   ThreadDynarray_unlock(ptr);
405   return capacity_available;
406 }
407
408 /*
409  * Returns true if the container is full.
410  */
411 bool ThreadDynarray_is_full(ThreadDynarray_t ptr)
412 {
413   bool is_full;
414   ThreadDynarray_lock(ptr);
415   is_full = (!ThreadDynarray_isEmpty(ptr)
416              && !ThreadDynarray_getCapacityAvailable(ptr));
417   ThreadDynarray_unlock(ptr);
418   return is_full;
419 }
420
421 /* 
422  * Assignement.
423  */
424 ThreadDynarray_t ThreadDynarray_assign(ThreadDynarray_t src,
425                                        ThreadDynarray_t dst)
426 {
427   ThreadDynarray_lock(src);
428   ThreadDynarray_lock(dst);
429
430   if (src != dst) {
431     ThreadDynarray_clear(dst);
432
433     if (src->count) {
434       dst->count = src->count;
435       dst->capacity = src->capacity;
436       dst->threads =
437           (ThreadEntry_t) malloc(src->capacity * sizeof(s_ThreadEntry_t));
438       memcpy(dst->threads, src->threads,
439              src->count * sizeof(s_ThreadEntry_t));
440     }
441   }
442   ThreadDynarray_unlock(src);
443   ThreadDynarray_unlock(dst);
444
445   return dst;
446 }
447
448 /* 
449  * Returns true if the dynamic arrays are equal.
450  */
451 bool ThreadDynarray_areEquals(ThreadDynarray_t ptr1, ThreadDynarray_t ptr2)
452 {
453   bool are_equals;
454
455   ThreadDynarray_lock(ptr1);
456   ThreadDynarray_lock(ptr2);
457
458   are_equals = (ptr1->count == ptr2->count &&
459                 ptr1->capacity == ptr2->capacity &&
460                 !memcmp(ptr2->threads, ptr1->threads, ptr1->capacity)
461       );
462
463   ThreadDynarray_unlock(ptr1);
464   ThreadDynarray_unlock(ptr2);
465
466   return are_equals;
467 }
468
469 /* 
470  * Returns true if the dynamic arrays are not equal.
471  */
472 ThreadDynarray_areNotEquals(ThreadDynarray_t ptr1, ThreadDynarray_t ptr2)
473 {
474   return !ThreadDynarray_areEquals(ptr1, ptr2);
475 }
476
477 void ThreadDynarray_lock(ThreadDynarray_t ptr)
478 {
479   if (!ptr->is_locked) {
480     EnterCriticalSection(&(ptr->cs));
481     ptr->is_locked = true;
482   }
483 }
484
485 void ThreadDynarray_unlock(ThreadDynarray_t ptr)
486 {
487   if (ptr->is_locked) {
488     LeaveCriticalSection(&(ptr->cs));
489     ptr->is_locked = false;
490   }
491 }