blob: 1bc6f030c2ea9f1bd4b0986b054e3074105eea52 [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package zx
import "unsafe"
var threadQueue struct {
writer, reader Channel
}
// init_threads_channel initializes a channel that is used as buffer for created
// threads. It must be called from os_init.
//
//go:nosplit
func init_threads_channel() {
if status := Sys_channel_create(0, threadQueue.writer.Handle(), threadQueue.reader.Handle()); status != ErrOk {
// NB: Can't allocate here to provide status in panic.
panic("failed to create threads channel")
}
}
// notify_new_thread is called by the runtime whenever a new thread is created
// in minit. It duplicates the handle and stores it in the threadQueue channels
// for later retrieval by applications. We can't do anything a lot fancier than
// this because minit is a very restricted environment where we can't allocate
// or do much else.
//
// h is the thread handle. w is a constant exported from the runtime package
// saying which thread type this is.
//
//go:nosplit
func notify_new_thread(h uint32, w byte) {
var dup Handle
// Duplicate the handle with the minimum set of rights to accomplish
// exposing the threads to applications and installing thread profiles.
if status := Sys_handle_duplicate(Handle(h), RightManageThread|RightTransfer, &dup); status != ErrOk {
// NB: Can't allocate here to provide status in panic.
panic("failed to duplicate thread handle")
}
if status := Sys_channel_write(threadQueue.writer.Handle().Load(), 0, unsafe.Pointer(&w), 1, &dup, 1); status != ErrOk {
// NB: Can't allocate here to provide status in panic.
panic("failed to write thread to channel")
}
}
// GetThreadsChannel returns a reference to a channel that will be enqueued with
// a single-byte single-handle message for every thread that the runtime
// creates. The single byte encodes the thread type. See runtime.ThreadType.
//
// Applications may read from this channel to retrieve handles to the runtime
// threads.
//
// Closing this channel may cause the runtime to panic. Writing to this channel
// has no effect but increasing process memory consumption, there's nothing
// reading the others side.
func GetThreadsChannel() *Channel {
return &threadQueue.reader
}