source: lib/data-struct/vector.c @ 2498008

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 2498008 was 2498008, checked in by Richard Sanger <rsangerarj@…>, 7 years ago

Refactor the combining step to allow user defined functions here.

Remove the old trace_get_results, now instead simply provide a reporter function which gets called as soon as results are ready.
The combiner function used determines the order of these results and when they are released etc.
The combiner function can be selected from those built-in or a custom version can be defined results are provided when ready.
Quickly hacked the parallel tests to work with this update, these are still a bit messy.

Also some fixes some compile warnings.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1#include "vector.h"
2
3#include <stdlib.h>
4#include <string.h>
5#include <assert.h>
6
7DLLEXPORT void libtrace_vector_init(libtrace_vector_t *v, size_t element_size) {
8        v->element_size = element_size;
9        v->size = 0; // Starts empty
10        v->max_size = 128; // Pick a largish size to begin with
11        v->elements = malloc(v->max_size * v->element_size);
12        ASSERT_RET(pthread_mutex_init(&v->lock, NULL), == 0);
13}
14
15DLLEXPORT void libtrace_vector_destroy(libtrace_vector_t *v) {
16        ASSERT_RET(pthread_mutex_destroy(&v->lock), == 0);
17        free(v->elements);
18        // Be safe make sure we wont work any more
19        v->elements = NULL;
20        v->size = 0;
21        v->max_size = 0;
22        v->element_size = 0;
23}
24
25DLLEXPORT void libtrace_vector_push_back(libtrace_vector_t *v, void *d) {
26        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
27        if (v->size >= v->max_size) {
28                /* Resize */
29                v->max_size *= 2;
30                v->elements = realloc(v->elements, v->max_size * v->element_size);
31                assert(v->elements);
32        }
33        memcpy(&v->elements[v->size*v->element_size], d, v->element_size);
34        v->size++;
35        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
36}
37
38DLLEXPORT size_t libtrace_vector_get_size(libtrace_vector_t *v) {
39        return v->size;
40}
41
42DLLEXPORT int libtrace_vector_get(libtrace_vector_t *v, size_t location, void *d) {
43        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
44        if (location >= v->size) {
45                ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
46                return 0;
47        }
48        memcpy(d, &v->elements[location*v->element_size], v->element_size);
49        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
50        return 1;
51}
52
53DLLEXPORT int libtrace_vector_remove_front(libtrace_vector_t *v) {
54        size_t i;
55        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
56        if (!v->size) {
57                ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
58                return 0;
59        }
60        v->size--;
61        // Of course this is mega slow
62        for (i = 0; i < v->size * v->element_size; i++)
63                v->elements[i] = v->elements[i+v->element_size];
64        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
65        return 1;
66}
67
68static inline void memswap(void *a, void *b, size_t size) {
69        char c;
70        size_t i;
71        for (i=0; i<size; i++) {
72                c = ((char *)a)[i];
73                ((char *)a)[i] = ((char *)b)[i];
74                ((char *)b)[i] = c;
75        }
76}
77// Note elements must be the same size
78// This also empties the second source array
79DLLEXPORT void libtrace_vector_append(libtrace_vector_t *dest, libtrace_vector_t *src)
80{
81        assert(dest->element_size == src->element_size);
82        if (src->size == 0) // Nothing to do if this is the case
83                return;
84        ASSERT_RET(pthread_mutex_lock(&dest->lock), == 0);
85        ASSERT_RET(pthread_mutex_lock(&src->lock), == 0);
86        if (src->size == 0) // Double check now we've got the locks - Nothing to do if this is the case
87                goto unlock;
88        if (dest->size == 0) {
89                memswap(&dest->max_size, &src->max_size, sizeof(src->max_size));
90                memswap(&dest->size, &src->size, sizeof(src->size));
91                memswap(&dest->element_size, &src->element_size, sizeof(src->element_size));
92                memswap(&dest->elements, &src->elements, sizeof(src->elements));
93        } else {
94                size_t oldmax = dest->max_size;
95                while (dest->max_size - dest->size < src->size) dest->max_size *= 2;
96                if (oldmax != dest->max_size)
97                        dest->elements = realloc(dest->elements, dest->max_size * dest->element_size);
98                // Now do the move
99                memcpy(&dest->elements[dest->element_size * dest->size], src->elements, src->element_size * src->size);
100                // Update the dest size
101                dest->size += src->size;
102                // Wipe the src
103                src->size = 0;
104        }
105unlock:
106        ASSERT_RET(pthread_mutex_unlock(&src->lock), == 0);
107        ASSERT_RET(pthread_mutex_unlock(&dest->lock), == 0);
108}
109
110DLLEXPORT void libtrace_zero_vector(libtrace_vector_t *v)
111{
112        v->max_size = 0;
113        v->size = 0;
114        v->element_size = 0;
115        v->elements = NULL;
116}
117
118DLLEXPORT void libtrace_vector_empty(libtrace_vector_t *v) {
119        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
120        v->size = 0;
121        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
122}
123
124
125DLLEXPORT void libtrace_vector_apply_function(libtrace_vector_t *v, vector_data_fn fn)
126{
127        size_t cur;
128        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
129        for (cur = 0; cur < v->size; cur++) {
130                (*fn)(&v->elements[cur*v->element_size]);
131        }
132        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
133}
134
135DLLEXPORT void libtrace_vector_qsort(libtrace_vector_t *v, int (*compar)(const void *, const void*)) {
136        ASSERT_RET(pthread_mutex_lock(&v->lock), == 0);
137        qsort(v->elements, v->element_size, v->element_size, compar);
138        ASSERT_RET(pthread_mutex_unlock(&v->lock), == 0);
139}
Note: See TracBrowser for help on using the repository browser.