Skip to content

Commit e18a35d

Browse files
committed
[#224] Add documentation and example for PlacementDefault
1 parent c4d8e26 commit e18a35d

File tree

9 files changed

+34
-14
lines changed

9 files changed

+34
-14
lines changed

FAQ.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ Use the feature flag `enforce_32bit_rwlock_atomic` which enforces 32-bit atomics
2424
targets at the cost of the lock-free guarantee. Meaning, when an application crashes at the wrong
2525
point in time it can lead to a system deadlock.
2626

27+
## My Transmission Type Is Too Large, Encounter Stack Overflow On Initialization.
28+
29+
Take a look at the
30+
[complex data types example](examples/rust/complex_data_types).
31+
32+
In this example the `PlacementDefault` trait is introduced that allows in place initialization
33+
and solves the stack overflow issue when the data type is larger than the available stack size.
34+
2735
## Application does not remove services/ports on shutdown or several application restarts lead to port count exceeded
2836

2937
The structs of iceoryx2 need to be able to cleanup all resources when they

examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ they interact and exchange data.
3838

3939
| Name | Description |
4040
|------|-------------|
41-
| [complex data types](rust/complex_data_types) | Send zero-copy compatible versions of `Vec`, `String`, .... |
41+
| [complex data types](rust/complex_data_types) | Send zero-copy compatible versions of `Vec` and `String`. Introduces `PlacementDefault` trait for large data types to perform an in place initialization where otherwise a stack overflow would be encountered.|
4242
| [discovery](rust/discovery) | List all available services in a system. |
4343
| [docker](rust/docker) | Communicate between different docker containers and the host. |
4444
| [event](rust/event) | Exchanging event signals between multiple processes.|

examples/rust/complex_data_types/complex_data_types.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,24 @@ use iceoryx2_bb_container::{
1717
byte_string::FixedSizeByteString, queue::FixedSizeQueue, vec::FixedSizeVec,
1818
};
1919

20-
#[derive(Debug, Default)]
20+
// For both data types we derive from PlacementDefault to allow in memory initialization
21+
// without any copy. Avoids stack overflows when data type is larger than the available stack.
22+
#[derive(Debug, Default, PlacementDefault)]
2123
#[repr(C)]
2224
pub struct ComplexData {
2325
name: FixedSizeByteString<4>,
2426
data: FixedSizeVec<u64, 4>,
2527
}
2628

27-
#[derive(Debug, Default)]
29+
// For both data types we derive from PlacementDefault to allow in memory initialization
30+
// without any copy. Avoids stack overflows when data type is larger than the available stack.
31+
#[derive(Debug, Default, PlacementDefault)]
2832
#[repr(C)]
2933
pub struct ComplexDataType {
3034
plain_old_data: u64,
3135
text: FixedSizeByteString<8>,
3236
vec_of_data: FixedSizeVec<u64, 4>,
33-
vec_of_complex_data: FixedSizeVec<ComplexData, 4>,
37+
vec_of_complex_data: FixedSizeVec<ComplexData, 404857>,
3438
a_queue_of_things: FixedSizeQueue<FixedSizeByteString<4>, 2>,
3539
}
3640

@@ -50,10 +54,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
5054
let mut counter = 0;
5155

5256
while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) {
53-
// acquire and send out sample
54-
let mut sample = publisher.loan()?;
55-
let payload = sample.payload_mut();
57+
// ComplexDataType as a size of over 30MB, we need to perform a placement new
58+
// otherwise we will encounter a StackOverflow.
59+
// Therefore, we acquire an uninitialized sample, use the PlacementDefault
60+
// trait to initialize ComplexDataType in place and then populate it with data.
61+
let mut sample = publisher.loan_uninit()?;
62+
unsafe { ComplexDataType::placement_default(sample.payload_mut().as_mut_ptr()) };
63+
let mut sample = unsafe { sample.assume_init() };
5664

65+
let payload = sample.payload_mut();
5766
payload.plain_old_data = counter;
5867
payload.text = FixedSizeByteString::from_bytes(b"hello")?;
5968
payload.vec_of_data.push(counter);

iceoryx2-bb/container/src/byte_string.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use std::{
3838
};
3939

4040
use iceoryx2_bb_derive_macros::PlacementDefault;
41+
use iceoryx2_bb_elementary::placement_default::PlacementDefault;
4142
use iceoryx2_bb_log::{fail, fatal_panic};
4243

4344
/// Returns the length of a string

iceoryx2-bb/container/src/semantic_string.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@
6060
//! }
6161
//! ```
6262
63-
pub use iceoryx2_bb_elementary::placement_default::PlacementDefault;
64-
6563
use crate::byte_string::FixedSizeByteStringModificationError;
6664
use crate::byte_string::{as_escaped_string, strnlen, FixedSizeByteString};
6765
use iceoryx2_bb_elementary::enum_gen;
@@ -381,10 +379,10 @@ macro_rules! semantic_string {
381379
value: iceoryx2_bb_container::byte_string::FixedSizeByteString<$capacity>
382380
}
383381

384-
impl iceoryx2_bb_container::semantic_string::PlacementDefault for $string_name {
382+
impl iceoryx2_bb_elementary::placement_default::PlacementDefault for $string_name {
385383
unsafe fn placement_default(ptr: *mut Self) {
386384
let ptr = core::ptr::addr_of_mut!((&mut *ptr).value);
387-
iceoryx2_bb_container::semantic_string::PlacementDefault::placement_default(ptr)
385+
iceoryx2_bb_elementary::placement_default::PlacementDefault::placement_default(ptr)
388386
}
389387
}
390388

iceoryx2-bb/derive-macros/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn placement_default_derive(input: TokenStream) -> TokenStream {
5656
let name = &f.ident;
5757
quote! {
5858
let field_address = core::ptr::addr_of_mut!((*ptr).#name);
59-
iceoryx2_bb_elementary::placement_default::PlacementDefault::placement_default(field_address);
59+
PlacementDefault::placement_default(field_address);
6060
}
6161
});
6262

@@ -71,7 +71,7 @@ pub fn placement_default_derive(input: TokenStream) -> TokenStream {
7171
let index = syn::Index::from(i);
7272
quote! {
7373
let field_address = core::ptr::addr_of_mut!((*ptr).#index);
74-
iceoryx2_bb_elementary::placement_default::PlacementDefault::placement_default(field_address);
74+
PlacementDefault::placement_default(field_address);
7575
}
7676
});
7777

@@ -92,7 +92,7 @@ pub fn placement_default_derive(input: TokenStream) -> TokenStream {
9292
};
9393

9494
let expanded = quote! {
95-
impl #impl_generics iceoryx2_bb_elementary::placement_default::PlacementDefault for #name #ty_generics #where_clause {
95+
impl #impl_generics PlacementDefault for #name #ty_generics #where_clause {
9696
#place_default_impl
9797
}
9898
};

iceoryx2-bb/system-types/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ version = { workspace = true }
1414
iceoryx2-bb-container = { workspace = true }
1515
iceoryx2-bb-log = { workspace = true }
1616
iceoryx2-pal-configuration = { workspace = true }
17+
iceoryx2-bb-elementary = { workspace = true }
1718
serde = { workspace = true }
1819

1920
[dev-dependencies]

iceoryx2/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enforce_32bit_rwlock_atomic = ["iceoryx2-pal-concurrency-sync/enforce_32bit_rwlo
2222

2323
[dependencies]
2424
iceoryx2-bb-container = { workspace = true }
25+
iceoryx2-bb-derive-macros = { workspace = true }
2526
iceoryx2-bb-system-types = { workspace = true }
2627
iceoryx2-bb-lock-free = { workspace = true }
2728
iceoryx2-bb-log = { workspace = true }

iceoryx2/src/prelude.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ pub use crate::service::{
1717
port_factory::publisher::UnableToDeliverStrategy, process_local, service_name::ServiceName,
1818
zero_copy, Service,
1919
};
20+
pub use iceoryx2_bb_derive_macros::PlacementDefault;
2021
pub use iceoryx2_bb_elementary::alignment::Alignment;
22+
pub use iceoryx2_bb_elementary::placement_default::PlacementDefault;

0 commit comments

Comments
 (0)