Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
H
heapless
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Per Lindgren
heapless
Commits
e841c8a6
Commit
e841c8a6
authored
Oct 31, 2017
by
Jorge Aparicio
Browse files
Options
Downloads
Patches
Plain Diff
update the documentation
parent
09682676
No related branches found
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/lib.rs
+3
-4
3 additions, 4 deletions
src/lib.rs
src/ring_buffer/mod.rs
+15
-5
15 additions, 5 deletions
src/ring_buffer/mod.rs
src/ring_buffer/spsc.rs
+14
-7
14 additions, 7 deletions
src/ring_buffer/spsc.rs
src/vec.rs
+10
-14
10 additions, 14 deletions
src/vec.rs
with
42 additions
and
30 deletions
src/lib.rs
+
3
−
4
View file @
e841c8a6
//! `static` friendly data structures that don't require dynamic memory
//! allocation
#![deny(missing_docs)]
#![feature(const_fn)]
#![feature(shared)]
#![feature(unsize)]
...
...
@@ -14,8 +15,6 @@ pub use ring_buffer::RingBuffer;
pub
mod
ring_buffer
;
mod
vec
;
/// Error
/// Error
raised when the buffer is full
#[derive(Clone,
Copy,
Debug,
Eq,
PartialEq)]
pub
enum
Error
{
Full
,
}
pub
struct
BufferFullError
;
This diff is collapsed.
Click to expand it.
src/ring_buffer/mod.rs
+
15
−
5
View file @
e841c8a6
//! Ring buffer
use
core
::
marker
::{
PhantomData
,
Unsize
};
use
core
::
ptr
;
use
untagged_option
::
UntaggedOption
;
use
Error
;
use
BufferFull
Error
;
pub
use
self
::
spsc
::{
Consumer
,
Producer
};
mod
spsc
;
/// An statically allocated ring buffer backed by an array
with type
`A`
/// An statically allocated ring buffer backed by an array `A`
pub
struct
RingBuffer
<
T
,
A
>
where
// FIXME(rust-lang/rust#44580) use "const generics" instead of `Unsize`
...
...
@@ -38,11 +40,13 @@ where
}
}
/// Returns the maximum number of elements the ring buffer can hold
pub
fn
capacity
(
&
self
)
->
usize
{
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
buffer
.len
()
-
1
}
/// Returns the item in the front of the queue, or `None` if the queue is empty
pub
fn
dequeue
(
&
mut
self
)
->
Option
<
T
>
{
let
n
=
self
.capacity
()
+
1
;
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
...
...
@@ -56,7 +60,10 @@ where
}
}
pub
fn
enqueue
(
&
mut
self
,
item
:
T
)
->
Result
<
(),
Error
>
{
/// Adds an `item` to the end of the queue
///
/// Returns `BufferFullError` if the queue is full
pub
fn
enqueue
(
&
mut
self
,
item
:
T
)
->
Result
<
(),
BufferFullError
>
{
let
n
=
self
.capacity
()
+
1
;
let
buffer
:
&
mut
[
T
]
=
unsafe
{
self
.buffer
.as_mut
()
};
...
...
@@ -68,10 +75,11 @@ where
self
.tail
=
next_tail
;
Ok
(())
}
else
{
Err
(
Error
::
Full
)
Err
(
BufferFullError
)
}
}
/// Returns the number of elements in the queue
pub
fn
len
(
&
self
)
->
usize
{
if
self
.head
>
self
.tail
{
self
.head
-
self
.tail
...
...
@@ -89,7 +97,7 @@ where
}
}
///
Mutable version of `iter`
///
Returns an iterator that allows modifying each value.
pub
fn
iter_mut
(
&
mut
self
)
->
IterMut
<
T
,
A
>
{
let
len
=
self
.len
();
IterMut
{
...
...
@@ -137,6 +145,7 @@ where
}
}
/// An iterator over a ring buffer items
pub
struct
Iter
<
'a
,
T
,
A
>
where
A
:
Unsize
<
[
T
]
>
+
'a
,
...
...
@@ -147,6 +156,7 @@ where
len
:
usize
,
}
/// A mutable iterator over a ring buffer items
pub
struct
IterMut
<
'a
,
T
,
A
>
where
A
:
Unsize
<
[
T
]
>
+
'a
,
...
...
This diff is collapsed.
Click to expand it.
src/ring_buffer/spsc.rs
+
14
−
7
View file @
e841c8a6
use
core
::
ptr
::{
self
,
Shared
};
use
core
::
marker
::
Unsize
;
use
Error
;
use
BufferFull
Error
;
use
ring_buffer
::
RingBuffer
;
impl
<
T
,
A
>
RingBuffer
<
T
,
A
>
...
...
@@ -9,6 +9,9 @@ where
A
:
Unsize
<
[
T
]
>
,
{
/// Splits a statically allocated ring buffer into producer and consumer end points
///
/// *Warning* the current implementation only supports single core processors. It's also fine to
/// use both end points on the same core of a multi-core processor.
pub
fn
split
(
&
'static
mut
self
)
->
(
Producer
<
T
,
A
>
,
Consumer
<
T
,
A
>
)
{
(
Producer
{
...
...
@@ -35,13 +38,14 @@ impl<T, A> Consumer<T, A>
where
A
:
Unsize
<
[
T
]
>
,
{
/// Returns the item in the front of the queue, or `None` if the queue is empty
pub
fn
dequeue
(
&
mut
self
)
->
Option
<
T
>
{
let
rb
=
unsafe
{
self
.rb
.as_mut
()
};
let
n
=
rb
.capacity
()
+
1
;
let
buffer
:
&
[
T
]
=
unsafe
{
rb
.buffer
.as_ref
()
};
// NOTE(volatile) the value of `tail` can change at any time in the context of the
consumer
// so we inform this to the compiler using a volatile load
// NOTE(volatile) the value of `tail` can change at any time in the
execution
context of the
//
consumer
so we inform this to the compiler using a volatile load
if
rb
.head
!=
unsafe
{
ptr
::
read_volatile
(
&
rb
.tail
)
}
{
let
item
=
unsafe
{
ptr
::
read
(
buffer
.as_ptr
()
.offset
(
rb
.head
as
isize
))
};
rb
.head
=
(
rb
.head
+
1
)
%
n
;
...
...
@@ -67,14 +71,17 @@ impl<T, A> Producer<T, A>
where
A
:
Unsize
<
[
T
]
>
,
{
pub
fn
enqueue
(
&
mut
self
,
item
:
T
)
->
Result
<
(),
Error
>
{
/// Adds an `item` to the end of the queue
///
/// Returns `BufferFullError` if the queue is full
pub
fn
enqueue
(
&
mut
self
,
item
:
T
)
->
Result
<
(),
BufferFullError
>
{
let
rb
=
unsafe
{
self
.rb
.as_mut
()
};
let
n
=
rb
.capacity
()
+
1
;
let
buffer
:
&
mut
[
T
]
=
unsafe
{
rb
.buffer
.as_mut
()
};
let
next_tail
=
(
rb
.tail
+
1
)
%
n
;
// NOTE(volatile) the value of `head` can change at any time in the context of the
producer
// so we inform this to the compiler using a volatile load
// NOTE(volatile) the value of `head` can change at any time in the
execution
context of the
//
producer
so we inform this to the compiler using a volatile load
if
next_tail
!=
unsafe
{
ptr
::
read_volatile
(
&
rb
.head
)
}
{
// NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We
// use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
...
...
@@ -82,7 +89,7 @@ where
rb
.tail
=
next_tail
;
Ok
(())
}
else
{
Err
(
Error
::
Full
)
Err
(
BufferFullError
)
}
}
}
...
...
This diff is collapsed.
Click to expand it.
src/vec.rs
+
10
−
14
View file @
e841c8a6
...
...
@@ -3,9 +3,9 @@ use core::{ops, ptr, slice};
use
untagged_option
::
UntaggedOption
;
use
Error
;
use
BufferFull
Error
;
/// [`Vec`] backed by a fixed size array
///
A
[`Vec`]
, *vector*,
backed by a fixed size array
///
/// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
pub
struct
Vec
<
T
,
A
>
...
...
@@ -22,6 +22,7 @@ impl<T, A> Vec<T, A>
where
A
:
Unsize
<
[
T
]
>
,
{
/// Constructs a new, empty `Vec<T>` backed by the array `A`
pub
const
fn
new
()
->
Self
{
Vec
{
_marker
:
PhantomData
,
...
...
@@ -30,19 +31,13 @@ where
}
}
/// Returns the maximum number of elements the vector can hold
pub
fn
capacity
(
&
self
)
->
usize
{
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
buffer
.len
()
}
pub
fn
iter
(
&
self
)
->
slice
::
Iter
<
T
>
{
(
**
self
)
.iter
()
}
pub
fn
iter_mut
(
&
mut
self
)
->
slice
::
IterMut
<
T
>
{
(
**
self
)
.iter_mut
()
}
/// Removes the last element from a vector and return it, or `None` if it's empty
pub
fn
pop
(
&
mut
self
)
->
Option
<
T
>
{
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
...
...
@@ -55,7 +50,10 @@ where
}
}
pub
fn
push
(
&
mut
self
,
item
:
T
)
->
Result
<
(),
Error
>
{
/// Appends an element to the back of the collection
///
/// Returns `BufferFullError` if the vector is full
pub
fn
push
(
&
mut
self
,
item
:
T
)
->
Result
<
(),
BufferFullError
>
{
let
capacity
=
self
.capacity
();
let
buffer
:
&
mut
[
T
]
=
unsafe
{
self
.buffer
.as_mut
()
};
...
...
@@ -66,7 +64,7 @@ where
self
.len
+=
1
;
Ok
(())
}
else
{
Err
(
Error
::
Full
)
Err
(
BufferFullError
)
}
}
}
...
...
@@ -152,7 +150,6 @@ mod tests {
static
mut
COUNT
:
i32
=
0
;
{
let
mut
v
:
Vec
<
Droppable
,
[
Droppable
;
2
]
>
=
Vec
::
new
();
v
.push
(
Droppable
::
new
())
.unwrap
();
...
...
@@ -231,5 +228,4 @@ mod tests {
assert_eq!
(
v
.pop
(),
None
);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment