summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib_win32.c
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2015-01-09 08:55:02 +0100
committer couriersud <couriersud@arcor.de>2015-01-09 08:55:02 +0100
commitb20dd29d62351047381b659f13e8841fe13f0592 (patch)
tree8d99dc4188796d3a2a871a7b1a2c9b8ba6c24477 /src/osd/modules/lib/osdlib_win32.c
parent15a5ab001ca0779667f25d8efe59551d81f669b1 (diff)
Commit missing files. (nw)
Diffstat (limited to 'src/osd/modules/lib/osdlib_win32.c')
-rw-r--r--src/osd/modules/lib/osdlib_win32.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/osd/modules/lib/osdlib_win32.c b/src/osd/modules/lib/osdlib_win32.c
new file mode 100644
index 00000000000..108005413ba
--- /dev/null
+++ b/src/osd/modules/lib/osdlib_win32.c
@@ -0,0 +1,164 @@
+//============================================================
+//
+// winos.c - Win32 OS specific low level code
+//
+//============================================================
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+// MAME headers
+#include "osdlib.h"
+#include "osdcomm.h"
+#include "osdcore.h"
+
+//============================================================
+// MACROS
+//============================================================
+
+// presumed size of a page of memory
+#define PAGE_SIZE 4096
+
+// align allocations to start or end of the page?
+#define GUARD_ALIGN_START 0
+
+//============================================================
+// osd_num_processors
+//============================================================
+
+int osd_get_num_processors(void)
+{
+ SYSTEM_INFO info;
+
+ // otherwise, fetch the info from the system
+ GetSystemInfo(&info);
+
+ // max out at 4 for now since scaling above that seems to do poorly
+ return MIN(info.dwNumberOfProcessors, 4);
+}
+
+//============================================================
+// osd_getenv
+//============================================================
+
+char *osd_getenv(const char *name)
+{
+ return getenv(name);
+}
+
+//============================================================
+// osd_setenv
+//============================================================
+
+int osd_setenv(const char *name, const char *value, int overwrite)
+{
+ char *buf;
+ int result;
+
+ if (!overwrite)
+ {
+ if (osd_getenv(name) != NULL)
+ return 0;
+ }
+ buf = (char *) osd_malloc_array(strlen(name)+strlen(value)+2);
+ sprintf(buf, "%s=%s", name, value);
+ result = putenv(buf);
+
+ /* will be referenced by environment
+ * Therefore it is not freed here
+ */
+
+ return result;
+}
+
+//============================================================
+// osd_process_kill
+//============================================================
+
+void osd_process_kill(void)
+{
+ TerminateProcess(GetCurrentProcess(), -1);
+}
+
+//============================================================
+// osd_malloc
+//============================================================
+
+void *osd_malloc(size_t size)
+{
+#ifndef MALLOC_DEBUG
+ return HeapAlloc(GetProcessHeap(), 0, size);
+#else
+ // add in space for the size
+ size += sizeof(size_t);
+
+ // basic objects just come from the heap
+ void *result = HeapAlloc(GetProcessHeap(), 0, size);
+
+ // store the size and return and pointer to the data afterward
+ *reinterpret_cast<size_t *>(result) = size;
+ return reinterpret_cast<UINT8 *>(result) + sizeof(size_t);
+#endif
+}
+
+
+//============================================================
+// osd_malloc_array
+//============================================================
+
+void *osd_malloc_array(size_t size)
+{
+#ifndef MALLOC_DEBUG
+ return HeapAlloc(GetProcessHeap(), 0, size);
+#else
+ // add in space for the size
+ size += sizeof(size_t);
+
+ // round the size up to a page boundary
+ size_t rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
+
+ // reserve that much memory, plus two guard pages
+ void *page_base = VirtualAlloc(NULL, rounded_size + 2 * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
+ if (page_base == NULL)
+ return NULL;
+
+ // now allow access to everything but the first and last pages
+ page_base = VirtualAlloc(reinterpret_cast<UINT8 *>(page_base) + PAGE_SIZE, rounded_size, MEM_COMMIT, PAGE_READWRITE);
+ if (page_base == NULL)
+ return NULL;
+
+ // work backwards from the page base to get to the block base
+ void *result = GUARD_ALIGN_START ? page_base : (reinterpret_cast<UINT8 *>(page_base) + rounded_size - size);
+
+ // store the size at the start with a flag indicating it has a guard page
+ *reinterpret_cast<size_t *>(result) = size | 0x80000000;
+ return reinterpret_cast<UINT8 *>(result) + sizeof(size_t);
+#endif
+}
+
+
+//============================================================
+// osd_free
+//============================================================
+
+void osd_free(void *ptr)
+{
+#ifndef MALLOC_DEBUG
+ HeapFree(GetProcessHeap(), 0, ptr);
+#else
+ size_t size = reinterpret_cast<size_t *>(ptr)[-1];
+
+ // if no guard page, just free the pointer
+ if ((size & 0x80000000) == 0)
+ HeapFree(GetProcessHeap(), 0, reinterpret_cast<UINT8 *>(ptr) - sizeof(size_t));
+
+ // large items need more care
+ else
+ {
+ ULONG_PTR page_base = (reinterpret_cast<ULONG_PTR>(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1);
+ VirtualFree(reinterpret_cast<void *>(page_base - PAGE_SIZE), 0, MEM_RELEASE);
+ }
+#endif
+}