419d48301349048ccbe34119803ba0ccd49bb3cc
[akaros.git] / tools / profile / perf / xlib.c
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  */
5
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include "xlib.h"
16
17 void xmem_arena_init(struct mem_arena *ma, size_t block_size)
18 {
19         memset(ma, 0, sizeof(*ma));
20         ma->block_size = (block_size != 0) ? block_size : (128 * 1024);
21 }
22
23 void xmem_arena_destroy(struct mem_arena *ma)
24 {
25         struct mem_arena_block *tmp;
26
27         while ((tmp = ma->blocks) != NULL) {
28                 ma->blocks = tmp->next;
29                 free(tmp);
30         }
31 }
32
33 void *xmem_arena_alloc(struct mem_arena *ma, size_t size)
34 {
35         size_t aspace = ma->top - ma->ptr;
36         void *data;
37
38         size = ROUNDUP(size, sizeof(void *));
39         if (aspace < size) {
40                 size_t bsize;
41                 struct mem_arena_block *blk;
42
43                 /* If there is enough space left, and the requested size is big enough,
44                  * hand over full block and keep the leftover space as is.
45                  */
46                 if (aspace >= (ma->block_size / 8)) {
47                         blk = xmalloc(size + sizeof(struct mem_arena_block));
48                         blk->next = ma->blocks;
49                         ma->blocks = blk;
50
51                         return (char *) blk + sizeof(struct mem_arena_block);
52                 }
53
54                 bsize = max(ma->block_size, size) + sizeof(struct mem_arena_block);
55                 blk = xmalloc(bsize);
56
57                 blk->next = ma->blocks;
58                 ma->blocks = blk;
59                 ma->ptr = (char *) blk + sizeof(struct mem_arena_block);
60                 ma->top = ma->ptr + bsize;
61         }
62         data = ma->ptr;
63         ma->ptr += size;
64
65         return data;
66 }
67
68 void *xmem_arena_zalloc(struct mem_arena *ma, size_t size)
69 {
70         void *data = xmem_arena_alloc(ma, size);
71
72         memset(data, 0, size);
73
74         return data;
75 }
76
77 char *xmem_arena_strdup(struct mem_arena *ma, const char *str)
78 {
79         size_t size = strlen(str);
80         char *dstr = xmem_arena_alloc(ma, size + 1);
81
82         memcpy(dstr, str, size + 1);
83
84         return dstr;
85 }
86
87 int xopen(const char *path, int flags, mode_t mode)
88 {
89         int fd = open(path, flags, mode);
90
91         if (fd < 0) {
92                 perror(path);
93                 exit(1);
94         }
95
96         return fd;
97 }
98
99 void xwrite(int fd, const void *data, size_t size)
100 {
101         ssize_t wcount = write(fd, data, size);
102
103         if (size != (size_t) wcount) {
104                 perror("Writing file");
105                 exit(1);
106         }
107 }
108
109 void xread(int fd, void *data, size_t size)
110 {
111         ssize_t rcount = read(fd, data, size);
112
113         if (size != (size_t) rcount) {
114                 perror("Reading file");
115                 exit(1);
116         }
117 }
118
119 void xpwrite(int fd, const void *data, size_t size, off_t off)
120 {
121         ssize_t wcount = pwrite(fd, data, size, off);
122
123         if (size != (size_t) wcount) {
124                 perror("Writing file");
125                 exit(1);
126         }
127 }
128
129 void xpread(int fd, void *data, size_t size, off_t off)
130 {
131         ssize_t rcount = pread(fd, data, size, off);
132
133         if (size != (size_t) rcount) {
134                 perror("Reading file");
135                 exit(1);
136         }
137 }
138
139 FILE *xfopen(const char *path, const char *mode)
140 {
141         FILE *file = fopen(path, mode);
142
143         if (!file) {
144                 fprintf(stderr, "Unable to open file '%s' for mode '%s': %s\n",
145                                 path, mode, strerror(errno));
146                 exit(1);
147         }
148
149         return file;
150 }
151
152 off_t xfsize(FILE *file)
153 {
154         off_t pos = ftello(file), size;
155
156         xfseek(file, 0, SEEK_END);
157         size = ftello(file);
158         xfseek(file, pos, SEEK_SET);
159
160         return size;
161 }
162
163 void xfwrite(const void *data, size_t size, FILE *file)
164 {
165         if (fwrite(data, 1, size, file) != size) {
166                 fprintf(stderr, "Unable to write %lu bytes: %s\n", size,
167                                 strerror(errno));
168                 exit(1);
169         }
170 }
171
172 void xfseek(FILE *file, off_t offset, int whence)
173 {
174         if (fseeko(file, offset, whence)) {
175                 int error = errno;
176
177                 fprintf(stderr, "Unable to seek at offset %ld from %s (fpos=%ld): %s\n",
178                                 offset, whence == SEEK_SET ? "beginning of file" :
179                                 (whence == SEEK_END ? "end of file" : "current position"),
180                                 ftell(file), strerror(error));
181                 exit(1);
182         }
183 }
184
185 void *xmalloc(size_t size)
186 {
187         void *data = malloc(size);
188
189         if (!data) {
190                 perror("Allocating memory block");
191                 exit(1);
192         }
193
194         return data;
195 }
196
197 void *xzmalloc(size_t size)
198 {
199         void *data = xmalloc(size);
200
201         memset(data, 0, size);
202
203         return data;
204 }
205
206 char *xstrdup(const char *str)
207 {
208         char *dstr = strdup(str);
209
210         if (dstr == NULL) {
211                 perror("Duplicating a string");
212                 exit(1);
213         }
214
215         return dstr;
216 }
217
218 const char *vb_decode_uint64(const char *data, uint64_t *pval)
219 {
220         unsigned int i;
221         uint64_t val = 0;
222
223         for (i = 0; (*data & 0x80) != 0; i += 7, data++)
224                 val |= (((uint64_t) *data) & 0x7f) << i;
225         *pval = val | ((uint64_t) *data) << i;
226
227         return data + 1;
228 }
229
230 int vb_fdecode_uint64(FILE *file, uint64_t *pval)
231 {
232         unsigned int i = 0;
233         uint64_t val = 0;
234
235         for (;;) {
236                 int c = fgetc(file);
237
238                 if (c == EOF)
239                         return EOF;
240                 val |= (((uint64_t) c) & 0x7f) << i;
241                 i += 7;
242                 if ((c & 0x80) == 0)
243                         break;
244         }
245         *pval = val;
246
247         return i / 7;
248 }