HNHacker News
TopNewBestAskShowJobs

Leotard6963

84 karma · joined December 27, 2022

submissionscomments
Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Note that this project is not an attempt to replace the Go runtime, but here is what we will do:

Precondition: in Go, each goroutine has its own `g` structure (like TCB, but for controlling goroutines) and its address is stored in the `g` register, which is reserved by the go compiler, active goroutines can call a function runtime.getg() to obtain the value of the `g` register.

In the official runtime, the `g` structure is a concrete type and the scheduler is implemented globally in the runtime package.

But we have made the `g` structure customizable (still requires a fixed header expected by the function prologue & epilogue and linker), so custom g implementations may contain a link to a custom scheduler, and the scheduler can decide how to handle an active goroutine.

> "goroutines" that automatically suspend themselves

The automatic suspend and resume happens by

- calling `runtime.entersyscall` from a running goroutine - and calling `runtime.exitsyscall` from an finished systemstack

all these operations can interact with the custom `g`, thus can interact with the custom scheduler.

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Yes, that's one of our motivations to build this std!

The feature of generating go packages from C in `ffigen` still needs significant work to be done (mostly dealing with C calling conventions on different platforms), and the generated go package only works with dynamic libraries (as it uses the pragma `go:cgo_import_dynamic`).

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
I'm afraid there is no such resource, but you may find cmd/compile/abi-internal.md[1] helpful

And in brief introduction, the `g` register is a non-scratch register, and is preserved by the go compiler, it stores the poitner to current goroutine (type `g` in the official runtime, a structure serves the similar purpose of TCB), and since all general purpose registers are thread local, the goroutine may enjoy some thread-local features without any thread-local requirements to the running environment.

[1]: https://github.com/golang/go/blob/master/src/cmd/compile/abi...

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Thank you for your suggestions, but I'm afraid the best we can do is to list packages compatible with both std.

The problem is, in order to build a std, we have to use a lot of <ABIInternal> stuff in assembly, and use internal/abi.FuncPCABIInternal in Go, so we can not make any promise regarding to the inter-std-compatibility for the time being, unless the Go project decided to make these features stable.

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Thanks, but the actually hard things are done by the Go team, the design of the interface type and availability of runtime type information made it relatively easy to complete that final goal, but let's go find out!
Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
"platform native sdk" is the collection of apis exposed on that platform exclusively (think win32 apis, android ndk).

The project is to build a stdlib, and by its nature is to be used by developers to build applications just like the official Go std.

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Yes, we are re-implementing (some of) the official std, but with careful redesign, and probably won't provide a lot of familiar apis, this is largely because packages from the official std often do implicit allocations with the assumption of GC running.

And Yes, we are defining brand new interfaces as well, in order to improve usability and fix inconsistent user experience.

For your specific example `os.WriteFile` (names mentioned below may subject to change):

The api won't make it inside the std, because the local filesystem will be implemented as a `fs.FS` (concrete type `*sysfs.FS`), so you can have multiple `sysfs.FS` instances each at its own working directory, and the `os.WriteFile` will be replaced with `fs.WriteFile(fsys fs.FS, path *fs.PathBuf, wctx *io.WriteContext) io.Status`, where `fs.PathBuf` is our solution to handle all kinds of path styles (windows, unix, cygwin, utf8, utf16, end-null) and operations (join, base, dir).

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
So this is the std made for you, and to make it compile, you have to import the runtime package explicitly.
Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Currently pcz is building applications with the `compiling-runtime` option, so variables implicitly escaped from the stack will cause compile error.

For variables you are sure living on the stack, you can use `mark.NoEscape(&v)` to obtain its pointer (a hack to cheat escape analysis found in the official runtime & reflect package), and the variable will be freed on function return.

For variables you want to control lifecycle, call `alloc.New` or `alloc.Make` with a explicit allocator, which can be an allocator whose storage is on the previous call stack (and there is a default goroutine local allocator thread.G().G().DefaultAlloc()) to allocate a non-stack-local variable, and call `alloc.Free` with the same allocator to free that variable.

The use of `make` is discouraged as go compiler does mid-stack inlining and escape analysis, so the return value of a `make` can be either on stack or on heap, thus to free it, the allocator needs to compare the address to thread.G().Stack.Lo and thread.G().Stack.Hi.

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
> dropping GC, dropping runtime concurrency

Making GC/goroutine optional & customizable requires building a std works with no GC/goroutine.

> dropping std

relax, this is a new std, let's spare the baby some hope?

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
You are right, the pcz std won't be a drop-in replacement to the official std as they have different modulepath.

We decided to make it this way so:

1) you can import packages from the pcz std module like you do with any other Go package without setting `GOROOT` to an unofficial std.

2) and because of 1), you can import packages from pcz std in your go application but still using the `go` command rather the `pcz` command.

In the future, we may provide drop-in replacement for applications using official std by introducing a compatibility module and a cli flag to redirect imports using packages from the official std to that module.

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
> converge or diverge

Neither, though the final result can be similar, but at project level, tinygo and pcz has very different approaches to achieve the final result:

- tinygo chose the hard path to write a llvm backed toolchain with some custom behavior that compiles Go code (using official std) to llvm targets.

- pcz chose the easy path to write a stdlib from scratch that compiles to desired targets using the official Go toolchain.

One major benefit of pcz's approach is you can import packages from the pcz std module like you do with any other Go package, the development experience can remain unchanged.

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
Sorry to cause the confusion, we are building a stdlib for Go, and all these goals are related to the development experience when using our stdlib, and we are not aiming at anything like replacing the official go stdlib (which we also enjoy work with).

Were the confusion caused by the choice of project name `pcz` instead of `xxxstd`? or any suggestion for us to improve?

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
"adapting to the platform" is mostly related to the goroutine topic, as we are working on the js/wasm support and these applications prefer async/await operations.

re: goroutines

the official go runtime spawns goroutines during program startup, which makes the usage of M:N goruntine mandatory, and they have to call lockOSThread()[1] before initializing packages for certain applications (mostly GUI application).

We like the design of goroutines (especially the idea of a `g` register), but `pcz` currently doesn't have goroutine support, and we are making it possible to spawn goroutines with custom allocator (with or without gc) and scheduler attached, so you can chose 1:1, M:N model for goroutines on your own (as decided by the scheduler attached).

you can find more details in the project ROADMAP.md[2]

[1]: https://github.com/golang/go/blob/352c8835e7609ad72872b5a63b... [2]: https://github.com/primecitizens/pcz/blob/master/ROADMAP.md

Leotard6963··on Show HN: A new stdlib for Golang focusing on platform native support
re: telemetry

We don't like it as well, just do not enable it :^

re: RAII

It is not possible to add RAII support without updating the compiler to call specific methods automatically, so currently it is not an option (as we are using unmodified official toolchain).

But the `g` register defined in Go is of great value, and we are making use of it to provide custom goroutine support, which means you can have custom allocator and scheduler for specific goroutines, so that you can have some of them with GC enabled and others not.

re: compare to V

pcz is a stdlib (plus a cli tool to build), not a new language, you still write Go code but in a slightly different style.

Leotard6963··on Ask HN: Resources for learning/teaching time zone conversions and datetime math?
afaik, the `time` package [1] from the golang standard library has a brilliant support for (almost) everything about time, including timezone, leap year, months, duration.

take timezone for example, time.Time.In [2] could be a good startpoint to learn how they do the conversion.

[1]: https://github.com/golang/go/tree/master/src/time [2]: https://github.com/golang/go/blob/38cfb3be9d4868334562767771...