source: lib/trace_vector.c @ 29ba7c2

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

My work from over summer, with a few things tidied up and updated to include recent commits/patches to bring this up to date. Still very much work in progress.

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