Sender and Receiver both have ClockSource field in their config structs, with two possible values:
-
ClockExternal - Receiver.ReadFloats and Sender.WriteFloats are non-blocking; the user is resposible for invoking these methods at appropriate time (in other words, the stream clock is managed by user, thus "external clock")
-
ClockInternal - Receiver.ReadFloats and Sender.WriteFloats are blocking; they will automatically block to align read and write operations with the stream clock (in other words, the stream clock is managed by library, thus "internal clock")
Current implementation of Receiver.ReadFloats and Sender.WriteFloats just invokes corresponding C function; if blocking is needed (for ClockInternal), it is done inside the C code.
However, this does not play perfectly well with the Go scheduler. Scheduler threads will idle until sysmon detects that we've blocked, instead of performing useful work, and then will have to do some extra houskeeping before proceeding.
We could avoid this the following way, for Sender:
-
If ClockSource is ClockInternal, OpenSender creates a channel and background goroutine. Sender.Close asks background goroutine to interrupt and waits until it exits.
-
Background goroutine calls runtime.LockOSThread to detach from Go scheduler and starts reading from channel.
-
Sender.WriteFloats writes frame to channel.
-
Background goroutine reads frames from channel and passes them to the C function.
-
Sender.WriteFloats waits until background goroutine finishes handling the frame.
This way, Sender.WriteFloats will block on a Go channel instead of blocking in C code, which will integrate well with the Go scheduler (it will efficently switch to other goroutines when the channel is blocked). Blocking inside C code will happen on a dedicated goroutine detached from scheduler, which won't harm it.
Receiver should be addressed the same way, but the flow of samples will be the opposite (from C to Go, not from Go to C).
A unit test should be added both to receiver_test.go and sender_test.go for I/O in internal clock mode.
Sender and Receiver both have
ClockSourcefield in their config structs, with two possible values:ClockExternal-Receiver.ReadFloatsandSender.WriteFloatsare non-blocking; the user is resposible for invoking these methods at appropriate time (in other words, the stream clock is managed by user, thus "external clock")ClockInternal-Receiver.ReadFloatsandSender.WriteFloatsare blocking; they will automatically block to align read and write operations with the stream clock (in other words, the stream clock is managed by library, thus "internal clock")Current implementation of
Receiver.ReadFloatsandSender.WriteFloatsjust invokes corresponding C function; if blocking is needed (forClockInternal), it is done inside the C code.However, this does not play perfectly well with the Go scheduler. Scheduler threads will idle until sysmon detects that we've blocked, instead of performing useful work, and then will have to do some extra houskeeping before proceeding.
We could avoid this the following way, for Sender:
If
ClockSourceisClockInternal,OpenSendercreates a channel and background goroutine.Sender.Closeasks background goroutine to interrupt and waits until it exits.Background goroutine calls runtime.LockOSThread to detach from Go scheduler and starts reading from channel.
Sender.WriteFloatswrites frame to channel.Background goroutine reads frames from channel and passes them to the C function.
Sender.WriteFloatswaits until background goroutine finishes handling the frame.This way,
Sender.WriteFloatswill block on a Go channel instead of blocking in C code, which will integrate well with the Go scheduler (it will efficently switch to other goroutines when the channel is blocked). Blocking inside C code will happen on a dedicated goroutine detached from scheduler, which won't harm it.Receiver should be addressed the same way, but the flow of samples will be the opposite (from C to Go, not from Go to C).
A unit test should be added both to receiver_test.go and sender_test.go for I/O in internal clock mode.