I once has an internship where my assigned task was to make a SOAP request by downloading a NuGet package and using that for the task.
Naturally I thought the assignment was to make the request myself.
Also SOAP is terrible.
Anyhow I decided against IT as a Job because of that! : D
We would like to try to support other languages in Genio with the full spectrum of features: build and run, syntax highlighting and LSP support (via omnisharp maybe?).
.NET and C# and Python would be our first choices.
So yes, please make the binaries available so we can experiment a bit.
For anyone interested, I will release my binary builds here.
The .NET runtime is already released as a build artifact. I will set up build scripts for the .NET SDK as well as the NuGet feeds later today. After that I will provide further installation instructions.
HaikuPorts releases are currently impossible because:
The current branch is using a prerelease version of .NET 8.
Many PRs are waiting to get merged upstream.
No official documentation (at least, not among the ones I know) on how to create packages that have themselves as a build prerequisite. Probably creating an initial dummy package that downloads pre-built binaries and then use that one to bootstrap another “revision” of the recipe might work?
Unconventional installation layout. All of .NET lives in one directory, and it should be writable so that additional workloads or other optional components can be installed through NuGet, instead of being divided into /bin, /lib, etc. like other UNIX applications.
You can look at hos this is done for Rust and Haskell.
For Rust, haikuports does not currently builds from source, but just repackages existing binaries.
For Haskell, the first version was cross compiled, and then that version was used to build the next one, and so on.
That will not really fit with the way haiku packages work. Living in one directory is no problem (just put it in system/develop/tools/dotnet for example), but you’ll probably need some things to be in a packaged directory and some to be in a non-packaged one.
According to the documentation, NuGet has “user” and “computer” levels, just like other package managers. Usually in Haiku, the “computer” level is read-only and managed by packages, and the “user” level will be in a non-packaged directory (at least I think that’s what we do for Python and Perl).
I have provided a dotnet-install.sh-like script that installs the latest .NET builds on Haiku.
The script currently installs Debug builds, not Release builds as the latter might have some mysterious hidden bugs.
Make sure you install .NET dependencies first:
pkgman install -y gmp krb5 libiconv llvm12_libunwind mpfr
pkgman install -y jq # Required for the dotnet-install script.
It seems like .NET uses edge-triggered polling with EPOLLET, or the equivalent EV_CLEAR for platforms with kqueue.
This means after an event has been read by the user, it will not be returned by the polling function a second time, even when there is more data to be read from/more data can be write to the file descriptor. The event will only be re-triggered when another write/read actually occurs on the other end.
This property cannot be satisfied by the current poll workaround. For poll, it is not possible to distinguish between two different events in two calls and the same unchanged event in two calls. Therefore, .NET tries to loop again and again and handles the same event over and over, starving CPU resources and preventing other threads from running.
I am also waiting for an epoll/kqueue implementation because of the problem mentioned above.
In the last week, I decided to pay the virtual memory technical debt by implementing _kern_remap_memory. While the code will need a bit more reviewing, it has been tested with scenarios similar to what should be used by .NET. I will update the .NET port to use this new syscall when it has been fully accepted into mainstream Haiku and exposed as a public API in libroot.so.
This is how some portions of .NET should look like if all my patches are accepted.
Currently, I am exposing the _kern_remap_memory system call as a special mode of mmap named MAP_REMAP. When this flag is specified, the last two arguments become the PID of the source memory (0 for using the same team), and the address of the cloned memory.
The commit uses this new functionality in a variety of ways, from committing memory in previously overcommitting area, remapping memory ranges with different protections (the doublemapper), and reading the memory of another process.
Using the new syscall, the bug that makes dotnet crash at fork unless COMPlus_EnableWriteXorExecute=0 is set disappears. The double mapper works flawlessly.
The mentioned commit also removes a hack related to datagram UNIX domain sockets, as I have implemented that in this patch.
These changes will not be visible in the dotnet-builds repository until the Haiku patches required get merged (and that will take quite a long time since they are both size XL on Gerrit).
With these two patches, and hopefully kqueue being implemented soon, most problems of the port are solved (at least until I get an SDK stable enough to bootstrap itself and run library tests). The remaining issues either have functionally equivalent workarounds, are obscure and not supported on many other platforms anyway (some process/thread attributes), or are way outside of my area of knowledge (IPV6 support).
Large but well-designed and well-documented patches are not a problem to review. But to achieve that it usually means spending some time to discuss things (for example in a bugtracker ticket) before implementing it “right” on the first try. Otherwise, the discussion will happen after the code is already written, and changes will be needed (that’s totally fine, sometimes it’s very useful to have a working prototype code to experiment with and see the limitations of an approach and what can be improved on it).
It is so similar that HyClone uses this to implement resize_area.
mremap is some kind of an opposite to the _kern_remap_memory. mremapmoves the mapping and resizes the it, but all of the mapping’s properties (protections and things like that) are left unmodified. The old mapping are always removed (MREMAP_DONTUNMAP does not keep the old pages but replaces them with zero-filled ones instead).
_kern_remap_memory cannot resize ranges but can change properties. It looks more similar to Darwin’s vm_remap.
Along with mremap, I have also considered exposing this syscall independently as remap_memory, but there do not seem to be any public non-area VM syscall on Haiku.
Do any of the BSDs have an equivalent to the Darwin API? It would be preferable if we just added something in libbsd or libgnu instead of adding our own private API. But we can do that if necessary.
Ultimately, whatever we do, it shouldn’t involve syscalls being invoked directly by third-party applications. That will just create compatibility problems. At least with syscall wrapper functions, we can modify the syscall without having to rebuild other programs.