2 #include <TThreadDynarray.h>
5 * Constructs a ThreadDynarray with the specified capacity.
7 ThreadDynarray_t ThreadDynarray_new(unsigned long capacity)
9 ThreadDynarray_t ptr = calloc(1, sizeof(s_ThreadDynarray_t));
12 ptr->capacity = capacity;
14 memset(&(ptr->cs), 0, sizeof(CRITICAL_SECTION));
15 InitializeCriticalSection(&(ptr->cs));
16 ptr->is_locked = false;
20 (ThreadEntry_t) calloc(capacity, sizeof(s_ThreadEntry_t));
28 * Destroy the ThreadDynarray
30 void ThreadDynarray_destroy(ThreadDynarray_t ptr)
32 ThreadDynarray_clear(ptr);
33 DeleteCriticalSection(&(ptr->cs));
39 * Returns an const pointer to entry pointed to by index.
41 ThreadEntry_t const ThreadDynarray_at(ThreadDynarray_t ptr,
44 ThreadEntry_t __entry;
45 ThreadDynarray_lock(ptr);
46 __entry = &(ptr->threads)[index];
47 ThreadDynarray_unlock(ptr);
52 * Fill the content of the entry addressed by __entry with the content
53 * of the entry pointed to by index.
55 void ThreadDynarray_get(ThreadDynarray_t ptr, unsigned long index,
56 ThreadEntry_t const __entry)
58 ThreadDynarray_lock(ptr);
59 ::memcpy(__entry, ThreadDynarray_at(ptr, index),
60 sizeof(s_ThreadEntry_t));
61 ThreadDynarray_unlock(ptr);
65 * Fill the content of the entry pointed to by index with the content of
66 * the entry addressed by __entry.
68 void ThreadDynarray_set(ThreadDynarray_t ptr, unsigned long index,
69 ThreadEntry_t const __entry)
72 ThreadDynarray_lock(ptr);
73 memcpy(ThreadDynarray_at(ptr, index), __entry, sizeof(s_ThreadEntry_t));
74 ThreadDynarray_unlock(ptr);
78 * Returns a const pointer to the first entry.
80 ThreadEntry_t const ThreadDynarray_getFront(ThreadDynarray_t ptr)
82 ThreadEntry_t __entry;
83 ThreadDynarray_lock(ptr);
84 __entry = ThreadDynarray_at(ptr, 0);
85 ThreadDynarray_unlock(ptr);
90 * Returns a const pointer to the last entry.
92 ThreadEntry_t const ThreadDynarray_getBack(ThreadDynarray_t ptr)
94 ThreadEntry_t __entry;
95 ThreadDynarray_lock(ptr);
96 __entry = ThreadDynarray_at(ptr, ptr->count - 1);;
97 ThreadDynarray_unlock(ptr);
102 * Inserts a copy of __entry at the front
104 void ThreadDynarray_pushFront(ThreadDynarray_t ptr,
105 ThreadEntry_t const __entry)
107 ThreadDynarray_lock(ptr);
109 if (!ThreadDynarray_getCapacityAvailable(ptr))
110 ThreadDynarray_resize(ptr);
113 ThreadDynarray_move(ptr, 1, ThreadDynarray_getLowerBound(ptr),
114 ThreadDynarray_getUpperBound(ptr));
115 ThreadDynarray_set(ptr, ThreadDynarray_getLowerBound(ptr), __entry);
117 ThreadDynarray_unlock(ptr);
121 * Appends a copy of __entry to the end.
123 void ThreadDynarray_pushBack(ThreadDynarray_t ptr,
124 ThreadEntry_t const __entry)
126 ThreadDynarray_lock(ptr);
128 if (!ThreadDynarray_getCapacityAvailable(ptr))
129 ThreadDynarray_resize(ptr);
132 ThreadDynarray_set(ptr, ThreadDynarray_getUpperBound(ptr), __entry);
134 ThreadDynarray_unlock(ptr);
139 * Inserts __entry at the position pointed to by index.
141 void ThreadDynarray_insert(ThreadDynarray_t ptr, unsigned long index,
142 ThreadEntry_t const __entry)
144 ThreadDynarray_lock(ptr);
146 if (!ThreadDynarray_getCapacityAvailable(ptr))
147 ThreadDynarray_resize(ptr);
149 ThreadDynarray_move(ptr, index + 1, index, ptr->count - index);
151 ThreadDynarray_set(ptr, index, __entry);
153 ThreadDynarray_unlock(ptr);
157 * Deletes the entry pointed to by index. If __entry is not NULL the
158 * fuction saves the entry threads at this address before.
160 void ThreadDynarray_erase(ThreadDynarray_t ptr, unsigned long index,
161 ThreadEntry_t const __entry)
164 ThreadDynarray_lock(ptr);
167 ThreadDynarray_set(ptr, index, __entry);
169 if (index != ThreadDynarray_getUpperBound(ptr))
170 ThreadDynarray_move(ptr, index, index + 1, (ptr->count - (index + 1)));
174 ThreadDynarray_unlock(ptr);
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.
182 long ThreadDynarray_getIndex(ThreadDynarray_t ptr,
183 ThreadEntry_t const __entry)
187 ThreadDynarray_lock(ptr);
189 for (i = 0; i < ptr->count; i++) {
190 if (ThreadDynarray_compare(ptr, i, __entry)) {
191 ThreadDynarray_unlock(ptr);
196 ThreadDynarray_unlock(ptr);
201 * Returns true if the entry exist.
203 bool ThreadDynarray_exist(ThreadDynarray_t ptr,
204 ThreadEntry_t const __entry)
208 ThreadDynarray_lock(ptr);
209 exist = (-1 != ThreadDynarray_getIndex(ptr, __entry));
210 ThreadDynarray_unlock(ptr);
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.
218 bool ThreadDynarray_remove(ThreadDynarray_t ptr,
219 ThreadEntry_t const __entry)
221 /* assert(!empty(ptr)); */
224 ThreadDynarray_lock(ptr);
225 __index = ThreadDynarray_getIndex(ptr, __entry);
228 ThreadDynarray_unlock(ptr);
232 ThreadDynarray_set(ptr, (unsigned long) __index, NULL);
233 ThreadDynarray_unlock(ptr);
238 * Erase all elements of the self.
240 void ThreadDynarray_clear(ThreadDynarray_t ptr)
242 ThreadDynarray_lock(ptr);
249 ThreadDynarray_unlock(ptr);
253 * Resets entry count to zero.
255 void ThreadDynarray_reset(ThreadDynarray_t ptr)
257 ThreadDynarray_lock(ptr);
259 ThreadDynarray_unlock(ptr);
263 * Moves count elements from src index to dst index.
265 void ThreadDynarray_move(ThreadDynarray_t ptr, const unsigned long dst,
266 const unsigned long src, unsigned long count)
268 ThreadDynarray_lock(ptr);
271 memmove(ThreadDynarray_at(ptr, dst), ThreadDynarray_at(ptr, src),
272 count * sizeof(s_ThreadEntry_t));
274 ThreadDynarray_unlock(ptr);
277 /* Compare the content of the entry pointed to by index with the content of
278 * the entry addressed by __entry. The function returns true if the contents
281 bool ThreadDynarray_compare(ThreadDynarray_t ptr,
282 const unsigned long index,
283 ThreadEntry_t const __entry)
286 ThreadDynarray_lock(ptr);
289 (ThreadDynarray_at(ptr, index), __entry, sizeof(s_ThreadEntry_t)));
290 ThreadDynarray_unlock(ptr);
295 * Returns a reference to a new ThreadDynarray new set is a clone of the self.
297 ThreadDynarray_t ThreadDynarray_clone(ThreadDynarray_t ptr)
299 ThreadDynarray_t new_ptr;
300 ThreadDynarray_lock(ptr);
301 ptr = ThreadDynarray_new(ptr->capacity);
304 memcpy(new_ptr->threads, ptr->threads,
305 ptr->count * sizeof(s_ThreadEntry_t));
306 new_ptr->count = ThreadDynarray_getCount(ptr);
308 ThreadDynarray_unlock(ptr);
313 * Extends the capacity when the container is full.
315 void ThreadDynarray_resize(ThreadDynarray_t ptr)
317 ThreadDynarray_lock(ptr);
319 ptr->capacity = (!ptr->capacity) ? 1 : (ptr->count << 1);
321 (ThreadEntry_t) realloc(ptr->threads,
322 ptr->capacity * sizeof(s_ThreadEntry_t));
324 ThreadDynarray_unlock(ptr);
329 * Returns the number of elements.
331 unsigned long ThreadDynarray_getCount(ThreadDynarray_t ptr)
334 ThreadDynarray_lock(ptr);
336 ThreadDynarray_unlock(ptr);
341 * Returns the current storage capacity of the ThreadDynarray. This is guaranteed
342 * to be at least as large as count().
344 unsigned long ThreadDynarray_getCapacity(ThreadDynarray_t ptr)
347 ThreadDynarray_lock(ptr);
348 capacity = ptr->capacity;
349 ThreadDynarray_unlock(ptr);
355 * Returns upper bound of self (max index).
357 unsigned long ThreadDynarray_getUpperBound(ThreadDynarray_t ptr)
359 unsigned long upper_bound;
360 ThreadDynarray_lock(ptr);
361 upper_bound = (ptr->count - 1);
362 ThreadDynarray_unlock(ptr);
367 * Returns lower bound of self (always zero).
369 unsigned long ThreadDynarray_getLowerBound(ThreadDynarray_t ptr)
375 * Returns the size of the elements.
377 unsigned long ThreadDynarray_getElementSize(ThreadDynarray_t ptr)
379 return sizeof(s_ThreadEntry_t);
383 * Returns true if the size of self is zero.
385 bool ThreadDynarray_isEmpty(ThreadDynarray_t ptr)
388 ThreadDynarray_lock(ptr);
389 is_empty = (ptr->count == 0);
390 ThreadDynarray_unlock(ptr);
395 * Returns true if capacity available.
397 bool ThreadDynarray_getCapacityAvailable(ThreadDynarray_t ptr)
399 bool capacity_available;
400 ThreadDynarray_lock(ptr);
401 capacity_available = (ptr->capacity > ptr->count);
402 ThreadDynarray_unlock(ptr);
403 return capacity_available;
407 * Returns true if the container is full.
409 bool ThreadDynarray_is_full(ThreadDynarray_t ptr)
412 ThreadDynarray_lock(ptr);
413 is_full = (!ThreadDynarray_isEmpty(ptr)
414 && !ThreadDynarray_getCapacityAvailable(ptr));
415 ThreadDynarray_unlock(ptr);
422 ThreadDynarray_t ThreadDynarray_assign(ThreadDynarray_t src,
423 ThreadDynarray_t dst)
425 ThreadDynarray_lock(src);
426 ThreadDynarray_lock(dst);
429 ThreadDynarray_clear(dst);
432 dst->count = src->count;
433 dst->capacity = src->capacity;
435 (ThreadEntry_t) malloc(src->capacity * sizeof(s_ThreadEntry_t));
436 memcpy(dst->threads, src->threads,
437 src->count * sizeof(s_ThreadEntry_t));
440 ThreadDynarray_unlock(src);
441 ThreadDynarray_unlock(dst);
447 * Returns true if the dynamic arrays are equal.
449 bool ThreadDynarray_areEquals(ThreadDynarray_t ptr1, ThreadDynarray_t ptr2)
453 ThreadDynarray_lock(ptr1);
454 ThreadDynarray_lock(ptr2);
456 are_equals = (ptr1->count == ptr2->count &&
457 ptr1->capacity == ptr2->capacity &&
458 !memcmp(ptr2->threads, ptr1->threads, ptr1->capacity)
461 ThreadDynarray_unlock(ptr1);
462 ThreadDynarray_unlock(ptr2);
468 * Returns true if the dynamic arrays are not equal.
470 ThreadDynarray_areNotEquals(ThreadDynarray_t ptr1, ThreadDynarray_t ptr2)
472 return !ThreadDynarray_areEquals(ptr1, ptr2);
475 void ThreadDynarray_lock(ThreadDynarray_t ptr)
477 if (!ptr->is_locked) {
478 EnterCriticalSection(&(ptr->cs));
479 ptr->is_locked = true;
483 void ThreadDynarray_unlock(ThreadDynarray_t ptr)
485 if (ptr->is_locked) {
486 LeaveCriticalSection(&(ptr->cs));
487 ptr->is_locked = false;