Skip to content

Commit 584c1da

Browse files
authored
Lockfree queue 2 (#20)
* Optional lockfree transport layer queue * Optional XCP_ENABLE_APP_ADDRESSING * xcptl_cfg.h to lower case
1 parent bed604c commit 584c1da

File tree

18 files changed

+838
-364
lines changed

18 files changed

+838
-364
lines changed

tests/test_multi_thread.rs

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ use xcp_test_executor::test_executor;
2424

2525
const TEST_CAL: xcp_test_executor::TestModeCal = xcp_test_executor::TestModeCal::Cal; // Execute calibration tests: Cal or None
2626
const TEST_DAQ: xcp_test_executor::TestModeDaq = xcp_test_executor::TestModeDaq::DaqMultiThread; // Execute measurement tests: MultiThreadDAQ or None
27-
const TEST_TASK_COUNT: usize = 16; // Number of test tasks to create
28-
const TEST_SIGNAL_COUNT: usize = 10; // Number of signals is TEST_SIGNAL_COUNT + 5 for each task
29-
const TEST_DURATION_MS: u64 = 5000;
30-
const TEST_CYCLE_TIME_US: u32 = 1000; // Cycle time in microseconds
27+
28+
const TEST_TASK_COUNT: usize = 50; // Number of test tasks to create
29+
const TEST_SIGNAL_COUNT: usize = 32; // Number of signals is TEST_SIGNAL_COUNT + 5 for each task
30+
const TEST_DURATION_MS: u64 = 10 * 1000; // Stop after TEST_DURATION_MS milliseconds
31+
const TEST_CYCLE_TIME_US: u32 = 100; // Cycle time in microseconds
32+
const TEST_QUEUE_SIZE: u32 = 1024 * 256; // Size of the XCP server transmit queue in Bytes
3133

3234
//-----------------------------------------------------------------------------
3335
// Calibration Segment
@@ -104,6 +106,7 @@ fn task(index: usize) {
104106
let mut loop_counter: u64 = 0;
105107
let mut changes: u64 = 0;
106108
let mut counter_max: u32 = 0;
109+
let mut time: u64 = 0;
107110
let mut test0: u64 = 0;
108111
let mut test1: u64 = 0;
109112
let mut test2: u64 = 0;
@@ -114,12 +117,36 @@ fn task(index: usize) {
114117
let mut test7: u64 = 0;
115118
let mut test8: u64 = 0;
116119
let mut test9: u64 = 0;
120+
let mut test10: u64 = 0;
121+
let mut test11: u64 = 0;
122+
let mut test12: u64 = 0;
123+
let mut test13: u64 = 0;
124+
let mut test14: u64 = 0;
125+
let mut test15: u64 = 0;
126+
let mut test16: u64 = 0;
127+
let mut test17: u64 = 0;
128+
let mut test18: u64 = 0;
129+
let mut test19: u64 = 0;
130+
let mut test20: u64 = 0;
131+
let mut test21: u64 = 0;
132+
let mut test22: u64 = 0;
133+
let mut test23: u64 = 0;
134+
let mut test24: u64 = 0;
135+
let mut test25: u64 = 0;
136+
let mut test26: u64 = 0;
137+
let mut test27: u64 = 0;
138+
let mut test28: u64 = 0;
139+
let mut test29: u64 = 0;
140+
let mut test30: u64 = 0;
141+
let mut test31: u64 = 0;
117142

118143
let mut event = daq_create_event_tli!("task", 16);
119144
daq_register_tli!(counter, event);
120145
daq_register_tli!(loop_counter, event);
121-
daq_register_tli!(changes, event);
122146
daq_register_tli!(counter_max, event);
147+
// daq_register_tli!(cal_test, event); // captured
148+
// daq_register_tli!(time, event); // captured
149+
daq_register_tli!(changes, event);
123150
daq_register_tli!(test0, event);
124151
daq_register_tli!(test1, event);
125152
daq_register_tli!(test2, event);
@@ -130,25 +157,75 @@ fn task(index: usize) {
130157
daq_register_tli!(test7, event);
131158
daq_register_tli!(test8, event);
132159
daq_register_tli!(test9, event);
160+
daq_register_tli!(test10, event);
161+
daq_register_tli!(test11, event);
162+
daq_register_tli!(test12, event);
163+
daq_register_tli!(test13, event);
164+
daq_register_tli!(test14, event);
165+
daq_register_tli!(test15, event);
166+
daq_register_tli!(test16, event);
167+
daq_register_tli!(test17, event);
168+
daq_register_tli!(test18, event);
169+
daq_register_tli!(test19, event);
170+
daq_register_tli!(test20, event);
171+
daq_register_tli!(test21, event);
172+
daq_register_tli!(test22, event);
173+
daq_register_tli!(test23, event);
174+
daq_register_tli!(test24, event);
175+
daq_register_tli!(test25, event);
176+
daq_register_tli!(test26, event);
177+
daq_register_tli!(test27, event);
178+
daq_register_tli!(test28, event);
179+
daq_register_tli!(test29, event);
180+
daq_register_tli!(test30, event);
181+
daq_register_tli!(test31, event);
133182

134183
loop {
135184
let cal_seg = cal_seg.read_lock();
136185

137186
// Sleep for a calibratable amount of time
138187
thread::sleep(Duration::from_micros(cal_seg.cycle_time_us as u64));
139188

189+
time = Xcp::get().get_clock();
190+
let _ = time;
191+
140192
// Modify measurement variables on stack
141193
loop_counter += 1;
142-
test0 = loop_counter + 1;
143-
test1 = test0 + 1;
144-
test2 = test1 + 1;
145-
test3 = test2 + 1;
146-
test4 = test3 + 1;
147-
test5 = test4 + 1;
148-
test6 = test5 + 1;
149-
test7 = test6 + 1;
150-
test8 = test7 + 1;
151-
test9 = test8 + 1;
194+
195+
let offset: u64 = 0x0001_0001_0001_0001;
196+
test0 = 0x0400_0300_0200_0100;
197+
test1 = test0 + offset;
198+
test2 = test1 + offset;
199+
test3 = test2 + offset;
200+
test4 = test3 + offset;
201+
test5 = test4 + offset;
202+
test6 = test5 + offset;
203+
test7 = test6 + offset;
204+
test8 = test7 + offset;
205+
test9 = test8 + offset;
206+
test10 = test9 + offset;
207+
test11 = test10 + offset;
208+
test12 = test11 + offset;
209+
test13 = test12 + offset;
210+
test14 = test13 + offset;
211+
test15 = test14 + offset;
212+
test16 = test15 + offset;
213+
test17 = test16 + offset;
214+
test18 = test17 + offset;
215+
test19 = test18 + offset;
216+
test20 = test19 + offset;
217+
test21 = test20 + offset;
218+
test22 = test21 + offset;
219+
test23 = test22 + offset;
220+
test24 = test23 + offset;
221+
test25 = test24 + offset;
222+
test26 = test25 + offset;
223+
test27 = test26 + offset;
224+
test28 = test27 + offset;
225+
test29 = test28 + offset;
226+
test30 = test29 + offset;
227+
test31 = test30 + offset;
228+
_ = test31;
152229

153230
// Calculate a counter wrapping at cal_seg.counter_max
154231
counter_max = cal_seg.counter_max;
@@ -170,6 +247,7 @@ fn task(index: usize) {
170247

171248
// Capture variable cal_test, to test capture buffer measurement mode
172249
daq_capture_tli!(cal_test, event);
250+
daq_capture_tli!(time, event);
173251

174252
// Trigger the measurement event for this task instance
175253
event.trigger();
@@ -215,7 +293,7 @@ async fn test_multi_thread() {
215293
.set_app_name("test_multi_thread")
216294
.set_app_revision("EPK1.0.0")
217295
.set_log_level(OPTION_XCP_LOG_LEVEL)
218-
.start_server(XcpTransportLayer::Udp, [127, 0, 0, 1], 5555, 1024 * 256)
296+
.start_server(XcpTransportLayer::Udp, [127, 0, 0, 1], 5555, TEST_QUEUE_SIZE)
219297
{
220298
Err(res) => {
221299
error!("XCP initialization failed: {:?}", res);

tests/test_single_thread.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use xcp_test_executor::test_executor;
2323

2424
const TEST_CAL: xcp_test_executor::TestModeCal = xcp_test_executor::TestModeCal::Cal; // Execute calibration tests: Cal or None
2525
const TEST_DAQ: xcp_test_executor::TestModeDaq = xcp_test_executor::TestModeDaq::DaqSingleThread; // Execute measurement tests: DaqSingleThread or None
26-
const TEST_DURATION_MS: u64 = 5000;
26+
const TEST_DURATION_MS: u64 = 10000;
2727
const TEST_CYCLE_TIME_US: u32 = 1000; // Cycle time in microseconds
2828
const TEST_SIGNAL_COUNT: usize = 10; // Number of signals is TEST_SIGNAL_COUNT + 5 for each task
2929
const TEST_REINIT: bool = true; // Execute reinitialization test
@@ -85,8 +85,9 @@ fn task(cal_seg: CalSeg<CalPage1>) {
8585
let mut loop_counter: u32 = 0;
8686
let mut cal_test: u64 = 0;
8787
let mut changes: u32 = 0;
88-
let mut counter_max: u32 = cal_seg.read_lock().counter_max;
88+
let mut counter_max: u32 = 0xFFFF;
8989
let mut counter: u32 = 0;
90+
let mut time: u64 = 0;
9091
let mut test0: u64 = 0;
9192
let mut test1: u64 = 0;
9293
let mut test2: u64 = 0;
@@ -99,12 +100,13 @@ fn task(cal_seg: CalSeg<CalPage1>) {
99100
let mut test9: u64 = 0;
100101

101102
// Create a DAQ event and register local variables for measurement
102-
let mut event = daq_create_event!("task", 16);
103+
let event = daq_create_event!("task", 0);
103104

104-
daq_register!(loop_counter, event);
105-
daq_register!(changes, event);
106-
daq_register!(counter_max, event);
107-
daq_register!(counter, event);
105+
daq_register_tli!(counter, event);
106+
daq_register_tli!(loop_counter, event);
107+
daq_register_tli!(counter_max, event);
108+
daq_register_tli!(cal_test, event);
109+
daq_register_tli!(time, event);
108110
daq_register_tli!(test0, event);
109111
daq_register_tli!(test1, event);
110112
daq_register_tli!(test2, event);
@@ -117,63 +119,62 @@ fn task(cal_seg: CalSeg<CalPage1>) {
117119
daq_register_tli!(test9, event);
118120

119121
loop {
120-
// Sleep for a calibratable amount of microseconds
121-
thread::sleep(Duration::from_micros(cal_seg.read_lock().cycle_time_us as u64));
122122
loop_counter += 1;
123123

124+
time = Xcp::get().get_clock();
125+
let _ = time;
126+
124127
{
125128
let cal_seg = cal_seg.read_lock();
126-
// Test XCP text messages if counter_max has changed
127-
if counter_max != cal_seg.counter_max {
128-
xcp_println!("Task: counter_max calibrated: counter_max={} !!!", cal_seg.counter_max);
129+
130+
// Check for termination
131+
if !cal_seg.run {
132+
break;
129133
}
130134

135+
// Sleep for a calibratable amount of microseconds
136+
thread::sleep(Duration::from_micros(cal_seg.cycle_time_us as u64));
137+
131138
// Create a calibratable wrapping counter signal
132139
counter_max = cal_seg.counter_max;
133140
counter += 1;
134141
if counter > counter_max {
135142
counter = 0;
136143
}
137-
test0 = loop_counter as u64 + 1;
138-
test1 = test0 + 1;
139-
test2 = test1 + 1;
140-
test3 = test2 + 1;
141-
test4 = test3 + 1;
142-
test5 = test4 + 1;
143-
test6 = test5 + 1;
144-
test7 = test6 + 1;
145-
test8 = test7 + 1;
146-
test9 = test8 + 1;
147-
let _ = test9;
148144

149145
// Test calibration data validity
150146
if cal_test != cal_seg.cal_test {
151147
changes += 1;
152148
cal_test = cal_seg.cal_test;
153149
assert_eq!((cal_test >> 32) ^ 0x55555555, cal_test & 0xFFFFFFFF);
154150
}
155-
daq_capture!(cal_test, event);
156-
157-
// Trigger DAQ event
158-
// daq_capture!(cal_test, event);
159-
// daq_capture!(counter_max, event);
160-
// daq_capture!(counter, event);
161-
event.trigger();
162151
}
163152

164-
// Check for termination
165-
if !cal_seg.read_lock().run {
166-
break;
167-
}
153+
// Test signal checked by the XCP client
154+
let offset: u64 = 0x0001_0001_0001_0001;
155+
test0 = 0x0400_0300_0200_0100;
156+
test1 = test0 + offset;
157+
test2 = test1 + offset;
158+
test3 = test2 + offset;
159+
test4 = test3 + offset;
160+
test5 = test4 + offset;
161+
test6 = test5 + offset;
162+
test7 = test6 + offset;
163+
test8 = test7 + offset;
164+
test9 = test8 + offset;
165+
let _ = test9;
166+
167+
// Trigger DAQ event
168+
event.trigger();
168169

169170
// Check if the XCP server is still alive
170-
if loop_counter % 256 == 0 && !Xcp::get().check_server() {
171+
if !Xcp::get().check_server() {
171172
panic!("XCP server shutdown!");
172173
}
173174
}
174175

175176
debug!("Task terminated, loop counter = {}, {} changes observed", loop_counter, changes);
176-
Xcp::disconnect_client(Xcp::get());
177+
//xcp_println!("Task terminated, loop counter = {}, {} changes observed", loop_counter, changes);
177178
}
178179

179180
//-----------------------------------------------------------------------------
@@ -223,12 +224,15 @@ async fn test_single_thread() {
223224
}
224225
});
225226

226-
thread::sleep(Duration::from_micros(100000));
227+
thread::sleep(Duration::from_micros(500000));
227228
xcp.finalize_registry().unwrap(); // Write the A2L file
228229

229230
test_executor(TEST_CAL, TEST_DAQ, TEST_DURATION_MS, 1, TEST_SIGNAL_COUNT, TEST_CYCLE_TIME_US as u64).await; // Start the test executor XCP client
230231

231232
t1.join().unwrap();
233+
234+
Xcp::disconnect_client(Xcp::get());
235+
232236
xcp.stop_server();
233237

234238
// Reinitialize the XCP server a second time, to check correct shutdown behaviour

0 commit comments

Comments
 (0)