Page 1 of 1

Mutex with “pause” assembly instruction

Posted: Wed Mar 01, 2023 9:40 pm
by FunnyGuy9796
I am implementing a lock function for my memory allocator but was curious what exactly the lock function should do. I am aware that it is intended to prevent other changes to memory while the current change is in progress. However, any implementation of a mutex simply tells the CPU to pause and I was wondering if this would be correct. To my knowledge, pausing the CPU would prevent even the current task with memory from executing and nothing would be accomplished. Sorry if this is a stupid question, just thought I’d ask.

Example Code:

Code: Select all

typedef volatile int mutex_t;
 
void acquire_mutex(mutex_t* mutex)
{
	while(!__sync_bool_compare_and_swap(mutex, 0, 1))
	{
		asm("pause");
	}
}
 
void release_mutex(mutex_t* mutex)
{
	*mutex = 0;
}

Re: Mutex with “pause” assembly instruction

Posted: Wed Mar 01, 2023 10:06 pm
by Octocontrabass
FunnyGuy9796 wrote:However, any implementation of a mutex simply tells the CPU to pause and I was wondering if this would be correct.
It tells the CPU to pause while another CPU holds the lock. This is the correct behavior when the lock will be held by another CPU for only a short period of time, since there's nothing useful the current CPU can do while it waits for the other CPU to release the lock.

In systems where there is only one CPU, or systems where the lock is likely to be held for a long time, you might instead choose to yield the current time slice while waiting for the lock to be released.
FunnyGuy9796 wrote:Example Code:
That example code is old and bad. You should use stdatomic.h (in C) or std::atomic (in C++) to implement your mutex. In fact, how about I fix that on the wiki...

Re: Mutex with “pause” assembly instruction

Posted: Thu Mar 02, 2023 12:40 am
by sounds
PAUSE on intel processors, as Octocontrabass says, delays execution of the next instruction, and may give the processor a hint how to predict the next branch instruction. It's even backward-compatible with old processors, which will see it as a NOP.

HLT on intel processors prevents execution, which might have been what you were thinking of. HLT is sometimes used to place the CPU in a halted state until the next interrupt wakes the CPU up.

Re: Mutex with “pause” assembly instruction

Posted: Thu Mar 02, 2023 1:18 am
by rdos
The example code locks more like a spinlock than a mutex. A mutex should be blocked (by the scheduler) when the mutex is busy, and when the mutex is released, any blocked thread should be resumed. A spinlock can be used in the implementation of the mutex, or in the scheduler, to ensure multicore operation. A spinlock should generally also disable interrupts to avoid excessive spinning if an interrupt happens when the critical code is executed.

An alternative to using spinlocks is to write lock-free code by using xchg or locked instructions.