Merge pull request #5035 from Sojamann/sync_chan-maintainance

core:sync/chan: maintainance and package clarity
This commit is contained in:
Jeroen van Rijn
2025-04-13 23:13:07 +02:00
committed by GitHub

View File

@@ -1037,139 +1037,6 @@ is_closed :: proc "contextless" (c: ^Raw_Chan) -> bool {
return bool(c.closed)
}
/*
`Raw_Queue` is a non-thread-safe queue implementation designed to store messages
of fixed size and alignment.
Note: For most use cases, it is recommended to use `core:container/queue` instead,
as `Raw_Queue` is used internally by `Raw_Chan` and may not provide the desired
level of convenience for typical applications.
*/
Raw_Queue :: struct {
data: [^]byte,
len: int,
cap: int,
next: int,
size: int, // element size
}
/*
Initializes a `Raw_Queue`
**Inputs**
- `q`: A pointert to the `Raw_Queue` to initialize
- `data`: The pointer to backing slice storing the messages
- `cap`: The capacity of the queue
- `size`: The size of a message
Example:
import "core:sync/chan"
raw_queue_init_example :: proc() {
// use a stack allocated array as backing storage
storage: [100]int
rq: chan.Raw_Queue
chan.raw_queue_init(&rq, &storage, cap(storage), size_of(int))
}
*/
raw_queue_init :: proc "contextless" (q: ^Raw_Queue, data: rawptr, cap: int, size: int) {
q.data = ([^]byte)(data)
q.len = 0
q.cap = cap
q.next = 0
q.size = size
}
/*
Add an element to the queue.
Note: The message referenced by `data` must match the size
and alignment used when the `Raw_Queue` was initialized.
**Inputs**
- `q`: A pointert to the `Raw_Queue`
- `data`: The pointer to message to add
**Returns**
- `true` if the element was added, `false` when the queue is already full
Example:
import "core:sync/chan"
raw_queue_push_example :: proc() {
storage: [100]int
rq: chan.Raw_Queue
chan.raw_queue_init(&rq, &storage, cap(storage), size_of(int))
value := 2
assert(chan.raw_queue_push(&rq, &value), "there was enough space")
}
*/
@(require_results)
raw_queue_push :: proc "contextless" (q: ^Raw_Queue, data: rawptr) -> bool {
if q.len == q.cap {
return false
}
pos := q.next + q.len
if pos >= q.cap {
pos -= q.cap
}
val_ptr := q.data[pos*q.size:]
mem.copy(val_ptr, data, q.size)
q.len += 1
return true
}
/*
Removes and returns the first element of the queue.
Note: The returned element is only guaranteed to be valid until the next
`raw_queue_push` operation. Accessing it after that point may result in
undefined behavior.
**Inputs**
- `c`: A pointer to the `Raw_Queue`.
**Returns**
- A pointer to the first element in the queue, or `nil` if the queue is empty.
Example:
import "core:sync/chan"
raw_queue_pop_example :: proc() {
storage: [100]int
rq: chan.Raw_Queue
chan.raw_queue_init(&rq, &storage, cap(storage), size_of(int))
assert(chan.raw_queue_pop(&rq) == nil, "queue was empty")
// add an element to the queue
value := 2
assert(chan.raw_queue_push(&rq, &value), "there was enough space")
assert((cast(^int)chan.raw_queue_pop(&rq))^ == 2, "retrieved the element")
}
*/
@(require_results)
raw_queue_pop :: proc "contextless" (q: ^Raw_Queue) -> (data: rawptr) {
if q.len > 0 {
data = q.data[q.next*q.size:]
q.next += 1
q.len -= 1
if q.next >= q.cap {
q.next -= q.cap
}
}
return
}
/*
Returns whether a message is ready to be read, i.e.,
if a call to `recv` or `recv_raw` would block
@@ -1347,3 +1214,137 @@ select_raw :: proc "odin" (recvs: []^Raw_Chan, sends: []^Raw_Chan, send_msgs: []
}
return
}
/*
`Raw_Queue` is a non-thread-safe queue implementation designed to store messages
of fixed size and alignment.
Note: For most use cases, it is recommended to use `core:container/queue` instead,
as `Raw_Queue` is used internally by `Raw_Chan` and may not provide the desired
level of convenience for typical applications.
*/
@(private)
Raw_Queue :: struct {
data: [^]byte,
len: int,
cap: int,
next: int,
size: int, // element size
}
/*
Initializes a `Raw_Queue`
**Inputs**
- `q`: A pointert to the `Raw_Queue` to initialize
- `data`: The pointer to backing slice storing the messages
- `cap`: The capacity of the queue
- `size`: The size of a message
Example:
import "core:sync/chan"
raw_queue_init_example :: proc() {
// use a stack allocated array as backing storage
storage: [100]int
rq: chan.Raw_Queue
chan.raw_queue_init(&rq, &storage, cap(storage), size_of(int))
}
*/
@(private)
raw_queue_init :: proc "contextless" (q: ^Raw_Queue, data: rawptr, cap: int, size: int) {
q.data = ([^]byte)(data)
q.len = 0
q.cap = cap
q.next = 0
q.size = size
}
/*
Add an element to the queue.
Note: The message referenced by `data` must match the size
and alignment used when the `Raw_Queue` was initialized.
**Inputs**
- `q`: A pointert to the `Raw_Queue`
- `data`: The pointer to message to add
**Returns**
- `true` if the element was added, `false` when the queue is already full
Example:
import "core:sync/chan"
raw_queue_push_example :: proc() {
storage: [100]int
rq: chan.Raw_Queue
chan.raw_queue_init(&rq, &storage, cap(storage), size_of(int))
value := 2
assert(chan.raw_queue_push(&rq, &value), "there was enough space")
}
*/
@(private, require_results)
raw_queue_push :: proc "contextless" (q: ^Raw_Queue, data: rawptr) -> bool {
if q.len == q.cap {
return false
}
pos := q.next + q.len
if pos >= q.cap {
pos -= q.cap
}
val_ptr := q.data[pos*q.size:]
mem.copy(val_ptr, data, q.size)
q.len += 1
return true
}
/*
Removes and returns the first element of the queue.
Note: The returned element is only guaranteed to be valid until the next
`raw_queue_push` operation. Accessing it after that point may result in
undefined behavior.
**Inputs**
- `c`: A pointer to the `Raw_Queue`.
**Returns**
- A pointer to the first element in the queue, or `nil` if the queue is empty.
Example:
import "core:sync/chan"
raw_queue_pop_example :: proc() {
storage: [100]int
rq: chan.Raw_Queue
chan.raw_queue_init(&rq, &storage, cap(storage), size_of(int))
assert(chan.raw_queue_pop(&rq) == nil, "queue was empty")
// add an element to the queue
value := 2
assert(chan.raw_queue_push(&rq, &value), "there was enough space")
assert((cast(^int)chan.raw_queue_pop(&rq))^ == 2, "retrieved the element")
}
*/
@(private, require_results)
raw_queue_pop :: proc "contextless" (q: ^Raw_Queue) -> (data: rawptr) {
if q.len > 0 {
data = q.data[q.next*q.size:]
q.next += 1
q.len -= 1
if q.next >= q.cap {
q.next -= q.cap
}
}
return
}