pangzhen1xiaomi opened a new pull request, #18072:
URL: https://github.com/apache/nuttx/pull/18072
Allows configuring a static stack for hpwork/lpwork.
## Summary
What This Patch Does
This patch extends NuttX work queue stack allocation to support configurable
custom memory sections. Instead of relying on dynamic memory allocation or the
default data section, administrators can now:
Specify a custom memory section for high-priority worker thread stacks
Specify a custom memory section for low-priority worker thread stacks
Allocate these stacks as static arrays placed in the designated sections
Enable more sophisticated memory layout and optimization strategies
Key Features
Static Stack Allocation: Stacks are now declared as static arrays instead of
dynamically allocated
Custom Section Support: Allows placement in special memory regions (e.g.,
SRAM, CCM, custom areas)
Dual Configuration: Separate configuration options for high-priority and
low-priority work queues
Backward Compatible: Empty default values maintain existing behavior when
not configured
Technical Changes
Configuration Options: 2 new Kconfig parameters
Build System: Updated CMakeLists.txt and Make.defs for macro definitions
Runtime: Modified stack initialization logic in kwork_thread.c
Files Changed: 4 files
Lines Added: 66 insertions, 4 deletions
## Impact
Positive Impact
Memory Management Flexibility: Enables placement of worker stacks in
optimized memory regions
Performance: Placing stacks in fast memory (CCM/SRAM) can improve performance
Advanced Configurations: Supports real-time systems requiring precise memory
layout control
Embedded Systems: Beneficial for resource-constrained systems with
heterogeneous memory
Deterministic Behavior: Static allocation provides predictable memory usage
patterns
Debuggability: Known memory locations facilitate debugging and profiling
Use Cases
Real-Time Systems: Place stacks in deterministic memory regions for timing
guarantees
Memory-Constrained Devices: Control which memory type holds worker thread
stacks
Performance Optimization: Use faster memory (CCM/SRAM) for
frequently-accessed data
NUMA Systems: Optimize memory locality for multi-socket systems
Secure Systems: Isolate worker stacks in protected memory regions
Testing: Test different memory configurations without binary recompilation
Risk Assessment
Low Risk:
Fully backward compatible (defaults to NULL)
Changes are purely additive
Conditional compilation ensures no impact when feature is unused
Stack initialization logic properly handles NULL case
Affected Components
[Kconfig](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
- Configuration options
[CMakeLists.txt](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
- CMake build system
[Make.defs](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
- Traditional build system
[kwork_thread.c](vscode-file://vscode-app/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
- Stack initialization logic
## Testing
Test Case 1: Configuration Defaults
/**
* Test: Verify default configuration behavior
* Purpose: Ensure system works when stack section not configured
* Expected: SCHED_HPWORKSTACKSECTION and SCHED_LPWORKSTACKSECTION undefined
*/
static void test_default_configuration(void)
{
#ifndef SCHED_HPWORKSTACKSECTION
printf("Test PASS: HPWORK stack section undefined (default)\n");
#else
printf("Test FAIL: HPWORK stack section should be undefined by default\n");
#endif
#ifndef SCHED_LPWORKSTACKSECTION
printf("Test PASS: LPWORK stack section undefined (default)\n");
#else
printf("Test FAIL: LPWORK stack section should be undefined by default\n");
#endif
}
Test Case 2: Static Stack Allocation
/**
* Test: Verify static stack arrays are properly allocated
* Purpose: Ensure stacks are allocated as static arrays
* Expected: g_hp_work_stack and g_lp_work_stack exist and have correct size
*/
static void test_static_stack_allocation(void)
{
extern uint8_t g_hp_work_stack[];
extern uint8_t g_lp_work_stack[];
size_t hp_stack_size = CONFIG_SCHED_HPNTHREADS *
CONFIG_SCHED_HPWORKSTACKSIZE;
size_t lp_stack_size = CONFIG_SCHED_LPNTHREADS *
CONFIG_SCHED_LPWORKSTACKSIZE;
// Verify stack symbols exist
assert(g_hp_work_stack != NULL);
assert(g_lp_work_stack != NULL);
// Verify stacks have correct alignment
assert(((uintptr_t)g_hp_work_stack % 4) == 0);
assert(((uintptr_t)g_lp_work_stack % 4) == 0);
printf("Test PASS: Static stacks allocated correctly\n");
printf(" HP stack: %p, size: %zu bytes\n", g_hp_work_stack,
hp_stack_size);
printf(" LP stack: %p, size: %zu bytes\n", g_lp_work_stack,
lp_stack_size);
}
Test Case 3: Custom Section Configuration
/**
* Test: Verify high-priority worker thread creation
* Purpose: Ensure hpwork threads initialize correctly with static stacks
* Expected: Worker threads start and remain operational
*/
static void test_hpwork_thread_creation(void)
{
int ret;
// Initialize high-priority work queue
ret = work_start_highpri();
assert(ret == OK);
// Verify worker threads are running
// ... additional worker thread checks ...
// Submit test work item
struct work_s work;
ret = work_queue(HPWORK, &work, test_work_handler, NULL, 0);
assert(ret == OK);
// Wait for work completion
sleep(1);
printf("Test PASS: High-priority worker threads created and
operational\n");
}
Test Case 4: High-Priority Worker Thread Creation
/**
* Test: Verify high-priority worker thread creation
* Purpose: Ensure hpwork threads initialize correctly with static stacks
* Expected: Worker threads start and remain operational
*/
static void test_hpwork_thread_creation(void)
{
int ret;
// Initialize high-priority work queue
ret = work_start_highpri();
assert(ret == OK);
// Verify worker threads are running
// ... additional worker thread checks ...
// Submit test work item
struct work_s work;
ret = work_queue(HPWORK, &work, test_work_handler, NULL, 0);
assert(ret == OK);
// Wait for work completion
sleep(1);
printf("Test PASS: High-priority worker threads created and
operational\n");
}
Test Case 5: Low-Priority Worker Thread Creation
/**
* Test: Verify low-priority worker thread creation
* Purpose: Ensure lpwork threads initialize correctly with static stacks
* Expected: Worker threads start and remain operational
*/
static void test_lpwork_thread_creation(void)
{
int ret;
// Initialize low-priority work queue
ret = work_start_lowpri();
assert(ret == OK);
// Verify worker threads are running
// ... additional worker thread checks ...
// Submit test work item
struct work_s work;
ret = work_queue(LPWORK, &work, test_work_handler, NULL, 0);
assert(ret == OK);
// Wait for work completion
sleep(1);
printf("Test PASS: Low-priority worker threads created and operational\n");
}
Test Case 6: Stack Offset Calculation
/**
* Test: Verify correct stack address calculation for multiple threads
* Purpose: Ensure each worker thread gets its own stack offset
* Expected: Each thread has unique stack address within the allocation
*/
static void test_stack_offset_calculation(void)
{
extern uint8_t g_hp_work_stack[];
FAR uint8_t *stack_addr;
for (int i = 0; i < CONFIG_SCHED_HPNTHREADS; i++)
{
stack_addr = g_hp_work_stack + (i * CONFIG_SCHED_HPWORKSTACKSIZE);
// Verify each stack is properly offset
assert(((uintptr_t)stack_addr % 4) == 0); // Proper alignment
// Verify no overlap
if (i > 0)
{
FAR uint8_t *prev_stack = g_hp_work_stack +
((i - 1) * CONFIG_SCHED_HPWORKSTACKSIZE);
assert(stack_addr > prev_stack);
}
}
printf("Test PASS: Stack offset calculation correct for all threads\n");
}
Test Case 7: Work Queue Operations
/**
* Test: Verify work queue operations work correctly with static stacks
* Purpose: Ensure work items are processed correctly by worker threads
* Expected: Work items completed successfully
*/
static void test_work_queue_operations(void)
{
struct work_s work;
volatile int test_flag = 0;
// Test work callback
void test_callback(FAR void *arg)
{
test_flag = 1;
}
// Queue work to high-priority queue
int ret = work_queue(HPWORK, &work, test_callback, NULL, 0);
assert(ret == OK);
// Wait for completion
int timeout = 100;
while (!test_flag && timeout-- > 0)
{
usleep(10000); // 10ms
}
assert(test_flag == 1);
printf("Test PASS: Work queue operations successful\n");
}
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]