ogl_beamforming

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

os_win32.c (7150B)


      1 /* See LICENSE for license details. */
      2 #include "util.h"
      3 
      4 #define STD_OUTPUT_HANDLE -11
      5 #define STD_ERROR_HANDLE  -12
      6 
      7 #define PAGE_READWRITE 0x04
      8 #define MEM_COMMIT     0x1000
      9 #define MEM_RESERVE    0x2000
     10 #define MEM_RELEASE    0x8000
     11 #define GENERIC_WRITE  0x40000000
     12 #define GENERIC_READ   0x80000000
     13 
     14 #define PIPE_TYPE_BYTE      0x00
     15 #define PIPE_ACCESS_INBOUND 0x01
     16 
     17 #define FILE_MAP_ALL_ACCESS 0x000F001F
     18 
     19 #define CREATE_ALWAYS  2
     20 #define OPEN_EXISTING  3
     21 
     22 typedef struct {
     23 	u16  wProcessorArchitecture;
     24 	u16  _pad1;
     25 	u32  dwPageSize;
     26 	size lpMinimumApplicationAddress;
     27 	size lpMaximumApplicationAddress;
     28 	u64  dwActiveProcessorMask;
     29 	u32  dwNumberOfProcessors;
     30 	u32  dwProcessorType;
     31 	u32  dwAllocationGranularity;
     32 	u16  wProcessorLevel;
     33 	u16  wProcessorRevision;
     34 } w32_sys_info;
     35 
     36 /* NOTE: this is packed because the w32 api designers are dumb and ordered the members
     37  * incorrectly. They worked around it be making the ft* members a struct {u32, u32} which
     38  * is aligned on a 4-byte boundary. Then in their documentation they explicitly tell you not
     39  * to cast to u64 because "it can cause alignment faults on 64-bit Windows" - go figure */
     40 typedef struct __attribute__((packed)) {
     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 } w32_file_info;
     52 
     53 #define W32(r) __declspec(dllimport) r __stdcall
     54 W32(b32)    CloseHandle(iptr);
     55 W32(b32)    CopyFileA(c8 *, c8 *, b32);
     56 W32(iptr)   CreateFileA(c8 *, u32, u32, void *, u32, u32, void *);
     57 W32(iptr)   CreateFileMappingA(iptr, void *, u32, u32, u32, c8 *);
     58 W32(iptr)   CreateNamedPipeA(c8 *, u32, u32, u32, u32, u32, u32, void *);
     59 W32(b32)    DeleteFileA(c8 *);
     60 W32(void)   ExitProcess(i32);
     61 W32(b32)    FreeLibrary(void *);
     62 W32(b32)    GetFileInformationByHandle(iptr, w32_file_info *);
     63 W32(i32)    GetLastError(void);
     64 W32(void *) GetProcAddress(void *, c8 *);
     65 W32(iptr)   GetStdHandle(i32);
     66 W32(void)   GetSystemInfo(void *);
     67 W32(void *) LoadLibraryA(c8 *);
     68 W32(void *) MapViewOfFile(iptr, u32, u32, u32, u64);
     69 W32(b32)    PeekNamedPipe(iptr, u8 *, i32, i32 *, i32 *, i32 *);
     70 W32(b32)    ReadFile(iptr, u8 *, i32, i32 *, void *);
     71 W32(b32)    WriteFile(iptr, u8 *, i32, i32 *, void *);
     72 W32(void *) VirtualAlloc(u8 *, size, u32, u32);
     73 W32(b32)    VirtualFree(u8 *, size, u32);
     74 
     75 static iptr win32_stderr_handle;
     76 
     77 static PLATFORM_WRITE_FILE_FN(os_write_file)
     78 {
     79 	i32 wlen;
     80 	WriteFile(file, raw.data, raw.len, &wlen, 0);
     81 	return raw.len == wlen;
     82 }
     83 
     84 static void
     85 os_write_err_msg(s8 msg)
     86 {
     87 	if (!win32_stderr_handle)
     88 		win32_stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
     89 	os_write_file(win32_stderr_handle, msg);
     90 }
     91 
     92 static void __attribute__((noreturn))
     93 os_fatal(s8 msg)
     94 {
     95 	os_write_err_msg(msg);
     96 	ExitProcess(1);
     97 	unreachable();
     98 }
     99 
    100 static PLATFORM_ALLOC_ARENA_FN(os_alloc_arena)
    101 {
    102 	Arena result;
    103 	w32_sys_info Info;
    104 	GetSystemInfo(&Info);
    105 
    106 	if (capacity % Info.dwPageSize != 0)
    107 		capacity += (Info.dwPageSize - capacity % Info.dwPageSize);
    108 
    109 	size oldsize = old.end - old.beg;
    110 	if (oldsize > capacity)
    111 		return old;
    112 
    113 	if (old.beg)
    114 		VirtualFree(old.beg, oldsize, MEM_RELEASE);
    115 
    116 	result.beg = VirtualAlloc(0, capacity, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
    117 	if (result.beg == NULL)
    118 		os_fatal(s8("os_alloc_arena: couldn't allocate memory\n"));
    119 	result.end = result.beg + capacity;
    120 	return result;
    121 }
    122 
    123 static PLATFORM_CLOSE_FN(os_close)
    124 {
    125 	CloseHandle(file);
    126 }
    127 
    128 static PLATFORM_OPEN_FOR_WRITE_FN(os_open_for_write)
    129 {
    130 	iptr result = CreateFileA(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    131 	return result;
    132 }
    133 
    134 static s8
    135 os_read_file(Arena *a, char *fname, size fsize)
    136 {
    137 	if (fsize < 0)
    138 		return (s8){.len = -1};
    139 
    140 	if (fsize > (size)U32_MAX) {
    141 		os_write_err_msg(s8("os_read_file: files >4GB are not yet handled on win32\n"));
    142 		return (s8){.len = -1};
    143 	}
    144 
    145 	iptr h = CreateFileA(fname, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
    146 	if (h == INVALID_FILE)
    147 		return (s8){.len = -1};
    148 
    149 	s8 ret = s8alloc(a, fsize);
    150 
    151 	i32 rlen  = 0;
    152 	b32 error = !ReadFile(h, ret.data, ret.len, &rlen, 0) || rlen != ret.len;
    153 	CloseHandle(h);
    154 	if (error)
    155 		return (s8){.len = -1};
    156 
    157 	return ret;
    158 }
    159 
    160 static PLATFORM_WRITE_NEW_FILE_FN(os_write_new_file)
    161 {
    162 	if (raw.len > (size)U32_MAX) {
    163 		os_write_err_msg(s8("os_write_file: files >4GB are not yet handled on win32\n"));
    164 		return 0;
    165 	}
    166 
    167 	iptr h = CreateFileA(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    168 	if (h == INVALID_FILE)
    169 		return  0;
    170 
    171 	b32 ret = os_write_file(h, raw);
    172 	CloseHandle(h);
    173 
    174 	return ret;
    175 }
    176 
    177 static FileStats
    178 os_get_file_stats(char *fname)
    179 {
    180 	iptr h = CreateFileA(fname, 0, 0, 0, OPEN_EXISTING, 0, 0);
    181 	if (h == INVALID_FILE)
    182 		return ERROR_FILE_STATS;
    183 
    184 	w32_file_info fileinfo;
    185 	if (!GetFileInformationByHandle(h, &fileinfo)) {
    186 		os_write_err_msg(s8("os_get_file_stats: couldn't get file info\n"));
    187 		CloseHandle(h);
    188 		return ERROR_FILE_STATS;
    189 	}
    190 	CloseHandle(h);
    191 
    192 	size filesize = (size)fileinfo.nFileSizeHigh << 32;
    193 	filesize     |= (size)fileinfo.nFileSizeLow;
    194 
    195 	return (FileStats){.filesize  = filesize, .timestamp = fileinfo.ftLastWriteTime};
    196 }
    197 
    198 static Pipe
    199 os_open_named_pipe(char *name)
    200 {
    201 	iptr h = CreateNamedPipeA(name, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, 1,
    202 	                          0, 1 * MEGABYTE, 0, 0);
    203 	return (Pipe){.file = h, .name = name};
    204 }
    205 
    206 /* NOTE: win32 doesn't pollute the filesystem so no need to waste the user's time */
    207 static void
    208 os_close_named_pipe(Pipe p)
    209 {
    210 }
    211 
    212 static PLATFORM_POLL_PIPE_FN(os_poll_pipe)
    213 {
    214 	i32 bytes_available = 0;
    215 	return PeekNamedPipe(p.file, 0, 1 * MEGABYTE, 0, &bytes_available, 0) && bytes_available;
    216 }
    217 
    218 static PLATFORM_READ_PIPE_FN(os_read_pipe)
    219 {
    220 	i32 total_read = 0;
    221 	ReadFile(pipe, buf, len, &total_read, 0);
    222 	return total_read;
    223 }
    224 
    225 static void *
    226 os_open_shared_memory_area(char *name, size cap)
    227 {
    228 	iptr h = CreateFileMappingA(-1, 0, PAGE_READWRITE, 0, cap, name);
    229 	if (h == INVALID_FILE)
    230 		return NULL;
    231 
    232 	return MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, cap);
    233 }
    234 
    235 /* NOTE: closing the handle releases the memory and this happens when program terminates */
    236 static void
    237 os_remove_shared_memory(char *name)
    238 {
    239 }
    240 
    241 static void *
    242 os_load_library(char *name, char *temp_name, Stream *e)
    243 {
    244 	if (temp_name) {
    245 		if (CopyFileA(name, temp_name, 0))
    246 			name = temp_name;
    247 	}
    248 
    249 	void *res = LoadLibraryA(name);
    250 	if (!res && e) {
    251 		s8 errs[] = {s8("WARNING: os_load_library("), cstr_to_s8(name), s8("): ")};
    252 		stream_append_s8_array(e, errs, ARRAY_COUNT(errs));
    253 		stream_append_i64(e, GetLastError());
    254 		stream_append_byte(e, '\n');
    255 		os_write_err_msg(stream_to_s8(e));
    256 		e->widx = 0;
    257 	}
    258 
    259 	if (temp_name)
    260 		DeleteFileA(temp_name);
    261 
    262 	return res;
    263 }
    264 
    265 static void *
    266 os_lookup_dynamic_symbol(void *h, char *name, Stream *e)
    267 {
    268 	if (!h)
    269 		return 0;
    270 	void *res = GetProcAddress(h, name);
    271 	if (!res && e) {
    272 		s8 errs[] = {s8("WARNING: os_lookup_dynamic_symbol("), cstr_to_s8(name), s8("): ")};
    273 		stream_append_s8_array(e, errs, ARRAY_COUNT(errs));
    274 		stream_append_i64(e, GetLastError());
    275 		stream_append_byte(e, '\n');
    276 		os_write_err_msg(stream_to_s8(e));
    277 		e->widx = 0;
    278 	}
    279 	return res;
    280 }
    281 
    282 static void
    283 os_unload_library(void *h)
    284 {
    285 	FreeLibrary(h);
    286 }