ogl_beamforming

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

os_win32.c (6452B)


      1 /* See LICENSE for license details. */
      2 
      3 #define OS_SHARED_MEMORY_NAME "Local\\ogl_beamformer_parameters"
      4 
      5 #define OS_PATH_SEPARATOR_CHAR '\\'
      6 #define OS_PATH_SEPARATOR      "\\"
      7 
      8 #include "util.h"
      9 
     10 #define STD_INPUT_HANDLE  -10
     11 #define STD_OUTPUT_HANDLE -11
     12 #define STD_ERROR_HANDLE  -12
     13 
     14 #define PAGE_READWRITE 0x04
     15 #define MEM_COMMIT     0x1000
     16 #define MEM_RESERVE    0x2000
     17 
     18 #define GENERIC_WRITE  0x40000000
     19 #define GENERIC_READ   0x80000000
     20 
     21 #define FILE_SHARE_READ            0x00000001
     22 #define FILE_MAP_ALL_ACCESS        0x000F001F
     23 #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000
     24 #define FILE_FLAG_OVERLAPPED       0x40000000
     25 
     26 #define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
     27 
     28 #define FILE_ACTION_MODIFIED 0x00000003
     29 
     30 #define CREATE_ALWAYS  2
     31 #define OPEN_EXISTING  3
     32 
     33 #define THREAD_SET_LIMITED_INFORMATION 0x0400
     34 
     35 /* NOTE: this is packed because the w32 api designers are dumb and ordered the members
     36  * incorrectly. They worked around it be making the ft* members a struct {u32, u32} which
     37  * is aligned on a 4-byte boundary. Then in their documentation they explicitly tell you not
     38  * to cast to u64 because "it can cause alignment faults on 64-bit Windows" - go figure */
     39 typedef struct w32_file_info w32_file_info;
     40 pack_struct(struct w32_file_info {
     41 	u32 dwFileAttributes;
     42 	u64 ftCreationTime;
     43 	u64 ftLastAccessTime;
     44 	u64 ftLastWriteTime;
     45 	u32 dwVolumeSerialNumber;
     46 	u32 nFileSizeHigh;
     47 	u32 nFileSizeLow;
     48 	u32 nNumberOfLinks;
     49 	u32 nFileIndexHigh;
     50 	u32 nFileIndexLow;
     51 });
     52 
     53 typedef struct {
     54 	u32 next_entry_offset;
     55 	u32 action;
     56 	u32 filename_size;
     57 	u16 filename[];
     58 } w32_file_notify_info;
     59 
     60 typedef struct {
     61 	u16  architecture;
     62 	u16  _pad1;
     63 	u32  page_size;
     64 	iz   minimum_application_address;
     65 	iz   maximum_application_address;
     66 	u64  active_processor_mask;
     67 	u32  number_of_processors;
     68 	u32  processor_type;
     69 	u32  allocation_granularity;
     70 	u16  processor_level;
     71 	u16  processor_revision;
     72 } w32_system_info;
     73 
     74 typedef struct {
     75 	uptr internal, internal_high;
     76 	union {
     77 		struct {u32 off, off_high;};
     78 		iptr pointer;
     79 	};
     80 	iptr event_handle;
     81 } w32_overlapped;
     82 
     83 typedef enum {
     84 	W32IOEvent_FileWatch,
     85 } W32IOEvent;
     86 
     87 typedef struct {
     88 	u64  tag;
     89 	iptr context;
     90 } w32_io_completion_event;
     91 
     92 typedef struct {
     93 	iptr *semaphores;
     94 	u32   reserved_count;
     95 } w32_shared_memory_context;
     96 
     97 #define W32(r) __declspec(dllimport) r __stdcall
     98 W32(b32)    CloseHandle(iptr);
     99 W32(b32)    CopyFileA(c8 *, c8 *, b32);
    100 W32(iptr)   CreateFileA(c8 *, u32, u32, void *, u32, u32, void *);
    101 W32(iptr)   CreateFileMappingA(iptr, void *, u32, u32, u32, c8 *);
    102 W32(iptr)   CreateIoCompletionPort(iptr, iptr, uptr, u32);
    103 W32(iptr)   CreateSemaphoreA(iptr, i32, i32, c8 *);
    104 W32(b32)    DeleteFileA(c8 *);
    105 W32(void)   ExitProcess(i32);
    106 W32(i32)    GetFileAttributesA(c8 *);
    107 W32(b32)    GetFileInformationByHandle(iptr, void *);
    108 W32(i32)    GetLastError(void);
    109 W32(b32)    GetQueuedCompletionStatus(iptr, u32 *, uptr *, w32_overlapped **, u32);
    110 W32(iptr)   GetStdHandle(i32);
    111 W32(void)   GetSystemInfo(w32_system_info *);
    112 W32(void *) MapViewOfFile(iptr, u32, u32, u32, u64);
    113 W32(b32)    QueryPerformanceCounter(u64 *);
    114 W32(b32)    QueryPerformanceFrequency(u64 *);
    115 W32(b32)    ReadDirectoryChangesW(iptr, u8 *, u32, b32, u32, u32 *, void *, void *);
    116 W32(b32)    ReadFile(iptr, u8 *, i32, i32 *, void *);
    117 W32(b32)    ReleaseSemaphore(iptr, i32, i32 *);
    118 W32(u32)    WaitForSingleObject(iptr, u32);
    119 W32(b32)    WaitOnAddress(void *, void *, uz, u32);
    120 W32(i32)    WakeByAddressAll(void *);
    121 W32(b32)    WriteFile(iptr, u8 *, i32, i32 *, void *);
    122 W32(void *) VirtualAlloc(u8 *, iz, u32, u32);
    123 
    124 function b32
    125 os_write_file(iptr file, void *data, i64 length)
    126 {
    127 	i32 wlen = 0;
    128 	if (length > 0 && length <= (i64)U32_MAX) WriteFile(file, data, (i32)length, &wlen, 0);
    129 	return length == wlen;
    130 }
    131 
    132 function no_return void
    133 os_exit(i32 code)
    134 {
    135 	ExitProcess(1);
    136 	unreachable();
    137 }
    138 
    139 function u64
    140 os_get_timer_frequency(void)
    141 {
    142 	u64 result;
    143 	QueryPerformanceFrequency(&result);
    144 	return result;
    145 }
    146 
    147 function u64
    148 os_get_timer_counter(void)
    149 {
    150 	u64 result;
    151 	QueryPerformanceCounter(&result);
    152 	return result;
    153 }
    154 
    155 function u32
    156 os_get_page_size(void)
    157 {
    158 	w32_system_info info = {0};
    159 	GetSystemInfo(&info);
    160 	u32 result = info.page_size;
    161 	return result;
    162 }
    163 
    164 function OS_ALLOC_ARENA_FN(os_alloc_arena)
    165 {
    166 	Arena result = {0};
    167 	capacity   = round_up_to(capacity, os_get_page_size());
    168 	result.beg = VirtualAlloc(0, capacity, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
    169 	if (result.beg) {
    170 		result.end = result.beg + capacity;
    171 		asan_poison_region(result.beg, result.end - result.beg);
    172 	}
    173 	return result;
    174 }
    175 
    176 BEAMFORMER_IMPORT OS_READ_ENTIRE_FILE_FN(os_read_entire_file)
    177 {
    178 	i64 result = 0;
    179 	w32_file_info fileinfo;
    180 	iptr h = CreateFileA((c8 *)file, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
    181 	if (h >= 0 && GetFileInformationByHandle(h, &fileinfo)) {
    182 		iz filesize  = (iz)fileinfo.nFileSizeHigh << 32;
    183 		filesize    |= (iz)fileinfo.nFileSizeLow;
    184 		if (buffer_capacity >= filesize) {
    185 			result = filesize;
    186 			i32 rlen;
    187 			if (!ReadFile(h, buffer, (i32)filesize, &rlen, 0) || rlen != filesize)
    188 				result = 0;
    189 		}
    190 	}
    191 	if (h >= 0) CloseHandle(h);
    192 
    193 	return result;
    194 }
    195 
    196 function OS_WRITE_NEW_FILE_FN(os_write_new_file)
    197 {
    198 	b32 result = 0;
    199 	iptr h = CreateFileA(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    200 	if (h >= 0) {
    201 		while (raw.len > 0) {
    202 			i64 length = MIN(raw.len, (iz)GB(2));
    203 			result     = os_write_file(h, raw.data, length);
    204 			if (!result) break;
    205 			raw = s8_cut_head(raw, length);
    206 		}
    207 		CloseHandle(h);
    208 	}
    209 	return result;
    210 }
    211 
    212 function b32
    213 os_file_exists(char *path)
    214 {
    215 	b32 result = GetFileAttributesA(path) != -1;
    216 	return result;
    217 }
    218 
    219 function b32
    220 os_copy_file(char *name, char *new)
    221 {
    222 	return CopyFileA(name, new, 0);
    223 }
    224 
    225 BEAMFORMER_IMPORT OS_WAIT_ON_ADDRESS_FN(os_wait_on_address)
    226 {
    227 	return WaitOnAddress(value, &current, sizeof(*value), timeout_ms);
    228 }
    229 
    230 BEAMFORMER_IMPORT OS_WAKE_ALL_WAITERS_FN(os_wake_all_waiters)
    231 {
    232 	if (sync) {
    233 		atomic_store_u32(sync, 0);
    234 		WakeByAddressAll(sync);
    235 	}
    236 }
    237 
    238 BEAMFORMER_IMPORT OSW32Semaphore
    239 os_w32_create_semaphore(const char *name, i32 initial_count, i32 maximum_count)
    240 {
    241 	OSW32Semaphore result = {(u64)CreateSemaphoreA(0, initial_count, maximum_count, (c8 *)name)};
    242 	return result;
    243 }
    244 
    245 BEAMFORMER_IMPORT u32
    246 os_w32_semaphore_wait(OSW32Semaphore handle, u32 timeout_ms)
    247 {
    248 	b32 result = !WaitForSingleObject(handle.value[0], timeout_ms);
    249 	return result;
    250 }
    251 
    252 BEAMFORMER_IMPORT void
    253 os_w32_semaphore_release(OSW32Semaphore handle, i32 count)
    254 {
    255 	ReleaseSemaphore(handle.value[0], count, 0);
    256 }