ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | LICENSE

os_unix.c (4786B)


      1 /* See LICENSE for license details. */
      2 #include "util.h"
      3 
      4 #include <dlfcn.h>
      5 #include <fcntl.h>
      6 #include <poll.h>
      7 #include <sys/mman.h>
      8 #include <sys/stat.h>
      9 #include <unistd.h>
     10 
     11 static PLATFORM_WRITE_FILE_FN(os_write_file)
     12 {
     13 	while (raw.len) {
     14 		size r = write(file, raw.data, raw.len);
     15 		if (r < 0) return 0;
     16 		raw = s8_cut_head(raw, r);
     17 	}
     18 	return 1;
     19 }
     20 
     21 static void
     22 os_write_err_msg(s8 msg)
     23 {
     24 	os_write_file(STDERR_FILENO, msg);
     25 }
     26 
     27 static void __attribute__((noreturn))
     28 os_fatal(s8 msg)
     29 {
     30 	os_write_err_msg(msg);
     31 	_exit(1);
     32 	unreachable();
     33 }
     34 
     35 static PLATFORM_ALLOC_ARENA_FN(os_alloc_arena)
     36 {
     37 	Arena result;
     38 	size pagesize = sysconf(_SC_PAGESIZE);
     39 	if (capacity % pagesize != 0)
     40 		capacity += pagesize - capacity % pagesize;
     41 
     42 	size oldsize = old.end - old.beg;
     43 	if (oldsize > capacity)
     44 		return old;
     45 
     46 	if (old.beg)
     47 		munmap(old.beg, oldsize);
     48 
     49 	result.beg = mmap(0, capacity, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
     50 	if (result.beg == MAP_FAILED)
     51 		os_fatal(s8("os_alloc_arena: couldn't allocate memory\n"));
     52 	result.end = result.beg + capacity;
     53 	return result;
     54 }
     55 
     56 static PLATFORM_CLOSE_FN(os_close)
     57 {
     58 	close(file);
     59 }
     60 
     61 static PLATFORM_OPEN_FOR_WRITE_FN(os_open_for_write)
     62 {
     63 	iptr result = open(fname, O_WRONLY|O_TRUNC);
     64 	if (result == -1)
     65 		result = INVALID_FILE;
     66 	return result;
     67 }
     68 
     69 static s8
     70 os_read_file(Arena *a, char *fname, size fsize)
     71 {
     72 	if (fsize < 0)
     73 		return (s8){.len = -1};
     74 
     75 	i32 fd = open(fname, O_RDONLY);
     76 	if (fd < 0)
     77 		return (s8){.len = -1};
     78 
     79 	s8 ret    = s8alloc(a, fsize);
     80 	size rlen = read(fd, ret.data, ret.len);
     81 	close(fd);
     82 
     83 	if (rlen != ret.len)
     84 		return (s8){.len = -1};
     85 
     86 	return ret;
     87 }
     88 
     89 static PLATFORM_WRITE_NEW_FILE_FN(os_write_new_file)
     90 {
     91 	iptr fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0600);
     92 	if (fd == INVALID_FILE)
     93 		return 0;
     94 	b32 ret = os_write_file(fd, raw);
     95 	close(fd);
     96 	return ret;
     97 }
     98 
     99 static FileStats
    100 os_get_file_stats(char *fname)
    101 {
    102 	struct stat st;
    103 
    104 	if (stat(fname, &st) < 0) {
    105 		return ERROR_FILE_STATS;
    106 	}
    107 
    108 	return (FileStats){
    109 		.filesize  = st.st_size,
    110 		.timestamp = st.st_mtim.tv_sec + st.st_mtim.tv_nsec * 1e9,
    111 	};
    112 }
    113 
    114 static Pipe
    115 os_open_named_pipe(char *name)
    116 {
    117 	mkfifo(name, 0660);
    118 	return (Pipe){.file = open(name, O_RDONLY|O_NONBLOCK), .name = name};
    119 }
    120 
    121 static void
    122 os_close_named_pipe(Pipe p)
    123 {
    124 	close(p.file);
    125 	unlink(p.name);
    126 }
    127 
    128 static PLATFORM_POLL_PIPE_FN(os_poll_pipe)
    129 {
    130 	struct pollfd pfd = {.fd = p.file, .events = POLLIN};
    131 	poll(&pfd, 1, 0);
    132 	return !!(pfd.revents & POLLIN);
    133 }
    134 
    135 static PLATFORM_READ_PIPE_FN(os_read_pipe)
    136 {
    137 	size r = 0, total_read = 0;
    138 	do {
    139 		if (r != -1)
    140 			total_read += r;
    141 		r = read(pipe, buf + total_read, len - total_read);
    142 	} while (r);
    143 	return total_read;
    144 }
    145 
    146 static void *
    147 os_open_shared_memory_area(char *name, size cap)
    148 {
    149 	i32 fd = shm_open(name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    150 	if (fd == -1)
    151 		return NULL;
    152 
    153 	if (ftruncate(fd, cap) == -1) {
    154 		close(fd);
    155 		return NULL;
    156 	}
    157 
    158 	void *new = mmap(NULL, cap, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    159 	close(fd);
    160 
    161 	if (new == MAP_FAILED)
    162 		return NULL;
    163 
    164 	return new;
    165 }
    166 
    167 static void
    168 os_remove_shared_memory(char *name)
    169 {
    170 	shm_unlink(name);
    171 }
    172 
    173 /* NOTE: complete garbage because there is no standarized copyfile() in POSix */
    174 static b32
    175 os_copy_file(char *name, char *new)
    176 {
    177 	b32 result = 0;
    178 	struct stat sb;
    179 	if (stat(name, &sb) < 0)
    180 		return 0;
    181 
    182 	i32 fd_old = open(name, O_RDONLY);
    183 	i32 fd_new = open(new, O_WRONLY|O_TRUNC, sb.st_mode);
    184 
    185 	if (fd_old < 0 || fd_new < 0)
    186 		goto ret;
    187 	u8 buf[4096];
    188 	size copied = 0;
    189 	while (copied != sb.st_size) {
    190 		size r = read(fd_old, buf, ARRAY_COUNT(buf));
    191 		if (r < 0) goto ret;
    192 		size w = write(fd_new, buf, r);
    193 		if (w < 0) goto ret;
    194 		copied += w;
    195 	}
    196 	result = 1;
    197 ret:
    198 	if (fd_old != -1) close(fd_old);
    199 	if (fd_new != -1) close(fd_new);
    200 	return result;
    201 }
    202 
    203 static void *
    204 os_load_library(char *name, char *temp_name, Stream *e)
    205 {
    206 	if (temp_name) {
    207 		if (os_copy_file(name, temp_name))
    208 			name = temp_name;
    209 	}
    210 	void *res = dlopen(name, RTLD_NOW|RTLD_LOCAL);
    211 	if (!res && e) {
    212 		s8 errs[] = {s8("WARNING: os_load_library("), cstr_to_s8(name), s8("): "),
    213 		             cstr_to_s8(dlerror()), s8("\n")};
    214 		stream_append_s8_array(e, errs, ARRAY_COUNT(errs));
    215 		os_write_err_msg(stream_to_s8(e));
    216 		e->widx = 0;
    217 	}
    218 
    219 	if (temp_name)
    220 		unlink(temp_name);
    221 
    222 	return res;
    223 }
    224 
    225 static void *
    226 os_lookup_dynamic_symbol(void *h, char *name, Stream *e)
    227 {
    228 	if (!h)
    229 		return 0;
    230 	void *res = dlsym(h, name);
    231 	if (!res && e) {
    232 		s8 errs[] = {s8("WARNING: os_lookup_dynamic_symbol("), cstr_to_s8(name), s8("): "),
    233 		             cstr_to_s8(dlerror()), s8("\n")};
    234 		stream_append_s8_array(e, errs, ARRAY_COUNT(errs));
    235 		os_write_err_msg(stream_to_s8(e));
    236 		e->widx = 0;
    237 	}
    238 
    239 	return res;
    240 }
    241 
    242 static void
    243 os_unload_library(void *h)
    244 {
    245 	/* NOTE: glibc is buggy gnuware so we need to check this */
    246 	if (h)
    247 		dlclose(h);
    248 }