boc

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2025 License: MIT Imports: 7 Imported by: 0

README

Behaviour-Oriented Concurrency

Go Reference

Package boc is a Go implementation of paper "When Concurrency Matters: Behaviour-Oriented Concurrency" in OOPSLA2023.

See Documentation for more details.

This package is rewritten from boc.rs. The benchmark is provided by kaist-cp/cs431 and rewritten in Go.

Thanks for authors of kaist-cp/cs431 and paper.

Documentation

Overview

Package boc is a Go implementation of paper "When Concurrency Matters: Behaviour-Oriented Concurrency" in OOPSLA2023.

This package is rewritten from boc.rs. The benchmark is provided by kaist-cp/cs431 and rewritten in Go.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultPostFn = func() {}

DefaultPostFn is a default post function that does nothing.

Functions

func EnableTypeCheck

func EnableTypeCheck()

EnableTypeCheck is a function to enable type checking. Pass "TYPE_CHECK=1" to the environment variable can also enable type checking.

func TypeCheckHelper

func TypeCheckHelper(fn func())

Use TypeCheckHelper to skip other operations, remaining only When statements. See example of TypeCheckHelper for usage.

Example
EnableTypeCheck()
c1 := NewCownPtr(1)
c2 := NewCownPtr(false)

t1 := CownIfaceVec{c1, c2}

ch := make(chan bool)

When(t1,
	gen2(
		func(g1 *bool, g2 *int) { // here g1, g2's type is wrong, should panic
			TypeCheckHelper(func() {
				*g1 = false
				*g2 += 2
				ch <- true
			})
		},
		func() {
			if r := recover(); r != nil {
				if strings.HasPrefix(r.(error).Error(), "convertion from interface") {
					fmt.Println(r)
					return
				}
			}
			panic("error is not interface convertion error")
		},
	),
)
TypeCheckHelper(func() {
	<-ch
})
TypeCheckWait()
Output:

convertion from interface{boc.CownPtr[int]} to boc.CownPtr[bool] failed

func TypeCheckWait added in v0.1.1

func TypeCheckWait()

Insert TypeCheckWait to the end of the main goroutine to wait for all When statements(goroutines spawned) to finish.

func When

func When(cowns CownIfaceVec, fn func(cowns CownIfaceVec))

Use When1, When2, When3, When4 or WhenVec instead of When if possible to leverage compiler type checking. If you want to use When directly, you can use AsCownPtr in fn to convert each cown in cowns to the correct type.

Example
c1 := NewCownPtr(0)
c2 := NewCownPtr(0)
c3 := NewCownPtr(false)
ch := make(chan bool)
When(CownIfaceVec{c1, c2}, func(cowns CownIfaceVec) {
	x0 := AsCownPtr[int](cowns[0]).AddrOfValue() // dynamic type checking
	x1 := AsCownPtr[int](cowns[1]).AddrOfValue()
	*x0 += 1
	*x1 += 1
	fmt.Println(*x0, *x1)
	When(CownIfaceVec{c3, c2}, func(cowns CownIfaceVec) {
		g3 := AsCownPtr[bool](cowns[0]).AddrOfValue()
		g2 := AsCownPtr[int](cowns[1]).AddrOfValue()
		*g2 += 1
		*g3 = true
		fmt.Println(*g2, *g3)
		ch <- true
	})
})
<-ch
Output:

1 1
2 true

func When1

func When1[T any](cown CownPtr[T], fn func(*T), postFn func())

When1 is a helper function for When with one cown. postFn is a function that will be called after fn. It is useful for cleanup and handling panic in spawned goroutine.

See example of When2 and boc_test.go for usage.

See example of TypeCheckHelper for usage of postFn to handle panic.

func When2

func When2[T0, T1 any](cown0 CownPtr[T0], cown1 CownPtr[T1], fn func(*T0, *T1), postFn func())

When2 is a helper function for When with two cown. See When1 for further explanation.

Example
c1 := NewCownPtr(1)
c2 := NewCownPtr(2)
c3 := NewCownPtr(false)

ch := make(chan int)

When2(c1, c2, func(g1 *int, g2 *int) {
	*g1 += 1
	*g2 += 2
	When2(c2, c3, func(g2 *int, g3 *bool) {
		*g2 += 1
		*g3 = true
		fmt.Println(*g1, *g2, *g3)
	}, DefaultPostFn)
}, DefaultPostFn)

When3(c1, c2, c3, func(g1 *int, g2 *int, g3 *bool) {
	if *g1 != 2 {
		panic("g1 should be 2") // Attention! don't use t.Fatalf here
	}
	if *g2 != 4 {
		panic("g2 should be 4")
	}
	ch <- 1
}, DefaultPostFn)

<-ch
Output:

2 5 true

func When3

func When3[T0, T1, T2 any](cown0 CownPtr[T0], cown1 CownPtr[T1], cown2 CownPtr[T2], fn func(*T0, *T1, *T2), postFn func())

See When1 for further explanation.

func When4

func When4[T0, T1, T2, T3 any](cown0 CownPtr[T0], cown1 CownPtr[T1], cown2 CownPtr[T2], cown3 CownPtr[T3], fn func(*T0, *T1, *T2, *T3), postFn func())

See When1 for further explanation.

func WhenVec

func WhenVec[T any](cowns CownPtrVec[T], fn func(content ...*T), postFn func())

WhenVec is a helper function for a slice of cowns with same type. See When1 for further explanation.

Example
c1 := NewCownPtr(0)
c2 := NewCownPtr(0)
c3 := NewCownPtr(false)

ch := make(chan bool)
WhenVec(CownPtrVec[int]{c1, c2}, func(x ...*int) {
	*x[0] += 1
	*x[1] += 1
	When2(c3, c2, func(g3 *bool, g2 *int) {
		*g2 += 1
		*g3 = true
		fmt.Println(*x[0], *x[1], *g3)
		ch <- true
	}, DefaultPostFn)
}, DefaultPostFn)
<-ch
Output:

1 2 true

Types

type CownIfaceVec

type CownIfaceVec []cownIface

CownIfaceVec is a slice of cownIface. cownIface can store different types of CownPtr[T]. The use case is CownIfaceVec{CownPtr[int], CownPtr[bool], ...}. But the type checking have to be deferred to runtime.

If macro is supported, finite tuple type (CownPtr[int], (CownPtr[bool], ...) can replace this

type CownPtr

type CownPtr[T any] struct {
	// contains filtered or unexported fields
}

CownPtr is a wrapper for a cown[T].

Use NewCownPtr to create a new CownPtr. User should not care about the inner data.

func AsCownPtr

func AsCownPtr[T any](ptr cownIface) CownPtr[T]

AsCownPtr convert from cownIface to CownPtr[T]. It panics if the conversion fails.

func NewCownPtr

func NewCownPtr[T any](value T) CownPtr[T]

NewCownPtr creates a new CownPtr with the given value. The value is stored in a cown, which allows for safe concurrent access. The CownPtr can be used to pass the value to other goroutines safely.

func (CownPtr[T]) AddrOfValue

func (ptr CownPtr[T]) AddrOfValue() *T

CownPtr.AddrOfValue returns the address of the value inside the CownPtr. This is useful for passing the value to a function that requires a pointer.

func (CownPtr[T]) String added in v0.2.0

func (ptr CownPtr[T]) String() string

String returns a string representation of the CownPtr.

type CownPtrVec

type CownPtrVec[T any] []CownPtr[T]

CownPtrVec is a slice of CownPtr with same type parameter T. Use CownPtrVec.ToIfaceVec to convert it to CownIfaceVec.

func (CownPtrVec[T]) ToIfaceVec added in v0.1.1

func (slice CownPtrVec[T]) ToIfaceVec() CownIfaceVec

CownPtrVec.ToIfaceVec converts a slice of CownPtr[T] to CownIfaceVec. This is useful for passing a slice of CownPtr[T] to a function that expects a CownIfaceVec.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL