Add READ_ONCE and WRITE_ONCE (XCC)
[akaros.git] / kern / lib / slice.c
1 /*
2  * Copyright (C) 2016 Google Inc.
3  * Dan Cross <crossd@gmail.com>
4  * See LICENSE for license details.
5  */
6
7 #include <kmalloc.h>
8 #include <assert.h>
9 #include <error.h>
10 #include <slice.h>
11
12 void slice_init(struct slice *slice)
13 {
14         memset(slice, 0, sizeof(*slice));
15 }
16
17 void slice_clear(struct slice *slice)
18 {
19         slice->len = 0;
20         memset(slice->ptrs, 0, sizeof(*slice->ptrs) * slice->capacity);
21 }
22
23 void *slice_get(struct slice *slice, size_t i)
24 {
25         if (i >= slice->len)
26                 return NULL;
27         return slice->ptrs[i];
28 }
29
30 bool slice_put(struct slice *slice, size_t i, void *p)
31 {
32         if (i >= slice->len)
33                 return FALSE;
34         slice->ptrs[i] = p;
35         return TRUE;
36 }
37
38 bool slice_del(struct slice *slice, size_t i)
39 {
40         if (i >= slice->len)
41                 return FALSE;
42         memmove(slice->ptrs + i, slice->ptrs + i + 1,
43                 (slice->len - (i + 1)) * sizeof(void *));
44         slice->len--;
45         return TRUE;
46 }
47
48 void slice_append(struct slice *s, void *p)
49 {
50         void **ps;
51
52         assert(p != NULL);
53         if (s->len == s->capacity) {
54                 if (s->capacity == 0)
55                         s->capacity = 4;
56                 s->capacity *= 2;
57                 ps = kreallocarray(s->ptrs, s->capacity, sizeof(void *),
58                                    MEM_WAIT);
59                 assert(ps != NULL);             /* XXX: if size*sizeof(void*) overflows. */
60                 s->ptrs = ps;
61         }
62         s->ptrs[s->len] = p;
63         s->len++;
64 }
65
66 size_t slice_len(struct slice *slice)
67 {
68         return slice->len;
69 }
70
71 void **slice_finalize(struct slice *slice)
72 {
73         void **ps;
74
75         ps = kreallocarray(slice->ptrs, slice->len, sizeof(void *), MEM_WAIT);
76         assert(ps != NULL);
77         slice->len = 0;
78         slice->capacity = 0;
79         slice->ptrs = NULL;
80
81         return ps;
82 }
83
84 void slice_destroy(struct slice *slice)
85 {
86         kfree(slice->ptrs);
87         slice->ptrs = NULL;
88         slice->capacity = 0;
89         slice->len = 0;
90 }