[MLton-devel] NetBSD porting and problems
Jesper Louis Andersen
jlouis@mongers.org
Tue, 5 Aug 2003 12:41:12 +0100
Quoting Matthew Fluet (fluet@cs.cornell.edu):
> > Unfortunately it goes like this:
>
> It is almost certainly not a GC bug; a bug in the GC will usually manifest
> as a core dump, rather than some error message.
Ah, yes, but of course. That makes sense
Ok patch follows, commented. Do not apply it blindingly, but read
through the comments first. The bootstrapping is done from SML/NJ, which
has not been updated for NetBSD for quite some time. What applies to the
SML/NJ patch for OpenBSD at:
http://j.mongers.org/pub/patches/2003-05-28/smlnj-openbsd-patches.tar.gz
applies to NetBSD as well, so floating point traps in SML/NJ are broken
and not precise in their error messages. We ignore that and hope MLton
does not abuse that part.
Furthermore, we cannot bootstrap MLton without MLton itself. We need
mllex and mlyacc in the MLton version. That can be handled by the pretty
Linux-emulation NetBSD has, so we run the linux version of MLton through
the emulation layer (on a suse-linux base-system in fact), and we hope
this does not break anything again
Time for the patch:
We need to be able to recognize that we are running on NetBSD:
diff -ur mlton-cvs/mlton/bin/host-os mlton-netbsd/bin/host-os
--- mlton-cvs/mlton/bin/host-os Fri Apr 11 06:31:09 2003
+++ mlton-netbsd/bin/host-os Sat Aug 2 21:33:51 2003
@@ -19,6 +19,9 @@
FreeBSD*)
os=freebsd
;;
+NetBSD*)
+ os=netbsd
+;;
SunOS)
os=sunos
;;
We also need to teach the SML part of MLton about a new citizen:
diff -ur mlton-cvs/mlton/lib/mlton-stubs/mlton.sml mlton-netbsd/lib/mlton-stubs/mlton.sml
--- mlton-cvs/mlton/lib/mlton-stubs/mlton.sml Tue Jul 8 03:51:47 2003
+++ mlton-netbsd/lib/mlton-stubs/mlton.sml Sat Aug 2 21:33:51 2003
@@ -38,7 +38,7 @@
val deserialize = fn _ => raise Fail "deserialize"
val eq = fn _ => false
val errno = fn _ => raise Fail "errno"
- datatype hostType = Cygwin | FreeBSD | Linux | Sun
+ datatype hostType = Cygwin | FreeBSD | NetBSD | Linux | Sun
val hostType = Linux
val isMLton = false
val safe = true
@@ -149,7 +149,7 @@
val arch: arch = X86
- datatype os = Cygwin | FreeBSD | Linux | SunOS
+ datatype os = Cygwin | FreeBSD | NetBSD | Linux | SunOS
val os: os = SunOS
end
diff -ur mlton-cvs/mlton/lib/mlton-stubs/platform.sig mlton-netbsd/lib/mlton-stubs/platform.sig
--- mlton-cvs/mlton/lib/mlton-stubs/platform.sig Fri Apr 11 06:31:10 2003
+++ mlton-netbsd/lib/mlton-stubs/platform.sig Sat Aug 2 21:33:51 2003
@@ -3,6 +3,6 @@
datatype arch = Sparc | X86
val arch: arch
- datatype os = Cygwin | FreeBSD | Linux | SunOS
+ datatype os = Cygwin | FreeBSD | NetBSD | Linux | SunOS
val os: os
end
NetBSD is like most UNIXen, so it should be instructed to leave Esp
alone and not drop a leading _:
diff -ur mlton-cvs/mlton/mlton/codegen/x86-codegen/x86-codegen.fun mlton-netbsd/mlton/codegen/x86-codegen/x86-codegen.fun
--- mlton-cvs/mlton/mlton/codegen/x86-codegen/x86-codegen.fun Fri Jul 25 22:14:47 2003
+++ mlton-netbsd/mlton/codegen/x86-codegen/x86-codegen.fun Sat Aug 2 22:18:38 2003
@@ -95,6 +95,7 @@
case !Control.hostOS of
Control.Cygwin => true
| Control.FreeBSD => false
+ | Control.NetBSD => false
| Control.Linux => false
| _ => Error.bug "x86 can't handle hostType"
@@ -160,6 +161,7 @@
case !Control.hostOS of
Control.Cygwin => String.dropPrefix (mainLabel, 1)
| Control.FreeBSD => mainLabel
+ | Control.NetBSD => mainLabel
| Control.Linux => mainLabel
| _ => Error.bug "x86 can't handle hostType"
in
Line converts, as most other OS's
diff -ur mlton-cvs/mlton/mlton/codegen/x86-codegen/x86-mlton-basic.fun mlton-netbsd/mlton/codegen/x86-codegen/x86-mlton-basic.fun
--- mlton-cvs/mlton/mlton/codegen/x86-codegen/x86-mlton-basic.fun Fri Aug 1 01:10:33 2003
+++ mlton-netbsd/mlton/codegen/x86-codegen/x86-mlton-basic.fun Sat Aug 2 22:19:19 2003
@@ -374,6 +374,7 @@
Label.fromString (case !Control.hostOS of
Control.Cygwin => "_LINE__"
| Control.FreeBSD => "__LINE__"
+ | Control.NetBSD => "__LINE__"
| Control.Linux => "__LINE__"
| _ => Error.bug "x86 can't handle hostOS"))
The hosttype should be so we can convert it to a string:
diff -ur mlton-cvs/mlton/mlton/control/control.sml mlton-netbsd/mlton/control/control.sml
--- mlton-cvs/mlton/mlton/control/control.sml Tue Jul 8 00:50:29 2003
+++ mlton-netbsd/mlton/control/control.sml Sat Aug 2 21:33:51 2003
@@ -167,6 +167,7 @@
val toString =
fn Cygwin => "Cygwin"
| FreeBSD => "FreeBSD"
+ | NetBSD => "NetBSD"
| Linux => "Linux"
| SunOS => "SunOS"
end
This was a hack I added in order to be able to simple look inside the
elaborator to confirm it got loaded correctly in SML/NJ. It can be
disregarded and should be removed in the final version.
diff -ur mlton-cvs/mlton/mlton/main/compile.sig mlton-netbsd/mlton/main/compile.sig
--- mlton-cvs/mlton/mlton/main/compile.sig Thu Jul 17 02:01:29 2003
+++ mlton-netbsd/mlton/main/compile.sig Sat Aug 2 22:45:29 2003
@@ -7,6 +7,8 @@
*)
signature COMPILE =
sig
+ structure Elaborate: ELABORATE
+
val compile: {input: File.t list,
outputC: unit -> {file: File.t,
print: string -> unit,
When reading the hostmap, teach MLton to recognize "netbsd" as the
hostType NetBSD. Furthermore, teach the gcc linking part of MLton to use rpath
directives for finding and linking libgmp into the binary. Used here are
POSIX compliant directives.
diff -ur mlton-cvs/mlton/mlton/main/main.sml mlton-netbsd/mlton/main/main.sml
--- mlton-cvs/mlton/mlton/main/main.sml Thu Jul 17 02:03:09 2003
+++ mlton-netbsd/mlton/main/main.sml Sat Aug 2 22:31:53 2003
@@ -71,6 +71,7 @@
case os of
"cygwin" => Control.Cygwin
| "freebsd" => Control.FreeBSD
+ | "netbsd" => Control.NetBSD
| "linux" => Control.Linux
| "sunos" => Control.SunOS
| _ => Error.bug (concat ["strange os: ", os])
@@ -615,6 +616,10 @@
case !hostOS of
Cygwin => ["-lgmp"]
| FreeBSD => ["-L/usr/local/lib/", "-lgmp"]
+ (* NetBSD explicitly uses rpath directives for all
+ libraries and does never rely on ldconfig or
+ $LD_LIBRARY_PATH *)
+ | NetBSD => ["-Wl,-R/usr/pkg/lib -L/usr/pkg/lib", "-lgmp"]
| Linux =>
let
val conf = "/etc/ld.so.conf"
IntInf representation, where is gmp.h?
diff -ur mlton-cvs/mlton/runtime/IntInf.h mlton-netbsd/runtime/IntInf.h
--- mlton-cvs/mlton/runtime/IntInf.h Thu Apr 10 04:03:10 2003
+++ mlton-netbsd/runtime/IntInf.h Sat Aug 2 21:33:51 2003
@@ -24,6 +24,13 @@
* MLton package.
*/
#include "/usr/local/include/gmp.h"
+#elif (defined (__NetBSD__))
+/* On NetBSD, we want gmp to be installed into the pkg tree (which represents
+ * the FreeBSD ports tree). For now we use the same method as in the FreeBSD
+ * case, but we note that this should be changed so the makefile provides the
+ * correct -I flags to the compiler
+ */
+#include "/usr/pkg/include/gmp.h"
#elif (defined (__linux__) || defined (__sun__))
#include <gmp.h>
#else
NetBSD uses the same filesystem as FreeBSD (Berkeley FFS), so we do not
have to pass O_LARGEFILE. Besides that, the semantics for open are the
same.
diff -ur mlton-cvs/mlton/runtime/Posix/FileSys/open.c mlton-netbsd/runtime/Posix/FileSys/open.c
--- mlton-cvs/mlton/runtime/Posix/FileSys/open.c Fri May 2 00:35:33 2003
+++ mlton-netbsd/runtime/Posix/FileSys/open.c Sat Aug 2 21:33:51 2003
@@ -4,13 +4,13 @@
#include "mlton-posix.h"
/* FreeBSD uses 64 bits files by default, so doesn't have O_LARGEFILE. */
-#if (defined __FreeBSD__)
+#if (defined (__FreeBSD__) || defined (__NetBSD__))
#define O_LARGEFILE 0
#endif
Int Posix_FileSys_open (NullString p, Word w, Mode m) {
-#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
return open ((char *) p, w | O_LARGEFILE, m);
Setenv(), simple:
diff -ur mlton-cvs/mlton/runtime/Posix/ProcEnv/setenv.c mlton-netbsd/runtime/Posix/ProcEnv/setenv.c
--- mlton-cvs/mlton/runtime/Posix/ProcEnv/setenv.c Thu Apr 10 04:03:11 2003
+++ mlton-netbsd/runtime/Posix/ProcEnv/setenv.c Sat Aug 2 21:33:51 2003
@@ -3,7 +3,7 @@
-#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__linux__))
+#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__linux__) || defined (__NetBSD__))
Int Posix_ProcEnv_setenv (NullString s, NullString v) {
return setenv ((char *)s, (char *)v, 1);
Signal handling like POSIX mostly:
diff -ur mlton-cvs/mlton/runtime/Posix/Signal/Signal.c mlton-netbsd/runtime/Posix/Signal/Signal.c
--- mlton-cvs/mlton/runtime/Posix/Signal/Signal.c Mon Jun 23 06:59:01 2003
+++ mlton-netbsd/runtime/Posix/Signal/Signal.c Sat Aug 2 21:33:51 2003
@@ -10,7 +10,7 @@
}
enum {
-#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
SA_FLAGS = SA_ONSTACK,
#elif (defined (__CYGWIN__))
SA_FLAGS = 0,
This is something I am not sure is good. I think it is nothing more than
an enumerated datatype so I just added MLton_Platform_os 4 for NetBSD
and are hoping the system uses switch {} semantics for handling it and
always provides a default case which panics.
prtrace() is ignored, since it can be added when the rest of the system
is up and running.
diff -ur mlton-cvs/mlton/runtime/basis-constants.h mlton-netbsd/runtime/basis-constants.h
--- mlton-cvs/mlton/runtime/basis-constants.h Fri Jun 6 00:57:14 2003
+++ mlton-netbsd/runtime/basis-constants.h Sat Aug 2 21:33:51 2003
@@ -46,6 +46,8 @@
#define MLton_Platform_os 2
#elif (defined (__sun__))
#define MLton_Platform_os 3
+#elif (defined (__NetBSD__))
+#define MLton_Platform_os 4
#else
#error MLton_Platform_os not defined
#endif
@@ -71,7 +73,8 @@
/* Nothing to do -- everything comes from sys/ptrace.h. */
-#elif (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__))
+#elif (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__) || defined(__NetBSD__))
+/* Note: NetBSD has a ptrace() interface, but for now, we ignore it */
#define PTRACE_BOGUS 0xFFFFFFFF
#define PTRACE_SYSCALL PTRACE_BOGUS
The biggo one. The garbage collector has its long fingers deep down into
the guts of the Operating system. There are much that needs to be
changed here.
First, provide correct includes.
Second, min and max should be defined properly
Third, Showmem and friends can be defined as in FreeBSD. Some goes for
mmap. NetBSD does not have the memory remap function like Linux does.
Let's see if that has a speed impact.
Fourth, disregard time profiling although I know it can be enabled. Let
it behave like the CYGWIN in this respect. I do hope this will not hit
the SML part in any bad way.
Fifth, totalSwap() and totalRam() can be controlled much like the code
in the FreeBSD part. Since /sbin/swapctl is not suid-bitted there might
be a cleaner way of getting the swap information from the kernel.
diff -ur mlton-cvs/mlton/runtime/gc.c mlton-netbsd/runtime/gc.c
--- mlton-cvs/mlton/runtime/gc.c Tue Jul 15 19:27:11 2003
+++ mlton-netbsd/runtime/gc.c Sat Aug 2 21:33:51 2003
@@ -16,6 +16,11 @@
#include <sys/sysctl.h>
#endif
+#if (defined (__NetBSD__))
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/times.h>
@@ -138,7 +143,7 @@
return n << 2;
}
-#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
static inline uint min (uint x, uint y) {
return ((x < y) ? x : y);
}
@@ -303,7 +308,7 @@
showMaps();
}
-#elif (defined (__FreeBSD__))
+#elif (defined (__FreeBSD__) || defined(__NetBSD__))
static void showMem () {
static char buffer[256];
@@ -343,7 +348,7 @@
PAGE_READWRITE);
if (NULL == result)
result = (void*)-1;
-#elif (defined (__linux__) || defined (__FreeBSD__))
+#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__NetBSD__))
result = mmap (start, length, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
#elif (defined (__sun__))
@@ -390,7 +395,7 @@
diee ("munmap failed");
}
-#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
/* A super-safe mmap.
* Allocates a region of memory with dead zones at the high and low ends.
* Any attempt to touch the dead zone (read or write) will cause a
@@ -427,7 +432,7 @@
#if (defined (__CYGWIN__))
if (0 == VirtualFree (base, 0, MEM_RELEASE))
die ("VirtualFree release failed");
-#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
smunmap (base, length);
#else
#error release not defined
@@ -441,7 +446,7 @@
#if (defined (__CYGWIN__))
if (0 == VirtualFree (base, length, MEM_DECOMMIT))
die ("VirtualFree decommit failed");
-#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
smunmap (base, length);
#else
#error decommit not defined
@@ -2654,7 +2659,7 @@
/* heapRemap */
/* ---------------------------------------------------------------- */
-#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
static bool heapRemap (GC_state s, GC_heap h, W32 desired, W32 minSize) {
return FALSE;
@@ -3746,7 +3751,7 @@
setProfTimer (10000);
}
-#elif (defined (__CYGWIN__))
+#elif (defined (__CYGWIN__) || defined(__NetBSD__))
/* No time profiling on Cygwin.
* There is a check in mlton/main/main.sml to make sure that time profiling is
@@ -3792,7 +3797,7 @@
/* Nothing */
-#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined(__NetBSD__))
static stack_t altstack;
size_t ss_size = align (SIGSTKSZ, s->pageSize);
@@ -3913,6 +3918,43 @@
len = sizeof (int);
if (-1 == sysctlbyname ("hw.physmem", &mem, &len, NULL, 0))
diee ("sysctl failed");
+ return mem;
+}
+
+static void setMemInfo (GC_state s) {
+ s->totalRam = totalRam();
+ s->totalSwap = totalSwap();
+}
+
+#elif (defined (__NetBSD__))
+
+/* returns total amount of swap available */
+static int totalSwap() {
+ static char buffer[256];
+ FILE *file;
+ int total_size = 0;
+
+ file = popen("/sbin/swapctl -s | awk '{ print $8; }'\n", "r");
+ if (file == NULL)
+ diee ("swapinfo failed");
+ /* read in data */
+ fgets (buffer, 255, file);
+ total_size = atoi(buffer);
+ pclose(file);
+ printf("Total amount of swap we think there is: %d\n",
+ total_size * 1024);
+ return total_size * 1024;
+}
+
+/* returns total amount of memory available */
+static int totalRam() {
+ int mem, len, mib[2];
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_PHYSMEM;
+ len = sizeof(mem);
+ if (-1 == sysctl(mib, 2, &mem, &len, NULL, 0))
+ diee ("sysctl failed");
return mem;
}
The resource limit for virtual memory can be read as in FreeBSD
diff -ur mlton-cvs/mlton/runtime/mlton-basis.h mlton-netbsd/runtime/mlton-basis.h
--- mlton-cvs/mlton/runtime/mlton-basis.h Sat Jul 19 03:23:28 2003
+++ mlton-netbsd/runtime/mlton-basis.h Sat Aug 2 21:33:51 2003
@@ -165,7 +165,7 @@
#define MLton_Rlimit_numProcesses RLIMIT_NPROC
#define MLton_Rlimit_residentSetSize RLIMIT_RSS
#define MLton_Rlimit_stackSize RLIMIT_STACK
-#if (defined (__FreeBSD__))
+#if (defined (__FreeBSD__) || defined (__NetBSD__))
#define MLton_Rlimit_virtualMemorySize RLIMIT_DATA
#elif (defined (__CYGWIN__) || defined (__linux__) || defined (__sun__))
#define MLton_Rlimit_virtualMemorySize RLIMIT_AS
Set MININT
diff -ur mlton-cvs/mlton/runtime/my-lib.c mlton-netbsd/runtime/my-lib.c
--- mlton-cvs/mlton/runtime/my-lib.c Tue Jun 17 02:14:18 2003
+++ mlton-netbsd/runtime/my-lib.c Sat Aug 2 21:33:51 2003
@@ -59,7 +59,7 @@
if (0 == n)
buf[i--] = '0';
-#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
#define MININT 0x80000000
#endif
else if (MININT == n) {
First, update comments.
Second, there is no difference between text and binary files
Third, NetBSD has a O_SYNC flag, although it should not be needed (FFS
are SYNC mounted by default and people mounting filesystems ASYNC
deserve the instability).
Fourth, _PC_ASYNC_IO and _PC_PRIO_IO is something noted in a newer POSIX
compliance guide than what NetBSD follows, so we need to comment them
out as 0. I am going to find a better way of solving this with the
NetBSD people, but for now, We hope that nobody uses these things and
let them break if they must.
Last, NSIG is straightforwardly defined.
diff -ur mlton-cvs/mlton/runtime/posix-constants.h mlton-netbsd/runtime/posix-constants.h
--- mlton-cvs/mlton/runtime/posix-constants.h Thu Apr 10 04:03:10 2003
+++ mlton-netbsd/runtime/posix-constants.h Sat Aug 2 22:08:43 2003
@@ -72,13 +72,13 @@
#define Posix_FileSys_S_ififo S_IFIFO
/* Cygwin/Windows distinguish between text and binary files, but Linux,
- * FreeBSD, and Solaris do not.
+ * FreeBSD, NetBSD, and Solaris do not.
*/
#if (defined (__CYGWIN__))
/* Nothing. */
-#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__))
+#elif (defined (__linux__) || defined (__FreeBSD__) || defined (__sun__) || defined(__NetBSD__))
#define O_BINARY 0
#define O_TEXT 0
@@ -95,7 +95,7 @@
#define Posix_FileSys_O_excl O_EXCL
#define Posix_FileSys_O_noctty O_NOCTTY
#define Posix_FileSys_O_nonblock O_NONBLOCK
-#if (defined (__CYGWIN__) || defined (__linux__) || defined (__sun__))
+#if (defined (__CYGWIN__) || defined (__linux__) || defined (__sun__) || defined (__NetBSD__))
#define Posix_FileSys_O_sync O_SYNC
#elif (defined (__FreeBSD__))
#define Posix_FileSys_O_sync 0
@@ -137,10 +137,23 @@
#define Posix_FileSys_PATH_MAX _PC_PATH_MAX
#define Posix_FileSys_PIPE_BUF _PC_PIPE_BUF
#define Posix_FileSys_VDISABLE _PC_VDISABLE
-#define Posix_FileSys_ASYNC_IO _PC_ASYNC_IO
#define Posix_FileSys_SYNC_IO _PC_SYNC_IO
+
+#if (defined (__NetBSD__))
+/* NetBSD does not define these constants in version 1.6.1, so we
+ * define them here.
+ */
+
+#define Posix_FileSys_ASYNC_IO 0
+#define Posix_FileSys_PRIO_IO 0
+
+#else
+
+#define Posix_FileSys_ASYNC_IO _PC_ASYNC_IO
#define Posix_FileSys_PRIO_IO _PC_PRIO_IO
+#endif
+
#define Posix_IO_F_DUPFD F_DUPFD
#define Posix_IO_F_GETFD F_GETFD
#define Posix_IO_F_SETFD F_SETFD
@@ -232,7 +245,7 @@
#define Posix_Signal_vtalrm SIGVTALRM
#define Posix_Signal_block SIG_BLOCK
-#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__))
+#if (defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__sun__) || defined (__NetBSD__))
#define Posix_Signal_numSignals NSIG
#elif (defined (__linux__))
#define Posix_Signal_numSignals _NSIG
--
j.
-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072303_01/01
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel