Skip to content

Commit c11edf7

Browse files
committed
Prepare for transfer to Raku Community Modules
1 parent c5934d0 commit c11edf7

File tree

13 files changed

+361
-165
lines changed

13 files changed

+361
-165
lines changed

.github/workflows/test.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches:
6+
- '*'
7+
tags-ignore:
8+
- '*'
9+
pull_request:
10+
11+
jobs:
12+
raku:
13+
strategy:
14+
matrix:
15+
os:
16+
- ubuntu-latest
17+
- macOS-latest
18+
- windows-latest
19+
raku-version:
20+
- 'latest'
21+
runs-on: ${{ matrix.os }}
22+
steps:
23+
- uses: actions/checkout@v2
24+
- uses: Raku/setup-raku@v1
25+
with:
26+
raku-version: ${{ matrix.raku-version }}
27+
- name: Run Tests
28+
run: raku run-tests

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
.precomp/
2+
/Concurrent-Stack-*

.travis.yml

Lines changed: 0 additions & 9 deletions
This file was deleted.

Changes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Revision history for Concurrent-Stack
2+
3+
{{$NEXT}}
4+
- Initial version in zef ecosystem

META6.json

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
{
2-
"name": "Concurrent::Stack",
3-
"description": "A lock-free concurrent stack data structure.",
4-
"version": "1.2",
5-
"perl": "6.*",
2+
"auth": "zef:raku-community-modules",
63
"authors": [
74
"Jonathan Worthington <jnthn@jnthn.net>"
85
],
9-
"depends": [],
6+
"build-depends": [
7+
],
8+
"depends": [
9+
],
10+
"description": "A lock-free concurrent stack data structure",
11+
"license": "Artistic-2.0",
12+
"name": "Concurrent::Stack",
13+
"perl": "6.c",
1014
"provides": {
11-
"Concurrent::Stack": "lib/Concurrent/Stack.pm6"
15+
"Concurrent::Stack": "lib/Concurrent/Stack.rakumod"
1216
},
13-
"resources": [],
14-
"license": "Artistic-2.0",
15-
"source-url": "https://github.com/jnthn/p6-concurrent-stack.git"
17+
"resources": [
18+
],
19+
"source-url": "https://github.com/raku-community-modules/Concurrent-Stack.git",
20+
"tags": [
21+
],
22+
"test-depends": [
23+
],
24+
"version": "1.2"
1625
}

README.md

Lines changed: 68 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,94 @@
1-
# Concurrent::Stack
1+
[![Actions Status](https://github.com/lizmat/Concurrent-Stack/actions/workflows/test.yml/badge.svg)](https://github.com/lizmat/Concurrent-Stack/actions)
22

3-
A lock-free stack data structure, safe for concurrent use.
3+
NAME
4+
====
45

5-
## Synopsis
6+
Concurrent::Stack - A lock-free concurrent stack data structure
67

7-
use Concurrent::Stack;
8+
SYNOPSIS
9+
========
810

9-
my $stack = Concurrent::Stack.new;
11+
```raku
12+
use Concurrent::Stack;
1013

11-
for 'a'..'z' {
12-
$stack.push($_);
13-
}
14+
my $stack = Concurrent::Stack.new;
1415

15-
say $stack.elems; # 26
16-
say $stack.peek; # z
17-
say $stack.pop; # z
18-
say $stack.pop; # y
19-
say $stack.peek; # x
20-
$stack.push('k');
21-
say $stack.peek; # k
22-
say $stack.elems; # 25
23-
say $stack.Seq; # A Seq iterating a snapshot of the stack
24-
say $stack.list; # A lazy List with a snapshot of the stack
16+
for 'a'..'z' {
17+
$stack.push($_);
18+
}
2519

26-
$stack.pop for ^25;
27-
say $stack.elems; # 0
28-
my $x = $stack.peek; # Failure with X::Concurrent::Stack::Empty
29-
my $y = $stack.pop; # Failure with X::Concurrent::Stack::Empty
20+
say $stack.elems; # 26
21+
say $stack.peek; # z
22+
say $stack.pop; # z
23+
say $stack.pop; # y
24+
say $stack.peek; # x
25+
$stack.push('k');
26+
say $stack.peek; # k
27+
say $stack.elems; # 25
28+
say $stack.Seq; # A Seq iterating a snapshot of the stack
29+
say $stack.list; # A lazy List with a snapshot of the stack
3030

31-
## Overview
31+
$stack.pop for ^25;
32+
say $stack.elems; # 0
33+
my $x = $stack.peek; # Failure with X::Concurrent::Stack::Empty
34+
my $y = $stack.pop; # Failure with X::Concurrent::Stack::Empty
35+
```
3236

33-
Lock-free data structures may be safely used from multiple threads, yet do not
34-
use locks in their implementation. They achieve this through the use of atomic
35-
operations provided by the hardware. Nothing can make contention between
36-
threads cheap - synchronization at the CPU level is still synchronization -
37-
but lock free data structures tend to scale better.
37+
DESCRIPTION
38+
===========
3839

39-
This lock-free stack data structure uses a linked list of immutable nodes, the
40-
only mutable state being a head pointer to the node representing the stack top
41-
and an element counter mintained through atomic increment/decrement operations.
42-
The element count updates are not performed as part of the stack update, and so
43-
may lag the actual state of the stack. However, since checking the number of
44-
elements to decide whether to `peek` or `pop` is doomed in a concurrent setting
45-
anyway (since another thread may `pop` the last value in the meantime), this is
46-
not problematic. The `elems` method primarily exists so that the number of
47-
elements can be queried once the stack reaches some known stable point (for
48-
example, when a bunch of working threads that `push` to it are all known to
49-
have completed their work).
40+
Lock-free data structures may be safely used from multiple threads, yet do not use locks in their implementation. They achieve this through the use of atomic operations provided by the hardware. Nothing can make contention between threads cheap - synchronization at the CPU level is still synchronization - but lock free data structures tend to scale better.
5041

51-
### Methods
42+
This lock-free stack data structure uses a linked list of immutable nodes, the only mutable state being a head pointer to the node representing the stack top and an element counter mintained through atomic increment/decrement operations. The element count updates are not performed as part of the stack update, and so may lag the actual state of the stack. However, since checking the number of elements to decide whether to `peek` or `pop` is doomed in a concurrent setting anyway (since another thread may `pop` the last value in the meantime), this is not problematic. The `elems` method primarily exists so that the number of elements can be queried once the stack reaches some known stable point (for example, when a bunch of working threads that `push` to it are all known to have completed their work).
5243

53-
#### push(Any $value)
44+
METHODS
45+
=======
46+
47+
push(Any $value)
48+
----------------
5449

5550
Pushes a value onto the stack. Returns the value that was pushed.
5651

57-
#### pop()
52+
pop()
53+
-----
54+
55+
If the stack is not empty, removes the top value and returns it. Otherwise, returns a `Failure` containing an exception of typei `X::Concurrent::Stack::Empty`.
56+
57+
peek()
58+
------
59+
60+
If the stack is not empty, returns the top value. Otherwise, returns a `Failure` containing an exception of type `X::Concurrent::Stack::Empty`.
61+
62+
elems()
63+
-------
64+
65+
Returns the number of elements on the stack. This value can only be relied upon when it is known that no threads are pushing/popping from the stack at the point this method is called. **Never** use the result of `elems` to decide whether to `peek` or `pop`, since another thread may `pop` in the meantime. Instead, check if `peek` or `pop` return a `Failure`.
66+
67+
head2 Bool()
68+
69+
Returns `False` if the stack is empty and `True` if the stack is non-empty. The result can only be relied upon when it is known that no threads are pushing/popping from the stack at the point this method is called. **Never** use the result of `Bool` to decide whether to `peek` or `pop`, since another thread may `pop` in the meantime. Instead, check if `peek` or `pop` return a `Failure`.
5870

59-
If the stack is not empty, removes the top value and returns it. Otherwise,
60-
returns a `Failure` containing an exception of type `X::Concurrent::Stack::Empty`.
71+
Seq()
72+
-----
6173

62-
#### peek()
74+
Returns a `Seq` that will iterate to a snapshot of the stack content, starting from the stack top. The snapshot is made at the time this method is called.
6375

64-
If the stack is not empty, returns the top value. Otherwise, returns a `Failure`
65-
containing an exception of type `X::Concurrent::Stack::Empty`.
76+
list()
77+
------
6678

67-
#### elems()
79+
Returns a `List` that will lazily evaluate to a snapshot of the stack content, starting from the stack top. The snapshot is made at the time this method is called.
6880

69-
Returns the number of elements on the stack. This value can only be relied upon
70-
when it is known that no threads are pushing/popping from the stack at the
71-
point this method is called. Never use the result of `elems` to decide whether
72-
to `peek` or `pop`, since another thread may `pop` in the meantime. Instead,
73-
check if `peek` or `pop` return a `Failure`.
81+
AUTHOR
82+
======
7483

75-
#### Bool()
84+
Jonathan Worthington
7685

77-
Returns `False` if the stack is empty and `True` if the stack is non-empty.
78-
The result can only be relied upon when it is known that no threads are
79-
pushing/popping from the stack at the point this method is called. Never use
80-
the result of `Bool` to decide whether to `peek` or `pop`, since another
81-
thread may `pop` in the meantime. Instead, check if `peek` or `pop` return a
82-
`Failure`.
86+
COPYRIGHT AND LICENSE
87+
=====================
8388

84-
#### Seq()
89+
Copyright 2018 - 2024 Raku Community
8590

86-
Returns a `Seq` that will iterate to a snapshot of the stack content,
87-
starting from the stack top. The snapshot is made at the time this
88-
method is called.
91+
Copyright 2024 Raku Community
8992

90-
#### list()
93+
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.
9194

92-
Returns a `List` that will lazily evaluate to a snapshot of the stack
93-
content, starting from the stack top. The snapshot is made at the time
94-
this method is called.

dist.ini

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name = Concurrent-Stack
2+
3+
[ReadmeFromPod]
4+
filename = lib/Concurrent/Stack.rakumod
5+
6+
[UploadToZef]
7+
8+
[Badges]
9+
provider = github-actions/test.yml

lib/Concurrent/Stack.pm6

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)