OSCrit - Critical Section Example
Overview
This example demonstrates how to implement critical sections in a real-time operating system (RTOS) environment using two different approaches: traditional C-style function calls and modern C++ object-oriented design.
Purpose
Critical sections are essential for protecting shared resources in multi-tasking environments. They ensure that only one task can access a shared resource at a time, preventing race conditions and data corruption that could occur when multiple tasks attempt to modify the same data simultaneously.
Application Description
The OSCrit example (main.cpp) showcases both methods of implementing critical sections:
Method 1: Traditional C-Style Critical Sections
Uses explicit function calls:
OSCritEnter() - Enters the critical section
OSCritLeave() - Exits the critical section
OS_CRIT cs;
cs.Enter();
GlobalVariable = 1;
cs.Leave();
Method 2: C++ Object-Oriented Critical Sections
Uses RAII (Resource Acquisition Is Initialization) pattern:
- Constructor automatically calls
OSCritEnter()
- Destructor automatically calls
OSCritLeave() when object goes out of scope
OS_CRIT cs2;
{
OSCriticalSectionObj UserMainCriticalSection(cs2);
GlobalVariable = 2;
}
Key Features
- Network Initialization: Waits for DHCP address assignment (5-second timeout)
- System Diagnostics: Enables system diagnostic features for debugging
- Shared Resource Protection: Demonstrates protection of a global variable
- Timeout Handling: Shows how to configure timeout values for critical section acquisition
- Automatic Resource Management: C++ approach eliminates the risk of mismatched enter/leave calls
Advantages of Each Approach
Traditional C-Style
- Explicit Control: Clear visibility of when critical sections are entered and exited
- Timeout Configuration: Allows custom timeout values for critical section acquisition
C++ Object-Oriented
- Automatic Management: No risk of forgetting to call
OSCritLeave()
- Exception Safety: Guaranteed cleanup even if exceptions occur
- Scope-Based: Critical section is automatically released when leaving the scope
Technical Details
- Application Name: "OSCrit Example"
- Shared Resource:
GlobalVariable (integer)
- Network Timeout: 5 seconds for DHCP acquisition
- Main Loop: 5-second delay iterations
- Timeout Behavior: Value of 0 means wait forever for critical section access
Use Cases
While this example uses a simple global variable for demonstration, critical sections are typically used for:
- Linked Lists: Protecting list modifications during insertions/deletions
- Shared Buffers: Ensuring atomic access to circular buffers or queues
- Hardware Resources: Coordinating access to peripherals or memory-mapped registers
- Data Structures: Protecting complex objects that require multiple operations to remain consistent
Best Practices Demonstrated
- Proper Initialization: System and network setup before critical operations
- Resource Protection: Using critical sections for shared data access
- Modern C++ Techniques: Leveraging RAII for automatic resource management
- Comparison Approach: Showing both traditional and modern implementation methods
Implementation Notes
- The second parameter in critical section calls represents timeout in system ticks
- A timeout value of 0 means the task will wait indefinitely
- The C++ approach always uses infinite timeout (wait forever)
- System diagnostics should be disabled in production code for optimal performance