Skip to content

Commit

Permalink
std/sync: add test for Once
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Dec 6, 2024
1 parent f981aca commit a932b46
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
8 changes: 4 additions & 4 deletions std/runtime/lock.jule
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const mutexWaiterShift = 3
const starvationThresholdNs = 1_100_000

// Advanced mutex implementation for common and public use.
// See the sync::Mutex for documentation.
// See the [sync::Mutex] for documentation.
// This implementation derived from the original Go code,
// but it may work different paritially.
// For the original Go code, see the sync.Mutex of the Go stdlib.
Expand All @@ -76,7 +76,7 @@ struct mutex {

impl mutex {
// Locks the mutex.
// See the [sync::Mutex.Lock] for documentation.
// See the [sync::Mutex] for documentation.
fn lock(self) {
// Fast path: grab unlocked mutex.
if atomicCompareAndSwap(self.state, 0, mutexLocked, atomicSeqCst) {
Expand Down Expand Up @@ -170,7 +170,7 @@ impl mutex {
}

// Tries to lock the mutex.
// See the [sync::Mutex.TryLock] for documentation.
// See the [sync::Mutex] for documentation.
fn tryLock(self): bool {
old := self.state
if old&(mutexLocked|mutexStarving) != 0 {
Expand All @@ -184,7 +184,7 @@ impl mutex {
}

// Unlocks the mutex.
// See the [sync::Mutex.Unlock] for documentation.
// See the [sync::Mutex] for documentation.
fn unlock(self) {
// Fast path: drop lock bit.
new := atomicAdd(self.state, -mutexLocked, atomicSeqCst)
Expand Down
39 changes: 39 additions & 0 deletions std/sync/once_test.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

use "std/sync/atomic"
use "std/testing"

type one: int

impl one {
fn Increment(mut self) {
self++
}
}

fn run(t: &testing::T, once: &Once, mut o: &one, mut c: &int) {
once.Do(fn() { o.Increment() })
if *o != 1 {
t.Errorf("once failed inside run: {} is not 1", *o)
}
atomic::Add(*c, 1, atomic::SeqCst)
}

#test
fn testOnce(t: &testing::T) {
mut o := new(one)
mut once := new(Once)
mut c := new(int)
const N = 10
mut i := 0
for i < N; i++ {
co run(t, once, o, c)
}
for atomic::Load(*c, atomic::SeqCst) != N {
}
if *o != 1 {
t.Errorf("once failed outside run: {} is not 1", *o)
}
}

0 comments on commit a932b46

Please sign in to comment.