main_linux.c (3381B)
1 /* See LICENSE for license details. */ 2 #ifndef __linux__ 3 #error This file is only meant to be compiled for Linux 4 #endif 5 6 #include "beamformer.h" 7 8 #include "os_unix.c" 9 10 #define OS_DEBUG_LIB_NAME "./beamformer.so" 11 #define OS_DEBUG_LIB_TEMP_NAME "./beamformer_temp.so" 12 13 #define OS_CUDA_LIB_NAME "./external/cuda_toolkit.so" 14 #define OS_CUDA_LIB_TEMP_NAME "./external/cuda_toolkit_temp.so" 15 16 #define OS_RENDERDOC_SONAME "librenderdoc.so" 17 18 #define OS_PIPE_NAME "/tmp/beamformer_data_fifo" 19 #define OS_SMEM_NAME "/ogl_beamformer_parameters" 20 21 #define OS_PATH_SEPERATOR "/" 22 23 #include "static.c" 24 25 static void 26 dispatch_file_watch_events(OS *os, Arena arena) 27 { 28 FileWatchContext *fwctx = &os->file_watch_context; 29 u8 *mem = alloc_(&arena, 4096, 64, 1); 30 Stream path = stream_alloc(&arena, 256); 31 struct inotify_event *event; 32 33 iz rlen; 34 while ((rlen = read(fwctx->handle, mem, 4096)) > 0) { 35 for (u8 *data = mem; data < mem + rlen; data += sizeof(*event) + event->len) { 36 event = (struct inotify_event *)data; 37 for (u32 i = 0; i < fwctx->directory_watch_count; i++) { 38 FileWatchDirectory *dir = fwctx->directory_watches + i; 39 if (event->wd != dir->handle) 40 continue; 41 42 s8 file = c_str_to_s8(event->name); 43 u64 hash = s8_hash(file); 44 for (u32 i = 0; i < dir->file_watch_count; i++) { 45 FileWatch *fw = dir->file_watches + i; 46 if (fw->hash == hash) { 47 stream_append_s8(&path, dir->name); 48 stream_append_byte(&path, '/'); 49 stream_append_s8(&path, file); 50 stream_append_byte(&path, 0); 51 stream_commit(&path, -1); 52 fw->callback(os, stream_to_s8(&path), 53 fw->user_data, arena); 54 stream_reset(&path, 0); 55 break; 56 } 57 } 58 } 59 } 60 } 61 } 62 63 int 64 main(void) 65 { 66 BeamformerCtx ctx = {0}; 67 BeamformerInput input = {.executable_reloaded = 1}; 68 Arena temp_memory = os_alloc_arena((Arena){0}, MB(16)); 69 ctx.error_stream = stream_alloc(&temp_memory, MB(1)); 70 71 ctx.ui_backing_store = sub_arena(&temp_memory, MB(2), KB(4)); 72 ctx.os.compute_worker.arena = sub_arena(&temp_memory, MB(2), KB(4)); 73 74 Pipe data_pipe = os_open_named_pipe(OS_PIPE_NAME); 75 input.pipe_handle = data_pipe.file; 76 ASSERT(data_pipe.file != INVALID_FILE); 77 78 #define X(name) ctx.os.name = os_ ## name; 79 OS_FNS 80 #undef X 81 82 ctx.os.file_watch_context.handle = inotify_init1(O_NONBLOCK|O_CLOEXEC); 83 ctx.os.compute_worker.asleep = 1; 84 ctx.os.stderr = STDERR_FILENO; 85 86 debug_init(&ctx.os, (iptr)&input, &temp_memory); 87 setup_beamformer(&ctx, &temp_memory); 88 os_wake_thread(ctx.os.compute_worker.sync_handle); 89 90 struct pollfd fds[2] = {{0}, {0}}; 91 fds[0].fd = ctx.os.file_watch_context.handle; 92 fds[0].events = POLLIN; 93 fds[1].fd = data_pipe.file; 94 fds[1].events = POLLIN; 95 96 while (!ctx.should_exit) { 97 poll(fds, 2, 0); 98 if (fds[0].revents & POLLIN) 99 dispatch_file_watch_events(&ctx.os, temp_memory); 100 101 input.pipe_data_available = !!(fds[1].revents & POLLIN); 102 input.last_mouse = input.mouse; 103 input.mouse.rl = GetMousePosition(); 104 105 beamformer_frame_step(&ctx, &temp_memory, &input); 106 107 input.executable_reloaded = 0; 108 } 109 110 /* NOTE: make sure this will get cleaned up after external 111 * programs release their references */ 112 shm_unlink(OS_SMEM_NAME); 113 114 /* NOTE: garbage code needed for Linux */ 115 close(data_pipe.file); 116 unlink(data_pipe.name); 117 }