Hello, The goal of my GSoC project was to port the reference compiler for the Go programming language to Haiku. I believe that I have furfilled that promise: the Golang port is mostly functional (the standard library compiles, most tests pass, and the Golang tour works on the ported runtime). The port can be built using the golang recipe in Haikuports: to build, setup Haikuporter and Mercurial, then type haikuporter --no-dependencies golang_x86 if you're on a GCC2 hybrid, and haikuporter --no-dependencies golang otherwise. What has been fixed during the second term: - spawning new processes - checking for stack overflows - handling signals - getting system time - pipes - any part of the runtime that needs the Go tool - Other architectures - the runtime is also working on x86_64 What still remains to be fixed: - TLS storage of the M and G structures - address space reservation for the Golang heap on 32-bit - Some functions in the Net package - the port lacks a network poller, which is used to speed up networking - listing directories' content one item at a time (currently only listing all items at the same time, as used by the Go tool, is supported) - various other tests in the standard library are not passing - Cgo is not working yet - the port is based on Golang 1.3; a port for 1.4 is required for upstreaming the port - cleanup is needed for upstreaming: the port accumulated quite a bit of // FIXME: haiku comments During the second half-term, the focus was to get every package in the standard library building. First, I kludged around the memory reservation issue by... not reserving any memory at all. (Later, I switched to the approach of mmapping the memory, and then immediately un-mmapping it again. That's still not working properly, and prevents the runtime from using all available memory on 32-bit, but for most workloads this should be fine) That at least allowed fork/exec to run, and after a week, the Go tool was able to successfully build all the packages in the standard library. After building all the packages, I was able to create a list of constants and structures from the host headers using the Cgo tool, which, as I mentioned in the last blog post, is written in Golang itself and depends on the standard library being functional. The list of constants and structures are used to call into libroot, and thus they must match what libroot uses and returns. This includes the list of errnos, the list of signals, and more. With these files regenerated, most functions in the syscall and runtime packages started working properly. Afterwards, I tried enabling signal handling and timers -- for both tasks, my initial attempts didn't work, and I only figured out the confusing causes of the problems after careful review. For timers, when I tried adapting the Solaris code for Haiku, I was greeted with the error message "stack expansion during syscall". In Golang, most methods have a segmented stack - the stack for each thread can grow and shrink as needed. However, in the semaphore code that controls sleeping, expanding the stack could create deadlocks, so the Solaris code was careful to avoid calling methods that require stack expansion. So why did this message appear when no method called required stack expansion? It turns out that the method used 64-bit division, and on 32-bit x86, this is implemented with a call to a method using a segmented stack, unlike on 64-bit amd64, where there are dedicated instructions for 64-bit division. Replacing the division with a call to a non-segmented method allowed timers to function. For signals, whenever a signal was received by the runtime, the program would suffer a segmentation fault in some completely unrelated code. The signal handler I put together from parts of the Solaris amd64 handler and the FreeBSD 386 handler seemed to work right: it saves all the registers needed, and seems to save the state of both the M and the G structure, which are used by the Golang scheduler. It turns out that I did not notice that the register for the M structure was overwritten when I restored the G structure, so I ended up restoring what should be written into the M structure into the G structure instead, confusing the scheduler and causing the segfaults. At this point, I tried running the Golang Tour on Haiku, and noticed another "impossible" bug: a timer with an interval below 1 second gets rounded up to 1 second. After staring for a while, I realized that the time that the runtime reports was only precise down to seconds: anything below seconds was reported as zero. Since the timer sleeps until the time changes, this limited the minimum sleep interval to 1 second. It turned out I had returned the nanoseconds in the BX register; the code expected it to be in the DX register. Sigh. During the last part of the work period, I worked on porting the runtime to Haiku x86_64 as well. This took much less time than the x86 port, partly because the Solaris port, which the Haiku port is based on, was developed for x86_64 only, so I was able to use much of its code unmodified in the x86_64 port. Finally, I submitted a HaikuPort recipe for Golang; it was merged; the package isn't being built automatically right now, but can be built with haikuporter manually, as stated above. In the future, I would like to update this port to Golang 1.4. I've looked at Golang 1.4 back in July, and it seems that the only major change was that the M and the G structures (which, as I mentioned, are used in the scheduler) no longer takes up two TLS slots: instead, only the G structure is stored in TLS, and points to the active M structure. That should be a minor change, mostly in the linker, the initialization code, and the signal handler. The repository for this port is at https://bitbucket.org/zhuowei/go-1-3-haiku/commits/branch/porthaiku2 , under the porthaiku2 bookmark. Again, I would like to thank everyone on the haiku-gsoc mailing list, especially my mentor, Bruno Albuquerque, for their encouragement and advice during this work period. Zhuowei Zhang