ogl_beamforming

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

base_win32.c (7796B)


      1 /* See LICENSE for license details. */
      2 
      3 /* NOTE(rnp): provides the platform layer for everything in this repo. */
      4 
      5 #define OS_SHARED_MEMORY_NAME "Local\\ogl_beamformer_parameters"
      6 
      7 #define OS_PATH_SEPARATOR_CHAR '\\'
      8 #define OS_PATH_SEPARATOR      "\\"
      9 
     10 #include "base_platform.h"
     11 
     12 #include "util.h"
     13 
     14 #define STD_INPUT_HANDLE  -10
     15 #define STD_OUTPUT_HANDLE -11
     16 #define STD_ERROR_HANDLE  -12
     17 
     18 #define PAGE_READONLY  0x02
     19 #define PAGE_READWRITE 0x04
     20 #define MEM_COMMIT     0x1000
     21 #define MEM_RESERVE    0x2000
     22 #define MEM_DECOMMIT   0x4000
     23 #define MEM_RELEASE    0x8000
     24 
     25 #define GENERIC_WRITE  0x40000000
     26 #define GENERIC_READ   0x80000000
     27 
     28 #define FILE_SHARE_READ            0x00000001
     29 #define FILE_MAP_ALL_ACCESS        0x000F001F
     30 #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000
     31 #define FILE_FLAG_OVERLAPPED       0x40000000
     32 
     33 #define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
     34 
     35 #define FILE_ACTION_MODIFIED 0x00000003
     36 
     37 #define CREATE_ALWAYS  2
     38 #define OPEN_EXISTING  3
     39 
     40 #define THREAD_SET_LIMITED_INFORMATION 0x0400
     41 
     42 /* NOTE: this is packed because the w32 api designers are dumb and ordered the members
     43  * incorrectly. They worked around it be making the ft* members a struct {u32, u32} which
     44  * is aligned on a 4-byte boundary. Then in their documentation they explicitly tell you not
     45  * to cast to u64 because "it can cause alignment faults on 64-bit Windows" - go figure */
     46 typedef struct w32_file_info w32_file_info;
     47 pack_struct(struct w32_file_info {
     48 	u32 dwFileAttributes;
     49 	u64 ftCreationTime;
     50 	u64 ftLastAccessTime;
     51 	u64 ftLastWriteTime;
     52 	u32 dwVolumeSerialNumber;
     53 	u32 nFileSizeHigh;
     54 	u32 nFileSizeLow;
     55 	u32 nNumberOfLinks;
     56 	u32 nFileIndexHigh;
     57 	u32 nFileIndexLow;
     58 });
     59 
     60 typedef struct {
     61 	u32 next_entry_offset;
     62 	u32 action;
     63 	u32 filename_size;
     64 	u16 filename[];
     65 } w32_file_notify_info;
     66 
     67 typedef struct {
     68 	u16  architecture;
     69 	u16  _pad1;
     70 	u32  page_size;
     71 	i64  minimum_application_address;
     72 	i64  maximum_application_address;
     73 	u64  active_processor_mask;
     74 	u32  number_of_processors;
     75 	u32  processor_type;
     76 	u32  allocation_granularity;
     77 	u16  processor_level;
     78 	u16  processor_revision;
     79 } w32_system_info;
     80 
     81 typedef struct {
     82 	uptr internal, internal_high;
     83 	union {
     84 		struct {u32 off, off_high;};
     85 		iptr pointer;
     86 	};
     87 	iptr event_handle;
     88 } w32_overlapped;
     89 
     90 typedef enum {
     91 	W32IOEvent_FileWatch,
     92 } W32IOEvent;
     93 
     94 typedef struct {
     95 	u64  tag;
     96 	iptr context;
     97 } w32_io_completion_event;
     98 
     99 typedef struct {
    100 	iptr *semaphores;
    101 	u32   reserved_count;
    102 } w32_shared_memory_context;
    103 
    104 #define W32(r) __declspec(dllimport) r __stdcall
    105 W32(b32)    CloseHandle(iptr);
    106 W32(b32)    CopyFileA(c8 *, c8 *, b32);
    107 W32(iptr)   CreateFileA(c8 *, u32, u32, void *, u32, u32, void *);
    108 W32(iptr)   CreateFileMappingA(iptr, void *, u32, u32, u32, c8 *);
    109 W32(iptr)   CreateIoCompletionPort(iptr, iptr, uptr, u32);
    110 W32(iptr)   CreateSemaphoreA(iptr, i32, i32, c8 *);
    111 W32(b32)    DeleteFileA(c8 *);
    112 W32(void)   ExitProcess(i32);
    113 W32(i32)    GetFileAttributesA(c8 *);
    114 W32(b32)    GetFileInformationByHandle(iptr, void *);
    115 W32(i32)    GetLastError(void);
    116 W32(b32)    GetQueuedCompletionStatus(iptr, u32 *, uptr *, w32_overlapped **, u32);
    117 W32(iptr)   GetStdHandle(i32);
    118 W32(void)   GetSystemInfo(w32_system_info *);
    119 W32(void *) MapViewOfFile(iptr, u32, u32, u32, u64);
    120 W32(b32)    QueryPerformanceCounter(u64 *);
    121 W32(b32)    QueryPerformanceFrequency(u64 *);
    122 W32(b32)    ReadDirectoryChangesW(iptr, u8 *, u32, b32, u32, u32 *, void *, void *);
    123 W32(b32)    ReadFile(iptr, u8 *, i32, i32 *, void *);
    124 W32(b32)    ReleaseSemaphore(iptr, i32, i32 *);
    125 W32(u32)    WaitForSingleObject(iptr, u32);
    126 W32(b32)    WaitOnAddress(void *, void *, u64, u32);
    127 W32(i32)    WakeByAddressAll(void *);
    128 W32(b32)    WriteFile(iptr, u8 *, i32, i32 *, void *);
    129 W32(void *) VirtualAlloc(u8 *, i64, u32, u32);
    130 W32(b32)    VirtualFree(void *, u64, u32);
    131 W32(b32)    VirtualProtect(void *, u64, u32, u32 *);
    132 
    133 global OSSystemInfo win32_system_info;
    134 
    135 function b32
    136 os_write_file(iptr file, void *data, i64 length)
    137 {
    138 	i32 wlen = 0;
    139 	if (length > 0 && length <= (i64)U32_MAX) WriteFile(file, data, (i32)length, &wlen, 0);
    140 	return length == wlen;
    141 }
    142 
    143 BASE_EXPORT no_return void
    144 os_exit(i32 code)
    145 {
    146 	ExitProcess(code);
    147 	unreachable();
    148 }
    149 
    150 function u64
    151 os_timer_frequency(void)
    152 {
    153 	u64 result;
    154 	QueryPerformanceFrequency(&result);
    155 	return result;
    156 }
    157 
    158 BASE_EXPORT u64
    159 os_timer_count(void)
    160 {
    161 	u64 result;
    162 	QueryPerformanceCounter(&result);
    163 	return result;
    164 }
    165 
    166 function void
    167 os_system_info_init(void)
    168 {
    169 	w32_system_info info = {0};
    170 	GetSystemInfo(&info);
    171 
    172 	win32_system_info.timer_frequency         = os_timer_frequency();
    173 	win32_system_info.logical_processor_count = info.number_of_processors;
    174 	win32_system_info.page_size               = info.page_size;
    175 	win32_system_info.path_separator_byte     = '\\';
    176 }
    177 
    178 BASE_EXPORT OSSystemInfo *
    179 os_system_info(void)
    180 {
    181 	#if BASE_PLATFORM_NO_MAIN
    182 	if unlikely(win32_system_info.path_separator_byte == 0)
    183 		os_system_info_init();
    184 	#endif
    185 	return &win32_system_info;
    186 }
    187 
    188 BASE_EXPORT void *
    189 os_memory_reserve(u64 size)
    190 {
    191 	void *result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
    192 	return result;
    193 }
    194 
    195 BASE_EXPORT void
    196 os_memory_release(void *base, u64 size)
    197 {
    198 	// NOTE(rnp): size must be 0 on w32, no partial releasing
    199 	VirtualFree(base, 0, MEM_RELEASE);
    200 }
    201 
    202 BASE_EXPORT b32
    203 os_memory_commit(void *base, u64 size)
    204 {
    205 	b32 result = VirtualAlloc(base, size, MEM_COMMIT, PAGE_READWRITE) != 0;
    206 	return result;
    207 }
    208 
    209 BASE_EXPORT void
    210 os_memory_uncommit(void *base, u64 size)
    211 {
    212 	VirtualFree(base, size, MEM_DECOMMIT);
    213 }
    214 
    215 BASE_EXPORT void
    216 os_memory_seal(void *base, u64 size)
    217 {
    218 	u32 w32_dummy;
    219 	VirtualProtect(base, size, PAGE_READONLY, &w32_dummy);
    220 }
    221 
    222 BASE_EXPORT OSW32Semaphore
    223 os_w32_create_semaphore(const char *name, i32 initial_count, i32 maximum_count)
    224 {
    225 	OSW32Semaphore result = {(u64)CreateSemaphoreA(0, initial_count, maximum_count, (c8 *)name)};
    226 	return result;
    227 }
    228 
    229 BASE_EXPORT u32
    230 os_w32_semaphore_wait(OSW32Semaphore handle, u32 timeout_ms)
    231 {
    232 	b32 result = !WaitForSingleObject(handle.value[0], timeout_ms);
    233 	return result;
    234 }
    235 
    236 BASE_EXPORT void
    237 os_w32_semaphore_release(OSW32Semaphore handle, i32 count)
    238 {
    239 	ReleaseSemaphore(handle.value[0], count, 0);
    240 }
    241 
    242 BASE_EXPORT str8
    243 os_read_entire_file(Arena *arena, const char *file)
    244 {
    245 	str8 result = {0};
    246 	w32_file_info fileinfo;
    247 	iptr h = CreateFileA((c8 *)file, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
    248 	if (h >= 0 && GetFileInformationByHandle(h, &fileinfo)) {
    249 		i64 filesize  = (i64)fileinfo.nFileSizeHigh << 32;
    250 		filesize     |= (i64)fileinfo.nFileSizeLow;
    251 		result.data   = push_array(arena, u8, filesize);
    252 		result.length = filesize;
    253 		i32 rlen;
    254 		if (!ReadFile(h, result.data, (i32)filesize, &rlen, 0) || rlen != filesize) {
    255 			arena_pop(arena, filesize);
    256 			zero_struct(&result);
    257 		}
    258 	}
    259 	if (h >= 0) CloseHandle(h);
    260 
    261 	return result;
    262 }
    263 
    264 function b32
    265 os_write_new_file(char *fname, str8 raw)
    266 {
    267 	b32 result = 0;
    268 	iptr h = CreateFileA(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    269 	if (h >= 0) {
    270 		while (raw.length > 0) {
    271 			i64 length = Min(raw.length, (i64)GB(2));
    272 			result     = os_write_file(h, raw.data, length);
    273 			if (!result) break;
    274 			raw = str8_cut_head(raw, length);
    275 		}
    276 		CloseHandle(h);
    277 	}
    278 	return result;
    279 }
    280 
    281 function b32
    282 os_file_exists(char *path)
    283 {
    284 	b32 result = GetFileAttributesA(path) != -1;
    285 	return result;
    286 }
    287 
    288 function b32
    289 os_copy_file(char *name, char *new)
    290 {
    291 	return CopyFileA(name, new, 0);
    292 }
    293 
    294 BASE_EXPORT b32
    295 os_wait_on_address(i32 *value, i32 current, u32 timeout_ms)
    296 {
    297 	return WaitOnAddress(value, &current, sizeof(*value), timeout_ms);
    298 }
    299 
    300 BASE_EXPORT void
    301 os_wake_all_waiters(i32 *sync)
    302 {
    303 	if (sync) {
    304 		atomic_store_u32(sync, 0);
    305 		WakeByAddressAll(sync);
    306 	}
    307 }
    308 
    309 #if !BASE_PLATFORM_NO_MAIN
    310 BASE_IMPORT void entry_point(i32 argc, char *argv[]);
    311 
    312 extern i32
    313 main(i32 argc, char *argv[])
    314 {
    315 	os_system_info_init();
    316 
    317 	entry_point(argc, argv);
    318 
    319 	return 0;
    320 }
    321 #endif