lib/thread: Allow nesting thread_cooperate and thread_prevent_coop
This change allows nesting critical sections, and frees the caller from having to keep track of whether the thread has coop enabled. BUG=b:179699789 TEST=Boot guybrush with SPI DMA Suggested-by: Julius Werner <jwerner@chromium.org> Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: I325ab6181b17c5c084ca1e2c181b4df235020557 Reviewed-on: https://review.coreboot.org/c/coreboot/+/56350 Reviewed-by: Karthik Ramasubramanian <kramasub@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
b95369c914
commit
be60a0ddb0
|
@ -43,8 +43,13 @@ int thread_yield_microseconds(unsigned int microsecs);
|
|||
|
||||
/* Allow and prevent thread cooperation on current running thread. By default
|
||||
* all threads are marked to be cooperative. That means a thread can yield
|
||||
* to another thread at a pre-determined switch point. Current there is
|
||||
* only a single place where switching may occur: a call to udelay(). */
|
||||
* to another thread at a pre-determined switch point. i.e., udelay,
|
||||
* thread_yield, or thread_yield_microseconds.
|
||||
*
|
||||
* These methods should be used to guard critical sections so a dead lock does
|
||||
* not occur. The critical sections can be nested. Just make sure the methods
|
||||
* are used in pairs.
|
||||
*/
|
||||
void thread_cooperate(void);
|
||||
void thread_prevent_coop(void);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ static inline struct cpu_info *thread_cpu_info(const struct thread *t)
|
|||
|
||||
static inline int thread_can_yield(const struct thread *t)
|
||||
{
|
||||
return (t != NULL && t->can_yield);
|
||||
return (t != NULL && t->can_yield > 0);
|
||||
}
|
||||
|
||||
/* Assumes current CPU info can switch. */
|
||||
|
@ -358,8 +358,12 @@ void thread_cooperate(void)
|
|||
|
||||
current = current_thread();
|
||||
|
||||
if (current != NULL)
|
||||
current->can_yield = 1;
|
||||
if (current == NULL)
|
||||
return;
|
||||
|
||||
assert(current->can_yield <= 0);
|
||||
|
||||
current->can_yield++;
|
||||
}
|
||||
|
||||
void thread_prevent_coop(void)
|
||||
|
@ -368,6 +372,8 @@ void thread_prevent_coop(void)
|
|||
|
||||
current = current_thread();
|
||||
|
||||
if (current != NULL)
|
||||
current->can_yield = 0;
|
||||
if (current == NULL)
|
||||
return;
|
||||
|
||||
current->can_yield--;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue