aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-12-01 13:16:42 +0100
committerRon Evans <[email protected]>2024-12-04 09:43:10 +0100
commitb5a8931fb57ca93fdfcf9c4e443833cd0def2a8d (patch)
tree32d3026998942bfa4fc1499b47154f76b67ff847
parentd3810ecd482ec8dc070e4aebb98d68f9b13fc3f7 (diff)
downloadtinygo-b5a8931fb57ca93fdfcf9c4e443833cd0def2a8d.tar.gz
tinygo-b5a8931fb57ca93fdfcf9c4e443833cd0def2a8d.zip
runtime: remove Cond
I don't think this is used anywhere right now, and it would need to be updated to work with multithreading. So instead of fixing it, I think we can remove it. My original intention was to have something like this that could be used in the machine package, but since this is in the runtime package (and the runtime package imports the machine package on baremetal) it can't actually be used that way. I checked the TinyGo repo and the drivers repo, and `runtime.Cond` isn't used anywhere except in that one test.
-rw-r--r--src/runtime/cond.go90
-rw-r--r--src/runtime/cond_nosched.go38
-rw-r--r--testdata/goroutines.go44
3 files changed, 0 insertions, 172 deletions
diff --git a/src/runtime/cond.go b/src/runtime/cond.go
deleted file mode 100644
index b27ab08ab..000000000
--- a/src/runtime/cond.go
+++ /dev/null
@@ -1,90 +0,0 @@
-//go:build !scheduler.none
-
-package runtime
-
-import (
- "internal/task"
- "sync/atomic"
- "unsafe"
-)
-
-// notifiedPlaceholder is a placeholder task which is used to indicate that the condition variable has been notified.
-var notifiedPlaceholder task.Task
-
-// Cond is a simplified condition variable, useful for notifying goroutines of interrupts.
-type Cond struct {
- t *task.Task
-}
-
-// Notify sends a notification.
-// If the condition variable already has a pending notification, this returns false.
-func (c *Cond) Notify() bool {
- for {
- t := (*task.Task)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t))))
- switch t {
- case nil:
- // Nothing is waiting yet.
- // Apply the notification placeholder.
- if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t)), unsafe.Pointer(t), unsafe.Pointer(&notifiedPlaceholder)) {
- return true
- }
- case &notifiedPlaceholder:
- // The condition variable has already been notified.
- return false
- default:
- // Unblock the waiting task.
- if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t)), unsafe.Pointer(t), nil) {
- scheduleTask(t)
- return true
- }
- }
- }
-}
-
-// Poll checks for a notification.
-// If a notification is found, it is cleared and this returns true.
-func (c *Cond) Poll() bool {
- for {
- t := (*task.Task)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t))))
- switch t {
- case nil:
- // No notifications are present.
- return false
- case &notifiedPlaceholder:
- // A notification arrived and there is no waiting goroutine.
- // Clear the notification and return.
- if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t)), unsafe.Pointer(t), nil) {
- return true
- }
- default:
- // A task is blocked on the condition variable, which means it has not been notified.
- return false
- }
- }
-}
-
-// Wait for a notification.
-// If the condition variable was previously notified, this returns immediately.
-func (c *Cond) Wait() {
- cur := task.Current()
- for {
- t := (*task.Task)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t))))
- switch t {
- case nil:
- // Condition variable has not been notified.
- // Block the current task on the condition variable.
- if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t)), nil, unsafe.Pointer(cur)) {
- task.Pause()
- return
- }
- case &notifiedPlaceholder:
- // A notification arrived and there is no waiting goroutine.
- // Clear the notification and return.
- if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&c.t)), unsafe.Pointer(t), nil) {
- return
- }
- default:
- panic("interrupt.Cond: condition variable in use by another goroutine")
- }
- }
-}
diff --git a/src/runtime/cond_nosched.go b/src/runtime/cond_nosched.go
deleted file mode 100644
index ff57f4146..000000000
--- a/src/runtime/cond_nosched.go
+++ /dev/null
@@ -1,38 +0,0 @@
-//go:build scheduler.none
-
-package runtime
-
-import "runtime/interrupt"
-
-// Cond is a simplified condition variable, useful for notifying goroutines of interrupts.
-type Cond struct {
- notified bool
-}
-
-// Notify sends a notification.
-// If the condition variable already has a pending notification, this returns false.
-func (c *Cond) Notify() bool {
- i := interrupt.Disable()
- prev := c.notified
- c.notified = true
- interrupt.Restore(i)
- return !prev
-}
-
-// Poll checks for a notification.
-// If a notification is found, it is cleared and this returns true.
-func (c *Cond) Poll() bool {
- i := interrupt.Disable()
- notified := c.notified
- c.notified = false
- interrupt.Restore(i)
- return notified
-}
-
-// Wait for a notification.
-// If the condition variable was previously notified, this returns immediately.
-func (c *Cond) Wait() {
- for !c.Poll() {
- waitForEvents()
- }
-}
diff --git a/testdata/goroutines.go b/testdata/goroutines.go
index 5ac3b7318..fe4347df9 100644
--- a/testdata/goroutines.go
+++ b/testdata/goroutines.go
@@ -1,7 +1,6 @@
package main
import (
- "runtime"
"sync"
"time"
)
@@ -83,8 +82,6 @@ func main() {
testGoOnInterface(Foo(0))
- testCond()
-
testIssue1790()
done := make(chan int)
@@ -172,47 +169,6 @@ func testGoOnBuiltins() {
}
}
-func testCond() {
- var cond runtime.Cond
- go func() {
- // Wait for the caller to wait on the cond.
- time.Sleep(time.Millisecond)
-
- // Notify the caller.
- ok := cond.Notify()
- if !ok {
- panic("notification not sent")
- }
-
- // This notification will be buffered inside the cond.
- ok = cond.Notify()
- if !ok {
- panic("notification not queued")
- }
-
- // This notification should fail, since there is already one buffered.
- ok = cond.Notify()
- if ok {
- panic("notification double-sent")
- }
- }()
-
- // Verify that the cond has no pending notifications.
- ok := cond.Poll()
- if ok {
- panic("unexpected early notification")
- }
-
- // Wait for the goroutine spawned earlier to send a notification.
- cond.Wait()
-
- // The goroutine should have also queued a notification in the cond.
- ok = cond.Poll()
- if !ok {
- panic("missing queued notification")
- }
-}
-
var once sync.Once
func testGoOnInterface(f Itf) {