1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#define _GNU_SOURCE
#include "platform.h"
#include "mmap.c"
#if not HAS_MSG_DONTWAIT
#include "recv.nonblock.c"
#endif
#include "windows.c"
#include "mremap.c"
/*
* The sysconf(_SC_PAGESIZE) is the necessary alignment for using
* mmap. Windows has another notion of page size (that corresponds to
* physical page size?). Just to be safe, we take the least common
* multiple of the sysconf and Windows notions of page size.
*
* Since sysconf(_SC_PAGESIZE) might not correspond to the physical
* page size, we can't use sysconf(_SC_PHYS_PAGES) to get physical
* memory. So, use the Windows function.
*
* See: http://cygwin.com/ml/cygwin/2006-06/msg00341.html
*/
static size_t GC_pageSize_sysconf (void) {
SYSTEM_INFO sysinfo;
long int pageSize;
pageSize = sysconf (_SC_PAGESIZE);
GetSystemInfo(&sysinfo);
/* MLton_Platform_CygwinUseMmap is not set when this is called.
* Assume the worst; choose the larger allocation unit.
*/
if ((size_t)pageSize < (size_t)sysinfo.dwAllocationGranularity)
return (size_t)sysinfo.dwAllocationGranularity;
else
return (size_t)pageSize;
}
static size_t GC_pageSize_windows (void) {
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return (size_t)sysinfo.dwPageSize;
}
size_t GC_pageSize (void) {
size_t pageSize_sysconf = GC_pageSize_sysconf ();
size_t pageSize_windows = GC_pageSize_windows ();
size_t a = pageSize_sysconf;
size_t b = pageSize_windows;
size_t t;
while (b != 0) {
t = b;
b = a % b;
a = t;
}
size_t gcd = a;
size_t lcm = (pageSize_sysconf / gcd) * pageSize_windows;
return lcm;
}
uintmax_t GC_physMem (void) {
MEMORYSTATUS memstat;
memstat.dwLength = sizeof(memstat);
GlobalMemoryStatus(&memstat);
return (uintmax_t)memstat.dwTotalPhys;
}
void *GC_mmapAnon (void *start, size_t length) {
if (MLton_Platform_CygwinUseMmap)
return mmapAnon (start, length);
else
return Windows_mmapAnon (start, length);
}
void GC_release (void *base, size_t length) {
if (MLton_Platform_CygwinUseMmap)
munmap_safe (base, length);
else
Windows_release (base, length);
}
void* GC_extendHead (void *base, size_t length) {
if (MLton_Platform_CygwinUseMmap)
return mmapAnon (base, length);
else
return Windows_mmapAnon (base, length);
}
void* GC_extendTail (void *base, size_t length) {
if (MLton_Platform_CygwinUseMmap)
return mmapAnon (base, length);
else
return Windows_extend (base, length);
}
HANDLE fileDesHandle (int fd) {
// The temporary prevents a "cast does not match function type" warning.
long t;
t = get_osfhandle (fd);
return (HANDLE)t;
}
/* ------------------------------------------------- */
/* Cygwin */
/* ------------------------------------------------- */
C_String_t Cygwin_toFullWindowsPath (NullString8_t path) {
static char res[MAX_PATH];
#if ((CYGWIN_VERSION_API_MAJOR > 0) || (CYGWIN_VERSION_API_MINOR > 181))
cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE,
(char*)path, &res[0], MAX_PATH);
#else
cygwin_conv_to_full_win32_path ((char*)path, &res[0]);
#endif
return (C_String_t)&res[0];
}
/* ------------------------------------------------- */
/* Posix */
/* ------------------------------------------------- */
void Posix_IO_setbin (C_Fd_t fd) {
/* cygwin has a different method for working with its fds */
setmode (fd, O_BINARY);
}
void Posix_IO_settext (C_Fd_t fd) {
/* cygwin has a different method for working with its fds */
setmode (fd, O_TEXT);
}
|