Skip to content

Commit c18470a

Browse files
authored
refactor: remove magic numbers (#64)
## Summary Decompose magic numbers into `const`'s adding relevant documentation. --------- Signed-off-by: Alan Ngo <ngoalan@microsoft.com>
1 parent b0dce6e commit c18470a

4 files changed

Lines changed: 77 additions & 19 deletions

File tree

general/echo/kmdf/driver/DriverSync/src/device.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation.
22
// License: MIT OR Apache-2.0
33

4+
use core::time::Duration;
5+
46
use wdk::{nt_success, paged_code, println};
57
use wdk_sys::{
68
call_unsafe_wdf_function_binding,
@@ -146,6 +148,24 @@ pub fn echo_device_create(mut device_init: &mut WDFDEVICE_INIT) -> NTSTATUS {
146148
///
147149
/// * `NTSTATUS` - Failures will result in the device stack being torn down.
148150
extern "C" fn echo_evt_device_self_managed_io_start(device: WDFDEVICE) -> NTSTATUS {
151+
/// 100ms relative due time for a WDF timer, in system time units.
152+
#[allow(
153+
clippy::cast_possible_truncation,
154+
reason = "100ms in 100-nanosecond units is known to fit in i64"
155+
)]
156+
const WDF_TIMER_DUE_TIME_100_MS: i64 = {
157+
// System time units are 100-nanosecond intervals.
158+
const SYSTEM_TIME_UNITS: u128 = Duration::from_millis(100).as_nanos() / 100;
159+
const {
160+
assert!(
161+
SYSTEM_TIME_UNITS <= i64::MAX as u128,
162+
"SYSTEM_TIME_UNITS should fit in i64"
163+
);
164+
};
165+
// Negative marks the value as a relative (rather than absolute) timeout.
166+
-(SYSTEM_TIME_UNITS as i64)
167+
};
168+
149169
// Restart the queue and the periodic timer. We stopped them before going
150170
// into low power state.
151171
let queue: WDFQUEUE;
@@ -162,7 +182,7 @@ extern "C" fn echo_evt_device_self_managed_io_start(device: WDFDEVICE) -> NTSTAT
162182
// into low power state.
163183
unsafe { call_unsafe_wdf_function_binding!(WdfIoQueueStart, queue) };
164184

165-
let due_time: i64 = -(100) * (10000);
185+
let due_time: i64 = WDF_TIMER_DUE_TIME_100_MS;
166186

167187
let _ = unsafe { (*queue_context).timer.start(due_time) };
168188

general/echo/kmdf/driver/DriverSync/src/driver.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,15 @@ fn echo_print_driver_version() -> NTSTATUS {
177177
call_unsafe_wdf_function_binding!(WdfDriverIsVersionAvailable, driver, &raw mut ver)
178178
} > 0
179179
{
180-
println!("Yes, framework version is 1.0");
180+
println!(
181+
"Yes, framework version is {}.{}",
182+
ver.MajorVersion, ver.MinorVersion
183+
);
181184
} else {
182-
println!("No, framework version is not 1.0");
185+
println!(
186+
"No, framework version is not {}.{}",
187+
ver.MajorVersion, ver.MinorVersion
188+
);
183189
}
184190

185191
STATUS_SUCCESS

general/echo/kmdf/driver/DriverSync/src/queue.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// License: MIT OR Apache-2.0
33

4-
use core::sync::atomic::Ordering;
4+
use core::{sync::atomic::Ordering, time::Duration};
55

66
use wdk::{nt_success, paged_code, println, wdf};
77
use wdk_sys::{
@@ -44,12 +44,6 @@ use crate::{
4444
WDF_TIMER_CONFIG_SIZE,
4545
};
4646

47-
/// Set max write length for testing
48-
const MAX_WRITE_LENGTH: usize = 1024 * 40;
49-
50-
/// Set timer period in ms
51-
const TIMER_PERIOD: u32 = 1000 * 10;
52-
5347
/// This routine will interlock increment a value only if the current value
5448
/// is greater then the floor value.
5549
///
@@ -130,6 +124,19 @@ fn echo_interlocked_increment_gtzero(target: &AtomicI32) -> i32 {
130124
/// * `NTSTATUS`
131125
#[link_section = "PAGE"]
132126
pub unsafe fn echo_queue_initialize(device: WDFDEVICE) -> NTSTATUS {
127+
#[allow(
128+
clippy::cast_possible_truncation,
129+
reason = "10 seconds in millisecond units is known to fit in u32"
130+
)]
131+
const TIMER_PERIOD_MS: u32 = {
132+
const MILLIS: u128 = Duration::from_secs(10).as_millis();
133+
const {
134+
assert!(MILLIS <= u32::MAX as u128, "10,000 should fit in u32");
135+
};
136+
137+
MILLIS as u32
138+
};
139+
133140
paged_code!();
134141

135142
let mut queue = WDF_NO_HANDLE as WDFQUEUE;
@@ -206,7 +213,7 @@ pub unsafe fn echo_queue_initialize(device: WDFDEVICE) -> NTSTATUS {
206213
let mut timer_config = WDF_TIMER_CONFIG {
207214
Size: WDF_TIMER_CONFIG_SIZE,
208215
EvtTimerFunc: Some(echo_evt_timer_func),
209-
Period: TIMER_PERIOD,
216+
Period: TIMER_PERIOD_MS,
210217
AutomaticSerialization: u8::from(true),
211218
TolerableDelay: 0,
212219
..WDF_TIMER_CONFIG::default()
@@ -518,6 +525,15 @@ extern "C" fn echo_evt_io_read(queue: WDFQUEUE, request: WDFREQUEST, mut length:
518525
///
519526
/// * `VOID`
520527
extern "C" fn echo_evt_io_write(queue: WDFQUEUE, request: WDFREQUEST, length: usize) {
528+
/// Number of bytes in one kilobyte.
529+
const BYTES_PER_KB: usize = 1024;
530+
/// Max write length, in bytes, for testing
531+
const MAX_WRITE_LENGTH: usize = 40 * BYTES_PER_KB;
532+
533+
/// Non-zero char literal (of one to four chars) for pool tag used in
534+
/// `ExAllocatePool2`
535+
const MEMORY_TAG: u32 = u32::from_be_bytes(*b"sam1");
536+
521537
let mut memory = WDF_NO_HANDLE as WDFMEMORY;
522538
let mut status: NTSTATUS;
523539
let queue_context = unsafe { queue_get_context(queue as WDFOBJECT) };
@@ -564,9 +580,8 @@ extern "C" fn echo_evt_io_write(queue: WDFQUEUE, request: WDFREQUEST, length: us
564580
(*queue_context).length = 0;
565581
}
566582

567-
// FIXME: Memory Tag
568583
(*queue_context).buffer =
569-
ExAllocatePool2(POOL_FLAG_NON_PAGED, length as SIZE_T, 's' as u32);
584+
ExAllocatePool2(POOL_FLAG_NON_PAGED, length as SIZE_T, MEMORY_TAG);
570585
if (*queue_context).buffer.is_null() {
571586
println!(
572587
"echo_evt_io_write Could not allocate {:?} byte buffer",
@@ -697,9 +712,8 @@ unsafe extern "C" fn echo_evt_timer_func(timer: WDFTIMER) {
697712
// currently racing with it), there is no need to use an interlocked
698713
// decrement to lower the cancel ownership count.
699714

700-
// 2 is the initial count we set when we initialized
701-
// CancelCompletionOwnershipCount plus the call to
702-
// EchoIncrementRequestCancelOwnershipCount()
715+
// 2 = the initial ownership count (1) plus the one increment
716+
// acquired via echo_increment_request_cancel_ownership_count.
703717
(*request_context)
704718
.cancel_completion_ownership_count
705719
.fetch_sub(2, Ordering::SeqCst);

general/echo/kmdf/exe/src/main.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ static NUM_ASYNCH_IO: usize = 100;
7272
static BUFFER_SIZE: usize = 40 * 1024;
7373

7474
fn main() -> Result<(), Box<dyn Error>> {
75+
/// Transfer length, in bytes, for the first synchronous write/read test.
76+
const SYNC_TEST_SMALL_LENGTH: u32 = 512;
77+
/// Transfer length, in bytes, for the second synchronous write/read test.
78+
const SYNC_TEST_LARGE_LENGTH: u32 = 30 * 1024;
79+
7580
let argument_vector: Vec<String> = env::args().collect();
7681
let argument_count = argument_vector.len();
7782

@@ -155,9 +160,9 @@ Exit the app anytime by pressing Ctrl-C
155160

156161
h.join().unwrap().unwrap();
157162
} else {
158-
perform_write_read_test(h_device, 512)?;
163+
perform_write_read_test(h_device, SYNC_TEST_SMALL_LENGTH)?;
159164

160-
perform_write_read_test(h_device, 30 * 1024)?;
165+
perform_write_read_test(h_device, SYNC_TEST_LARGE_LENGTH)?;
161166
}
162167

163168
Ok(())
@@ -292,6 +297,14 @@ fn async_io(thread_parameter: u32) -> Result<(), Box<dyn Error + Send + Sync>> {
292297
// function warning
293298
#[allow(clippy::too_many_lines)]
294299
fn async_io_work(io_type: u32) -> Result<(), Box<dyn Error>> {
300+
/// Completion key associated with the device handle on the I/O completion
301+
/// port.
302+
const COMPLETION_PORT_KEY: usize = 1;
303+
/// Number of concurrent threads allowed to run for the I/O completion port.
304+
/// Zero lets the system allow as many concurrent threads as there are
305+
/// processors.
306+
const COMPLETION_PORT_CONCURRENT_THREADS: u32 = 0;
307+
295308
let globals = GLOBAL_DATA.read()?;
296309

297310
let h_device: HANDLE;
@@ -334,7 +347,12 @@ fn async_io_work(io_type: u32) -> Result<(), Box<dyn Error>> {
334347
// Call Win32 API FFI CreateIoCompletionPort to get handle for completing async
335348
// requests
336349
unsafe {
337-
h_completion_port = CreateIoCompletionPort(h_device, std::ptr::null_mut(), 1, 0);
350+
h_completion_port = CreateIoCompletionPort(
351+
h_device,
352+
std::ptr::null_mut(),
353+
COMPLETION_PORT_KEY,
354+
COMPLETION_PORT_CONCURRENT_THREADS,
355+
);
338356
}
339357

340358
if h_completion_port.is_null() {

0 commit comments

Comments
 (0)