blob: 471206e982de2a0245ae74fbb0e87b43a7a4cda1 [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
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.
//go:nosplit
func notify_new_thread(h int32) {
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, nil, 0, &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 zero-byte single-handle message for every thread that the runtime creates.
// 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
}