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