Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TRACKING] xtimer/xtimer.c: xtimer_mutex_lock_timeout fix and improvements #11660

Conversation

JulianHolzwarth
Copy link
Contributor

@JulianHolzwarth JulianHolzwarth commented Jun 7, 2019

This pr tracks the fix for xtimer/xtimer.c: xtimer_mutex_lock_timeout
This pr includes two throwaway test commits.

Contribution description

This pr fixes Bugs in xtimer.c: xtimer_mutex_lock_timeout() and improves it. It addresses concurrency issues. The timer can trigger at a different time than expected.
Before there were problems when the timer spins. This happens when the timeout is less than XTIMER_BACKOFF.

This pr also creates a new static function called _mutex_remove_thread_from_waiting_queue. The function removes a thread from a mutex waiting queue, when the thread waiting for the mutex. This was already used inside of the _mutex_timeout function. It is needed for the xtimer_mutex_lock_timeout function.
This function should go into core/mutex in the future because it modifies queue of the mutex_t struct. (in mutex_t struct comment: @brief Mutex structure. Must never be modified by the user. and in comment of queue @brief The process waiting queue of the mutex. **Must never be changed by the user.**)

This pr also fixes core/mutex.c:_mutex_lock() there was a problem when it gets interrupted before disabling interrupt. This is fixed by giving it a pointer to blocking.

This pr also has tests and throwaway commits to show the bug and fix.

The struct for the xtimer_mutex_lock_timeout function called mutex_thread_t was changed to fix the function and name changes for better understanding.

This pull request is split into smaller parts:

Testing procedure

BOARD=native make -C tests/xtimer_mutex_lock timeout/ flash test
it outputs:

...
> mutex_timeout_long_unlocked
mutex_timeout_long_unlocked
starting test: xtimer mutex lock timeout
OK

> mutex_timeout_long_locked
mutex_timeout_long_locked
starting test: xtimer mutex lock timeout
OK

> mutex_timeout_long_locked_low
mutex_timeout_long_locked_low
starting test: xtimer mutex lock timeout with thread
threads = 2
THREAD low prio: start
MAIN THREAD: calling xtimer_mutex_lock_timeout
OK
threads = 3
MAIN THREAD: waiting for created thread to end
THREAD low prio: exiting low
threads = 2

> mutex_timeout_short_locked
mutex_timeout_short_locked
starting test: xtimer mutex lock timeout with short timeout and locked mutex
OK

> mutex_timeout_short_unlocked
mutex_timeout_short_unlocked
starting test: xtimer mutex lock timeout with short timeout and unlocked mutex
OK

>

Without the fixes this would fail.

The remove me commits show other bugs.
Go to the commit before "REMOVE ME" commit gets reverted.
Test will work.

Now go to the "REMOVE ME" commit.
Test will fail.

To test the bug in mutex.c:_mutex_lock revert to the second "REMOVE ME" commit with the commit message

REMOVE ME

test commit to show bug in _mutex_lock
when interupted before irq_disable

Issues/PRs references

#11679: first tests
#11807: sys/xtimer/xtimer.c: _mutex_timeout() clean ups
#11992: sys/xtimer/xtimer.c: _mutex_timeout() bug fix
#12008: tests/xtimer_mutex_lock_timeout: New test
#13185: xtimer/xtimer.c:_mutex_timeout() improved
#13199: xtimer/xtimer.c: xtimer_mutex_lock_timeout fix with short timeout

needed for:
- #11977: xtimer/xtimer.c: xtimer_rmutex_lock_timeout
- #11485: [TRACKING] FreeRTOS Adaption Layer

@jcarrano jcarrano requested a review from cladmi June 7, 2019 11:46
@jcarrano jcarrano added Area: timers Area: timer subsystems Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: tracking The issue tracks and organizes the sub-tasks of a larger effort labels Jun 7, 2019
@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from 3c65bc6 to b9b3cd4 Compare June 26, 2019 16:03
@JulianHolzwarth
Copy link
Contributor Author

rebase because #11679 got merged

@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from b9b3cd4 to a1c5030 Compare June 26, 2019 17:24
}
sched_set_status(thread, STATUS_PENDING);
irq_restore(irqstate);
thread_yield_higher();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it is sched_switch that may need to be used here instead to be working everywhere.
But from the implementation, thread_yield_higher in cpu/atmega_common/thread_arch.c, does the check for is_in_irq

I will do a dedicated test for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation in the CPU is wrong, this code is correct #11759 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it to sched_switch for now until #11759 is solved/discussed/closed.

Copy link
Contributor Author

@JulianHolzwarth JulianHolzwarth Jul 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in: sys/xtimer/xtimer.c: _mutex_timeout() clean ups #11807

@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from f00b6df to 25ffbc4 Compare July 10, 2019 15:55
@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from f5b931d to ec2933a Compare July 30, 2019 16:16
@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch 2 times, most recently from 17c6311 to 8ffafdb Compare August 14, 2019 13:58
@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from 8ffafdb to cbe6a24 Compare August 14, 2019 14:53
@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from cbe6a24 to 8853126 Compare January 24, 2020 15:37
@JulianHolzwarth
Copy link
Contributor Author

rebased on master

@JulianHolzwarth
Copy link
Contributor Author

JulianHolzwarth commented Mar 6, 2020

The _mutex_remove_thread_from_waiting_queue function will be moved into mutex.c

@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from 8853126 to 9fc60bd Compare March 6, 2020 20:42
@JulianHolzwarth
Copy link
Contributor Author

rebased on master

Copy link
Contributor

@MichelRottleuthner MichelRottleuthner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested and was able to reproduce the bug and verify the fix.
Some of the added debug output lines are longer than the absolute maximum of 120 chars and some are outdated (changed variable names).
While the debug messages probably were helpful for working on the test I don't think we should keep (all of) them.
Please squash so we can put Murdock to work.

@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from 9fc60bd to 05c88f4 Compare March 26, 2020 15:40
@JulianHolzwarth
Copy link
Contributor Author

@MichelRottleuthner done. Removed debug msg.

@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from 05c88f4 to 40bf85e Compare March 26, 2020 15:43
Copy link
Contributor

@MichelRottleuthner MichelRottleuthner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't see that before: the commit message is outdated (and contains typos).
Also see below.

@@ -100,7 +101,8 @@ int _mutex_lock(mutex_t *mutex, int blocking);
*/
static inline int mutex_trylock(mutex_t *mutex)
{
return _mutex_lock(mutex, 0);
uint8_t blocking = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be declared as volatile explicitly.

@@ -110,7 +112,8 @@ static inline int mutex_trylock(mutex_t *mutex)
*/
static inline void mutex_lock(mutex_t *mutex)
{
_mutex_lock(mutex, 1);
uint8_t blocking = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@@ -247,6 +247,7 @@ static void _mutex_timeout(void *arg)
unsigned int irqstate = irq_disable();

mutex_thread_t *mt = (mutex_thread_t *)arg;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated

@JulianHolzwarth
Copy link
Contributor Author

JulianHolzwarth commented Mar 26, 2020

@MichelRottleuthner can I just rebase after the changes? (do you want fixup commits?)

_mutex_lock uses a volatile int pointer for the parameter blocking instead of an int.
@MichelRottleuthner
Copy link
Contributor

sure

@JulianHolzwarth JulianHolzwarth force-pushed the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch from 40bf85e to dd6e51b Compare March 26, 2020 17:03
@JulianHolzwarth
Copy link
Contributor Author

done

@MichelRottleuthner MichelRottleuthner added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines labels Mar 26, 2020
Copy link
Contributor

@MichelRottleuthner MichelRottleuthner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes make sense and were tested -> ACK

@MichelRottleuthner MichelRottleuthner merged commit 80ef241 into RIOT-OS:master Mar 27, 2020
@leandrolanzieri leandrolanzieri added this to the Release 2020.04 milestone Apr 3, 2020
chrysn added a commit to RIOT-OS/rust-riot-sys that referenced this pull request May 31, 2022
@JulianHolzwarth JulianHolzwarth deleted the pr/xtimer_mutex_lock_timeout/_mutex_remove_thread_from_waiting_queue branch May 8, 2024 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: timers Area: timer subsystems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: tracking The issue tracks and organizes the sub-tasks of a larger effort
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants