A toy deadlock detector written in Go.

Toy Deadlock Detector

GoDoc CircleCI

This package aims to provide a DSL to represent processes as finite state machines and their concurrent composition. A detector traverses all possible states of the concurrent system, and reports on deadlocks, namely states in which no process can take the next step. Also, the package provides Graphviz style outputs, so you can intuitively view the state space of your system.

Example: Dining Philosophers Problem

The dining philosophers problem is one of the best-known examples of concurrent programming. In this model, some philosophers are sitting on a round table and forks are served between each philosopher. A pasta bawl is also served at the centre of the table, but philosophers have to hold both of left/right forks to help themselves. Here the philosophers are analogues of processes/threads, and the forks are that of shared resources.

philosophers and forks around a table

In a naive implementation of this setting, for example, all philosophers act as following:

  1. Pick up the fork on the left side
  2. Pick up the fork on the right side
  3. Eat the pasta
  4. Put down the fork on the right side
  5. Put down the fork on the left side

When multiple philosophers act like this concurrently, as you noticed, it results in a deadlock. Let's model the situation and detect the deadlocked state by this package.

As the simplest case, assume that only two philosophers sitting on the table. We define two processes P1, P2 to represent the philosophers, and two shared variables f1, f2 for forks. The fork f1 is on P1's left side, and the f2 is on his right side.

package main

import (
	"fmt"
	"os"

	"github.com/y-taka-23/ddsv-go/deadlock"
	"github.com/y-taka-23/ddsv-go/deadlock/rule"
	"github.com/y-taka-23/ddsv-go/deadlock/rule/do"
	"github.com/y-taka-23/ddsv-go/deadlock/rule/vars"
	"github.com/y-taka-23/ddsv-go/deadlock/rule/when"
)

func main() {

	philo := func(me int, left, right vars.Name) deadlock.Process {
		return deadlock.NewProcess().
			EnterAt("0").
			// Pick up the fork on his left side
			Define(rule.At("0").Only(when.Var(left).Is(0)).
				Let("up_l", do.Set(me).ToVar(left)).MoveTo("1")).
			// Pick up the fork on his right side
			Define(rule.At("1").Only(when.Var(right).Is(0)).
				Let("up_r", do.Set(me).ToVar(right)).MoveTo("2")).
			// Put down the fork on his right side
			Define(rule.At("2").Only(when.Var(right).Is(me)).
				Let("down_r", do.Set(0).ToVar(right)).MoveTo("3")).
			// Put down the fork on his left side
			Define(rule.At("3").Only(when.Var(left).Is(me)).
				Let("down_l", do.Set(0).ToVar(left)).MoveTo("0"))
	}

	system := deadlock.NewSystem().
		Declare(vars.Shared{"f1": 0, "f2": 0}).
		Register("P1", philo(1, "f1", "f2")).
		Register("P2", philo(1, "f2", "f1"))

	report, err := deadlock.NewDetector().Detect(system)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	_, err = deadlock.NewPrinter(os.Stdout).Print(report)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

}

transition graph which has a deadlocked state

The red arrows show you an error trace from the initial state (blue) to a deadlock (red.) In the error firstly P1 gets f1 (P1.up_l) then P2 gets f2 (P2.up_l.) At the deadlock, P1 waits f2 and P2 waits f1 respectively forever.

Then, how can we solve the deadlock problem? One idea is to let philosophers put down his first fork if his second fork is occupied by another philosopher, and try again. Add the following lines in the definition of philo. Run the detector again, and you see the deadlock state disappears.

// Discard the fork in his left side
Define(rule.At("1").Only(when.Var(right).IsNot(0)).
	Let("down_l", do.Set(0).ToVar(left)).MoveTo("0")).

transition graph without the deadlock

More examples are demonstrated in the examples directory. Check it out!

Acknowledgements

Similar Resources

Goroutine Leak Detector

Leaktest Refactored, tested variant of the goroutine leak detector found in both net/http tests and the cockroachdb source tree. Takes a snapshot of r

Dec 26, 2022

A toy GameBoy Color emulator written in golang.

A toy GameBoy Color emulator written in golang.

🌏 worldwide 日本語のドキュメントはこちら GameBoyColor emulator written in golang. This emulator can play a lot of ROMs work without problems and has many features.

Jan 1, 2023

A toy language parser, lexer and interpreter written in Golang

Monkey - A toy programming language Monkey is a toy programming language used to learn how to write a lexer, parser and interpreter. The language is i

Nov 16, 2021

A toy project to stream from a Remarkable2

goMarkableStream I use this toy project to stream my remarkable 2 (firmware 2.5) on my laptop using the local wifi. video/demo here Quick start You ne

Dec 31, 2022

Toy gRPC Tunnel over CloudFlare (Proof of Concept)

Toy gRPC Tunnel over CloudFlare (Proof of Concept)

gun You know what it means. Guide Server Go to your domain in CloudFlare. In "Network" tab, turn on gRPC.

Jan 6, 2023

Toy Lisp 1.5 interpreter

Lisp 1.5 To install: go get robpike.io/lisp. This is an implementation of the language defined, with sublime concision, in the first few pages of the

Jan 1, 2023

Toy TLS certificate viewer

veilig Toy tls certificate viewer that I built because openssl s_client confuses me Source available at: https://github.com/noqqe/veilig/ Please repor

Aug 25, 2022

A toy MMO example built using Ebiten and WebRTC DataChannels (UDP)

A toy MMO example built using Ebiten and WebRTC DataChannels (UDP)

Ebiten WebRTC Toy MMO ⚠️ This is a piece of incomplete hobby work and not robust. Please read the "Why does this project exist?" section. What is this

Aug 28, 2022

Toy Shader in TinyGo for Game Boy Advance.

Toy Shader in TinyGo for Game Boy Advance.

toyshader.gba Toy Shader in TinyGo for Game Boy Advance. Releases v0.2: 80x80 screen with 3x2 pixel block version for drawing speed. v0.1: 240x160 pix

Oct 29, 2022

Toy program for benchmarking safe and unsafe ways of saving a file

save-a-file benchmarks the many strategies an editor could use to save a file. Example output on a SSD: ext4: $ ./save-a-file ~/tmp/foo 29.195µs per s

Jan 4, 2023

A toy ray tracer to practice writing go.

pbrt-go A toy ray tracer written to practice writing go. Slowly working towards an implementation based on the excellent 3rd edition of PBRT, because

Oct 19, 2021

My toy gin-like webframe

gan-webframe My toy gin-like webframe gan named after my favourite cartoon character Stan in South Park! Usage: func main() { r := gan.Default() //

Nov 21, 2021

Implement a toy in-memory store information service for a delivery company

Implement a toy in-memory store information service for a delivery company

Nov 22, 2021

A toy repo used to test the functionality of "go mod why".

Mod Why Test Discussion From a module perspective: The main module (github.com/ejweber/mod-why-test) has a single direct dependency (github.com/ejwebe

Dec 1, 2021

A simple toy example for running Graphsync + libp2p.

A simple toy example for running Graphsync + libp2p.

graphsync-example Here we outline a simple toy example (main.go) where two local peers transfer Interplanetary Linked Data (IPLD) graphs using Graphsy

Dec 8, 2021

Goava: a toy project to explore Go generics

Goava This is a toy project to explore Go generics. Totally WIP. The idea is to create an in memory cache similar to Java's popular Guava cache. Gener

Dec 16, 2021

Toy application level encryption protocol

noodle A toy application level encryption module. A a high level, it provides co

Jan 3, 2022

Toy scripting language with a syntax similar to Rust.

Dust - toy scripting language Toy scripting language with a syntax similar to Rust. 👍 Syntax similar to Rust 👍 Loose JSON parsing 👍 Calling host fu

Sep 28, 2022

A toy project like cowsay or ponysay

A toy project like cowsay or ponysay

xkcdsay is a simple application just for fun. Once again, Just for fun. I like c

Dec 23, 2022
PHP parser written in Go
PHP parser written in Go

PHP Parser written in Go This project uses goyacc and ragel tools to create PHP parser. It parses source code into AST. It can be used to write static

Dec 30, 2022
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go

Sloc Cloc and Code (scc) A tool similar to cloc, sloccount and tokei. For counting physical the lines of code, blank lines, comment lines, and physica

Jan 4, 2023
A Log4J Version 2 Detector written in golang

Installation From source: go install github.com/juergenhoetzel/log4j2go/cmd/log4

Dec 20, 2021
Goroutine leak detector

goleak Goroutine leak detector to help avoid Goroutine leaks. Installation You can use go get to get the latest version: go get -u go.uber.org/goleak

Dec 30, 2022
Chronos - A static race detector for the go language
Chronos - A static race detector for the go language

Chronos Chronos is a static race detector for the Go language written in Go. Quick Start: Download the package go get -v github.com/amit-davidson/Chro

Dec 12, 2022
A faster file programming language detector
A faster file programming language detector

Programming language detector and toolbox to ignore binary or vendored files. enry, started as a port to Go of the original Linguist Ruby library, that has an improved 2x performance.

Jan 1, 2023
TProx is a fast reverse proxy path traversal detector and directory bruteforcer.
TProx is a fast reverse proxy path traversal detector and directory bruteforcer.

TProx is a fast reverse proxy path traversal detector and directory bruteforcer Install • Usage • Examples • Join Discord Install Options From Source

Nov 9, 2022
A detector for the Trojan Source and other unicode-based vulnerabilities.

Trojan Source Detector This application detects Trojan Source attacks in source code. It can be used as part of the CI system to make sure there are n

Jan 6, 2022
Log4j detector and reporting server for scalable detection of vulnerable running processes.

Log4j Detector A client and reporting server to identify systems vulnerable to Log4j at scale. This work is based on Stripe's Remediation Tools, but w

Apr 8, 2022
User Agents detector for tv, phone, tablet and desktop devices.

gouseragents Accurate and fresh list of desktop, phone, tablet and tv user agents. install go get github.com/emetriq/gouseragents usage import ( "f

Apr 26, 2022