Page 1 of 1
Mutex
Posted: Wed Sep 04, 2002 5:03 am
by Whatever5k
I'm wondering how to implement a Mutex. I've got OS Design and Implementation by A. Tanenbaum and he discusses this topic, too. But there's only a solution, if only *two* processes want to access a variable. There is also the tsr instruction, but I do not know, if every CPU supports it. And message handling is too compilicated.
So, what do you think - how should I solve this?
Re:Mutex
Posted: Wed Sep 04, 2002 5:42 am
by Pype.Clicker
Code: Select all
mutex_lock:
cli
; assume [edx] is the place where the mutex is
; a non-zero value in the mutex means its locked.
mov al, 1
.loop:
xchg [edx],al
cmp al,1
je .loop
ret
mutex_unlock:
mov byte [edx],0
sti
ret
now, this is a "spinlock" mutex, so you should use it only when you know the access to the component will be locked only for a very short time. You'll also notice i locked interrupts while waiting so that we're sure there won't be a preemptive task switch while the mutex is held.
This code will also work fine with multi-CPU systems as XCHG is an atomic operation on the bus (lock xchg if not sure
. And because you only put short operations and have busy waiting, it won't hang other CPUs for too long
Basic idea is to use this to control access to structures more complex like semaphores, message queues, etc.
Re:Mutex
Posted: Wed Sep 04, 2002 7:05 am
by Whatever5k
Ok, but how do I transfer my mutex variable to edx?
Is this here possible?
Code: Select all
[BITS 32]
lock_mutex:
cli;
push eax;
push edx;
mov al,1
mov edx,[ss:esp+2] ; is this here possible?
.loop:
...
...
Is it possible? If not, how can I fix it?
I do the [ss:esp+2] because I call lock_mutex in C like this:
lock_mutex(&semaphore);
So semaphore is put on the stack.
Re:Mutex
Posted: Wed Sep 04, 2002 7:54 am
by Pype.Clicker
Whatever5k wrote:
Ok, but how do I transfer my mutex variable to edx?
Is this here possible?
Code: Select all
[BITS 32]
lock_mutex:
cli;
push eax;
push edx;
mov al,1
mov edx,[ss:esp+2] ; is this here possible?
.loop:
...
...
Is it possible? If not, how can I fix it?
I do the [ss:esp+2] because I call lock_mutex in C like this:
lock_mutex(&semaphore);
So semaphore is put on the stack.
just keep in mind that dx is not the mutex, but just a pointer to it ... So yes, you can give the address of semaphore on the stack and get it with [ss:esp+4] (remember we're in BITS32, so eip needs 4 bytes), or for more cleaner (backtrace-friendly) code,
Code: Select all
push ebp
mov ebp, esp
mov edx,[ebp+8]
...
pop ebp
ret
Re:Mutex
Posted: Wed Sep 04, 2002 8:42 am
by Whatever5k
Thanks...here is the full code:
Code: Select all
[BITS 32]
[global _lock_mutex]
_lock_mutex:
cli ; disable interrupts
push eax; ; save
push edx; ; registers
push ebp;
mov ebp,esp
mov edx,[ss:ebp+8] ; MOV the parameter of the function to edx
mov al,1
.loop:
xchg [edx],al
cmp al,1
je .loop
pop ebp;
pop edx;
pop eax;
ret
[global _unlock_mutex]
_unlock_mutex:
push eax;
push edx;
push ebp;
mov ebp,esp
mov edx,[ss:ebp+8]
mov byte [edx],0
pop ebp;
pop edx;
pop eax;
sti ; enable interrupts
ret