class
#include <pros/rtos.hpp>
RecursiveMutex
Constructors, destructors, conversion operators
- RecursiveMutex() constexpr
- RecursiveMutex(const RecursiveMutex&) deleted
- RecursiveMutex(RecursiveMutex&&) deleted
- ~RecursiveMutex()
Public functions
- RecursiveMutex& operator=(const RecursiveMutex&) deleted
- RecursiveMutex& operator=(RecursiveMutex&&) deleted
- bool take()
- Takes and locks a mutex indefinetly.
- bool take(std::uint32_t timeout)
- Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.
- bool give()
- Unlocks a mutex.
- void lock()
- Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds.
- void unlock()
- Unlocks a mutex.
- bool try_lock()
- Try to lock a mutex.
-
template<typename Rep, typename Period>bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
- Takes and locks a mutex, waiting for a specified duration.
-
template<typename Duration>bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time)
- Takes and locks a mutex, waiting until a specified time.
Function documentation
bool pros:: rtos:: RecursiveMutex:: take()
Takes and locks a mutex indefinetly.
Returns | True if the mutex was successfully taken, false otherwise. If false is returned, then errno is set with a hint about why the the mutex couldn't be taken |
---|
See https:/
Example
// Global variables for the robot's odometry, which the rest of the robot's // subsystems will utilize double odom_x = 0.0; double odom_y = 0.0; double odom_heading = 0.0; // This mutex protects the odometry data. Whenever we read or write to the // odometry data, we should make copies into the local variables, and read // all 3 values at once to avoid errors. pros::RecursiveMutex odom_mutex; void odom_task(void* param) { while(true) { // First we fetch the odom coordinates from the previous iteration of the // odometry task. These are put into local variables so that we can // keep the size of the critical section as small as possible. This lets // other tasks that need to use the odometry data run until we need to // update it again. odom_mutex.take(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.give(); double x_new = 0.0; double y_new = 0.0; double heading_new = 0.0; // --- Calculate new pose for the robot here --- // Now that we have the new pose, we can update the global variables odom_mutex.take(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.give(); delay(10); } } void chassis_task(void* param) { while(true) { // Here we copy the current odom values into local variables so that // we can use them without worrying about the odometry task changing say, // the y value right after we've read the x. This ensures our values are // sound. odom_mutex.take(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.give(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::RecursiveMutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
bool pros:: rtos:: RecursiveMutex:: take(std::uint32_t timeout)
Takes and locks a mutex, waiting for up to a certain number of milliseconds before timing out.
Parameters | |
---|---|
timeout | Time to wait before the mutex becomes available. A timeout of 0 can be used to poll the mutex. TIMEOUT_MAX can be used to block indefinitely. |
Returns | True if the mutex was successfully taken, false otherwise. If false is returned, then errno is set with a hint about why the the mutex couldn't be taken. |
See https:/
Example
// Global variables for the robot's odometry, which the rest of the robot's // subsystems will utilize double odom_x = 0.0; double odom_y = 0.0; double odom_heading = 0.0; // This mutex protects the odometry data. Whenever we read or write to the // odometry data, we should make copies into the local variables, and read // all 3 values at once to avoid errors. pros::RecursiveMutex odom_mutex; void odom_task(void* param) { while(true) { // First we fetch the odom coordinates from the previous iteration of the // odometry task. These are put into local variables so that we can // keep the size of the critical section as small as possible. This lets // other tasks that need to use the odometry data run until we need to // update it again. odom_mutex.take(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.give(); double x_new = 0.0; double y_new = 0.0; double heading_new = 0.0; // --- Calculate new pose for the robot here --- // Now that we have the new pose, we can update the global variables odom_mutex.take(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.give(); delay(10); } } void chassis_task(void* param) { while(true) { // Here we copy the current odom values into local variables so that // we can use them without worrying about the odometry task changing say, // the y value right after we've read the x. This ensures our values are // sound. odom_mutex.take(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.give(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::RecursiveMutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
bool pros:: rtos:: RecursiveMutex:: give()
Unlocks a mutex.
Returns | True if the mutex was successfully returned, false otherwise. If false is returned, then errno is set with a hint about why the mutex couldn't be returned. |
---|
See https:/
Example
// Global variables for the robot's odometry, which the rest of the robot's // subsystems will utilize double odom_x = 0.0; double odom_y = 0.0; double odom_heading = 0.0; // This mutex protects the odometry data. Whenever we read or write to the // odometry data, we should make copies into the local variables, and read // all 3 values at once to avoid errors. pros::RecursiveMutex odom_mutex; void odom_task(void* param) { while(true) { // First we fetch the odom coordinates from the previous iteration of the // odometry task. These are put into local variables so that we can // keep the size of the critical section as small as possible. This lets // other tasks that need to use the odometry data run until we need to // update it again. odom_mutex.take(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.give(); double x_new = 0.0; double y_new = 0.0; double heading_new = 0.0; // --- Calculate new pose for the robot here --- // Now that we have the new pose, we can update the global variables odom_mutex.take(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.give(); delay(10); } } void chassis_task(void* param) { while(true) { // Here we copy the current odom values into local variables so that // we can use them without worrying about the odometry task changing say, // the y value right after we've read the x. This ensures our values are // sound. odom_mutex.take(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.give(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::RecursiveMutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
void pros:: rtos:: RecursiveMutex:: lock()
Takes and locks a mutex, waiting for up to TIMEOUT_MAX milliseconds.
Exceptions | |
---|---|
std::system_error | Mutex could not be locked within TIMEOUT_MAX milliseconds. see errno for details. |
Effectively equivalent to calling pros::RecursiveMutex::take with TIMEOUT_MAX as the parameter.
Conforms to named requirment BasicLockable
Example
// Global variables for the robot's odometry, which the rest of the robot's // subsystems will utilize double odom_x = 0.0; double odom_y = 0.0; double odom_heading = 0.0; // This mutex protects the odometry data. Whenever we read or write to the // odometry data, we should make copies into the local variables, and read // all 3 values at once to avoid errors. pros::RecursiveMutex odom_mutex; void odom_task(void* param) { while(true) { // First we fetch the odom coordinates from the previous iteration of the // odometry task. These are put into local variables so that we can // keep the size of the critical section as small as possible. This lets // other tasks that need to use the odometry data run until we need to // update it again. odom_mutex.lock(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.unlock(); double x_new = 0.0; double y_new = 0.0; double heading_new = 0.0; // --- Calculate new pose for the robot here --- // Now that we have the new pose, we can update the global variables odom_mutex.lock(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.unlock(); delay(10); } } void chassis_task(void* param) { while(true) { // Here we copy the current odom values into local variables so that // we can use them without worrying about the odometry task changing say, // the y value right after we've read the x. This ensures our values are // sound. odom_mutex.lock(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.unlock(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::RecursiveMutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
void pros:: rtos:: RecursiveMutex:: unlock()
Unlocks a mutex.
Equivalent to calling pros::RecursiveMutex::give.
Conforms to named requirement BasicLockable
Example
// Global variables for the robot's odometry, which the rest of the robot's // subsystems will utilize double odom_x = 0.0; double odom_y = 0.0; double odom_heading = 0.0; // This mutex protects the odometry data. Whenever we read or write to the // odometry data, we should make copies into the local variables, and read // all 3 values at once to avoid errors. pros::RecursiveMutex odom_mutex; void odom_task(void* param) { while(true) { // First we fetch the odom coordinates from the previous iteration of the // odometry task. These are put into local variables so that we can // keep the size of the critical section as small as possible. This lets // other tasks that need to use the odometry data run until we need to // update it again. odom_mutex.lock(); double x_old = odom_x; double y_old = odom_y; double heading_old = odom_heading; odom_mutex.unlock(); double x_new = 0.0; double y_new = 0.0; double heading_new = 0.0; // --- Calculate new pose for the robot here --- // Now that we have the new pose, we can update the global variables odom_mutex.lock(); odom_x = x_new; odom_y = y_new; odom_heading = heading_new; odom_mutex.unlock(); delay(10); } } void chassis_task(void* param) { while(true) { // Here we copy the current odom values into local variables so that // we can use them without worrying about the odometry task changing say, // the y value right after we've read the x. This ensures our values are // sound. odom_mutex.lock(); double current_x = odom_x; double current_y = odom_y; double current_heading = odom_heading; odom_mutex.unlock(); // ---- Move the robot using the current locations goes here ---- delay(10); } } void initialize() { odom_mutex = pros::RecursiveMutex(); pros::Task odom_task(odom_task, "Odometry Task"); pros::Task chassis_task(odom_task, "Chassis Control Task"); }
.
bool pros:: rtos:: RecursiveMutex:: try_lock()
Try to lock a mutex.
Returns | True when lock was acquired succesfully, or false otherwise. |
---|
Returns immediately if unsucessful.
Conforms to named requirement Lockable
pros::
void my_task_fn(void* param) { while (true) { if(mutex.try_lock()) { printf("Mutex aquired successfully!\n"); // Do stuff that requires the protected resource here } else { printf("Mutex not aquired!\n"); } } }
template<typename Rep, typename Period>
bool pros:: rtos:: RecursiveMutex:: try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
Takes and locks a mutex, waiting for a specified duration.
Parameters | |
---|---|
rel_time | Time to wait before the mutex becomes available. |
Returns | True if the lock was acquired succesfully, otherwise false. |
Equivalent to calling pros::RecursiveMutex::take with a duration specified in milliseconds.
Conforms to named requirement TimedLockable
Example
void my_task_fn(void* param) { while (true) { if(mutex.try_lock_for(std::chrono::milliseconds(100))) { printf("Mutex aquired successfully!\n"); // Do stuff that requires the protected resource here } else { printf("Mutex not aquired after 100 milliseconds!\n"); } } }
template<typename Duration>
bool pros:: rtos:: RecursiveMutex:: try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time)
Takes and locks a mutex, waiting until a specified time.
Parameters | |
---|---|
abs_time | Time point until which to wait for the mutex. |
Returns | True if the lock was acquired succesfully, otherwise false. |
Conforms to named requirement TimedLockable
Example
void my_task_fn(void* param) { while (true) { // Get the current time point auto now = std::chrono::system_clock::now(); // Calculate the time point 100 milliseconds from now auto abs_time = now + std::chrono::milliseconds(100); if(mutex.try_lock_until(abs_time)) { printf("Mutex aquired successfully!\n"); // Do stuff that requires the protected resource here } else { printf("Mutex not aquired after 100 milliseconds!\n"); } } }