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
//! `static` friendly data structures that don't require dynamic memory
//! allocation
//! allocation
#![deny(missing_docs)]
#![feature(const_fn)]
#![feature(const_fn)]
#![feature(shared)]
#![feature(shared)]
#![feature(unsize)]
#![feature(unsize)]
...
@@ -14,8 +15,6 @@ pub use ring_buffer::RingBuffer;
...
@@ -14,8 +15,6 @@ pub use ring_buffer::RingBuffer;
pub
mod
ring_buffer
;
pub
mod
ring_buffer
;
mod
vec
;
mod
vec
;
/// Error
/// Error
raised when the buffer is full
#[derive(Clone,
Copy,
Debug,
Eq,
PartialEq)]
#[derive(Clone,
Copy,
Debug,
Eq,
PartialEq)]
pub
enum
Error
{
pub
struct
BufferFullError
;
Full
,
}
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
::
marker
::{
PhantomData
,
Unsize
};
use
core
::
ptr
;
use
core
::
ptr
;
use
untagged_option
::
UntaggedOption
;
use
untagged_option
::
UntaggedOption
;
use
Error
;
use
BufferFull
Error
;
pub
use
self
::
spsc
::{
Consumer
,
Producer
};
pub
use
self
::
spsc
::{
Consumer
,
Producer
};
mod
spsc
;
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
>
pub
struct
RingBuffer
<
T
,
A
>
where
where
// FIXME(rust-lang/rust#44580) use "const generics" instead of `Unsize`
// FIXME(rust-lang/rust#44580) use "const generics" instead of `Unsize`
...
@@ -38,11 +40,13 @@ where
...
@@ -38,11 +40,13 @@ where
}
}
}
}
/// Returns the maximum number of elements the ring buffer can hold
pub
fn
capacity
(
&
self
)
->
usize
{
pub
fn
capacity
(
&
self
)
->
usize
{
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
buffer
.len
()
-
1
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
>
{
pub
fn
dequeue
(
&
mut
self
)
->
Option
<
T
>
{
let
n
=
self
.capacity
()
+
1
;
let
n
=
self
.capacity
()
+
1
;
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
...
@@ -56,7 +60,10 @@ where
...
@@ -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
n
=
self
.capacity
()
+
1
;
let
buffer
:
&
mut
[
T
]
=
unsafe
{
self
.buffer
.as_mut
()
};
let
buffer
:
&
mut
[
T
]
=
unsafe
{
self
.buffer
.as_mut
()
};
...
@@ -68,10 +75,11 @@ where
...
@@ -68,10 +75,11 @@ where
self
.tail
=
next_tail
;
self
.tail
=
next_tail
;
Ok
(())
Ok
(())
}
else
{
}
else
{
Err
(
Error
::
Full
)
Err
(
BufferFullError
)
}
}
}
}
/// Returns the number of elements in the queue
pub
fn
len
(
&
self
)
->
usize
{
pub
fn
len
(
&
self
)
->
usize
{
if
self
.head
>
self
.tail
{
if
self
.head
>
self
.tail
{
self
.head
-
self
.tail
self
.head
-
self
.tail
...
@@ -89,7 +97,7 @@ where
...
@@ -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
>
{
pub
fn
iter_mut
(
&
mut
self
)
->
IterMut
<
T
,
A
>
{
let
len
=
self
.len
();
let
len
=
self
.len
();
IterMut
{
IterMut
{
...
@@ -137,6 +145,7 @@ where
...
@@ -137,6 +145,7 @@ where
}
}
}
}
/// An iterator over a ring buffer items
pub
struct
Iter
<
'a
,
T
,
A
>
pub
struct
Iter
<
'a
,
T
,
A
>
where
where
A
:
Unsize
<
[
T
]
>
+
'a
,
A
:
Unsize
<
[
T
]
>
+
'a
,
...
@@ -147,6 +156,7 @@ where
...
@@ -147,6 +156,7 @@ where
len
:
usize
,
len
:
usize
,
}
}
/// A mutable iterator over a ring buffer items
pub
struct
IterMut
<
'a
,
T
,
A
>
pub
struct
IterMut
<
'a
,
T
,
A
>
where
where
A
:
Unsize
<
[
T
]
>
+
'a
,
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
::
ptr
::{
self
,
Shared
};
use
core
::
marker
::
Unsize
;
use
core
::
marker
::
Unsize
;
use
Error
;
use
BufferFull
Error
;
use
ring_buffer
::
RingBuffer
;
use
ring_buffer
::
RingBuffer
;
impl
<
T
,
A
>
RingBuffer
<
T
,
A
>
impl
<
T
,
A
>
RingBuffer
<
T
,
A
>
...
@@ -9,6 +9,9 @@ where
...
@@ -9,6 +9,9 @@ where
A
:
Unsize
<
[
T
]
>
,
A
:
Unsize
<
[
T
]
>
,
{
{
/// Splits a statically allocated ring buffer into producer and consumer end points
/// 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
>
)
{
pub
fn
split
(
&
'static
mut
self
)
->
(
Producer
<
T
,
A
>
,
Consumer
<
T
,
A
>
)
{
(
(
Producer
{
Producer
{
...
@@ -35,13 +38,14 @@ impl<T, A> Consumer<T, A>
...
@@ -35,13 +38,14 @@ impl<T, A> Consumer<T, A>
where
where
A
:
Unsize
<
[
T
]
>
,
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
>
{
pub
fn
dequeue
(
&
mut
self
)
->
Option
<
T
>
{
let
rb
=
unsafe
{
self
.rb
.as_mut
()
};
let
rb
=
unsafe
{
self
.rb
.as_mut
()
};
let
n
=
rb
.capacity
()
+
1
;
let
n
=
rb
.capacity
()
+
1
;
let
buffer
:
&
[
T
]
=
unsafe
{
rb
.buffer
.as_ref
()
};
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
// NOTE(volatile) the value of `tail` can change at any time in the
execution
context of the
// so we inform this to the compiler using a volatile load
//
consumer
so we inform this to the compiler using a volatile load
if
rb
.head
!=
unsafe
{
ptr
::
read_volatile
(
&
rb
.tail
)
}
{
if
rb
.head
!=
unsafe
{
ptr
::
read_volatile
(
&
rb
.tail
)
}
{
let
item
=
unsafe
{
ptr
::
read
(
buffer
.as_ptr
()
.offset
(
rb
.head
as
isize
))
};
let
item
=
unsafe
{
ptr
::
read
(
buffer
.as_ptr
()
.offset
(
rb
.head
as
isize
))
};
rb
.head
=
(
rb
.head
+
1
)
%
n
;
rb
.head
=
(
rb
.head
+
1
)
%
n
;
...
@@ -67,14 +71,17 @@ impl<T, A> Producer<T, A>
...
@@ -67,14 +71,17 @@ impl<T, A> Producer<T, A>
where
where
A
:
Unsize
<
[
T
]
>
,
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
rb
=
unsafe
{
self
.rb
.as_mut
()
};
let
n
=
rb
.capacity
()
+
1
;
let
n
=
rb
.capacity
()
+
1
;
let
buffer
:
&
mut
[
T
]
=
unsafe
{
rb
.buffer
.as_mut
()
};
let
buffer
:
&
mut
[
T
]
=
unsafe
{
rb
.buffer
.as_mut
()
};
let
next_tail
=
(
rb
.tail
+
1
)
%
n
;
let
next_tail
=
(
rb
.tail
+
1
)
%
n
;
// NOTE(volatile) the value of `head` can change at any time in the context of the
producer
// NOTE(volatile) the value of `head` can change at any time in the
execution
context of the
// so we inform this to the compiler using a volatile load
//
producer
so we inform this to the compiler using a volatile load
if
next_tail
!=
unsafe
{
ptr
::
read_volatile
(
&
rb
.head
)
}
{
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
// 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
// use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
...
@@ -82,7 +89,7 @@ where
...
@@ -82,7 +89,7 @@ where
rb
.tail
=
next_tail
;
rb
.tail
=
next_tail
;
Ok
(())
Ok
(())
}
else
{
}
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};
...
@@ -3,9 +3,9 @@ use core::{ops, ptr, slice};
use
untagged_option
::
UntaggedOption
;
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
/// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
pub
struct
Vec
<
T
,
A
>
pub
struct
Vec
<
T
,
A
>
...
@@ -22,6 +22,7 @@ impl<T, A> Vec<T, A>
...
@@ -22,6 +22,7 @@ impl<T, A> Vec<T, A>
where
where
A
:
Unsize
<
[
T
]
>
,
A
:
Unsize
<
[
T
]
>
,
{
{
/// Constructs a new, empty `Vec<T>` backed by the array `A`
pub
const
fn
new
()
->
Self
{
pub
const
fn
new
()
->
Self
{
Vec
{
Vec
{
_marker
:
PhantomData
,
_marker
:
PhantomData
,
...
@@ -30,19 +31,13 @@ where
...
@@ -30,19 +31,13 @@ where
}
}
}
}
/// Returns the maximum number of elements the vector can hold
pub
fn
capacity
(
&
self
)
->
usize
{
pub
fn
capacity
(
&
self
)
->
usize
{
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
buffer
.len
()
buffer
.len
()
}
}
pub
fn
iter
(
&
self
)
->
slice
::
Iter
<
T
>
{
/// Removes the last element from a vector and return it, or `None` if it's empty
(
**
self
)
.iter
()
}
pub
fn
iter_mut
(
&
mut
self
)
->
slice
::
IterMut
<
T
>
{
(
**
self
)
.iter_mut
()
}
pub
fn
pop
(
&
mut
self
)
->
Option
<
T
>
{
pub
fn
pop
(
&
mut
self
)
->
Option
<
T
>
{
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
let
buffer
:
&
[
T
]
=
unsafe
{
self
.buffer
.as_ref
()
};
...
@@ -55,7 +50,10 @@ where
...
@@ -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
capacity
=
self
.capacity
();
let
buffer
:
&
mut
[
T
]
=
unsafe
{
self
.buffer
.as_mut
()
};
let
buffer
:
&
mut
[
T
]
=
unsafe
{
self
.buffer
.as_mut
()
};
...
@@ -66,7 +64,7 @@ where
...
@@ -66,7 +64,7 @@ where
self
.len
+=
1
;
self
.len
+=
1
;
Ok
(())
Ok
(())
}
else
{
}
else
{
Err
(
Error
::
Full
)
Err
(
BufferFullError
)
}
}
}
}
}
}
...
@@ -152,7 +150,6 @@ mod tests {
...
@@ -152,7 +150,6 @@ mod tests {
static
mut
COUNT
:
i32
=
0
;
static
mut
COUNT
:
i32
=
0
;
{
{
let
mut
v
:
Vec
<
Droppable
,
[
Droppable
;
2
]
>
=
Vec
::
new
();
let
mut
v
:
Vec
<
Droppable
,
[
Droppable
;
2
]
>
=
Vec
::
new
();
v
.push
(
Droppable
::
new
())
.unwrap
();
v
.push
(
Droppable
::
new
())
.unwrap
();
...
@@ -231,5 +228,4 @@ mod tests {
...
@@ -231,5 +228,4 @@ mod tests {
assert_eq!
(
v
.pop
(),
None
);
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