Any Semaphore Implementation information pls?
Posted: Wed Aug 20, 2008 1:27 am
Any Semaphore Implementation information pls?
Or any lock mechanism?
Or any lock mechanism?
The Place to Start for Operating System Developers
http://f.osdev.org/
Write one, genius.oohayulin wrote:Any Semaphore Implementation information pls?
Or any lock mechanism?
I'm a little bored, so here's some simple unoptimized spinlock code:oohayulin wrote:Or any lock mechanism?
Code: Select all
;Acquire the lock
;
;Input
; esi address of the lock
acquireSpinlock:
.tryLock:
lock bts [esi],0
jc .tryLock
ret
;Release the lock
;
;Input
; esi address of the lock
releaseLock:
mov dword [esi],0
ret
Code: Select all
;Acquire the lock
;
;Input
; esi address of the lock
acquireSpinlock:
.testLock1:
bt [esi],0
jnc .tryLock
.testLock2:
pause
bt [esi],0
jc .testLock2
.tryLock:
lock bts [esi],0
jc .tryLock
ret
;Release the lock
;
;Input
; esi address of the lock
releaseSpinlock:
mov dword [esi],0
ret
Code: Select all
;Initialize the lock
;
;Input
; esi address of the lock
initSpinlock:
%ifdef DEBUGGING
cmp dword [esi+4],0xFEEDFACE
je CRITICAL_ERROR_attempt_to_initialize_lock_that_was_already_initialized
mov dword [esi+4],0xFEEDFACE
%endif
mov dword [esi],0
ret
;Acquire the lock
;
;Input
; esi address of the lock
acquireSpinlock:
%ifdef DEBUGGING
push ebx
push eax
mov ebx,[current_thread_ID]
xor eax,eax
or ebx,0x80000000
cmp dword [esi+4],0xFEEDFACE
je CRITICAL_ERROR_attempt_to_acquire_something_that_isn't_a_valid_lock
.testLock1:
cmp [esi],eax
je .tryLock
.testLock2:
pause
cmp [esi],eax
jne .testLock2
.tryLock:
lock cmpxchg [esi],ebx
je .gotLock
cmp eax,ebx
jne CRITICAL_ERROR_attempt_to_acquire_lock_that_thread_already_has
xor eax,eax
jmp .testLock2
.gotLock:
pop eax
pop ebx
%else
.testLock1:
bt [esi],0
jnc .tryLock
.testLock2:
pause
bt [esi],0
jc .testLock2
.tryLock:
lock bts [esi],0
jc .tryLock
%endif
ret
;Release the lock
;
;Input
; esi address of the lock
releaseSpinlock:
%ifdef DEBUGGING
cmp dword [esi+4],0xFEEDFACE
jne CRITICAL_ERROR_attempt_to_release_something_that_isn't_a_valid_lock
cmp dword [esi],0
jne CRITICAL_ERROR_tried_to_free_lock_when_lock_not_acquired
push ebx
mov ebx,[current_thread_ID]
or ebx,0x80000000
cmp [esi],ebx
pop ebx
jne CRITICAL_ERROR_wrong_task_tried_to_free_lock
%endif
mov dword [esi],0
ret
Code: Select all
;Macro to create a pre-initialized spinlock (e.g. in the ".data" section)
%macro SPINLOCK 1
%if ($ & 0x7F) <> 0
%warning Lock not aligned on a 128-byte boundary
%endif
dd 0
dd 0xFEEDFACE
%endmacro
;Macro to initialize a lock (e.g. for dynamically allocated locks)
%macro INIT_SPINLOCK 1
%ifdef DEBUGGING
cmp dword [%1+4],0xFEEDFACE
je CRITICAL_ERROR_attempt_to_initialize_lock_that_was_already_initialized
mov dword [%1+4],0xFEEDFACE
%endif
mov dword [%1],0
%endmacro
;Macro to acquire a lock
%macro ACQUIRE_SPINLOCK 1
%ifdef DEBUGGING
push ebx
push eax
mov ebx,[current_thread_ID]
xor eax,eax
or ebx,0x80000000
cmp dword [%1+4],0xFEEDFACE
je CRITICAL_ERROR_attempt_to_acquire_something_that_isn't_a_valid_lock
%%testLock1:
cmp [%1],eax
je %%tryLock
%%testLock2:
pause
cmp [%1],eax
jne %%testLock2
%%tryLock:
lock cmpxchg [%1],ebx
je %%gotLock
cmp eax,ebx
jne CRITICAL_ERROR_attempt_to_acquire_lock_that_thread_has_already_acquired
xor eax,eax
jmp %%testLock2
%%gotLock:
pop eax
pop ebx
%else
%%testLock1:
bt [%1],0
jnc %%tryLock
%%testLock2:
pause
bt [%1],0
jc %%testLock2
%%tryLock:
lock bts [%1],0
jc %%tryLock
%endif
%endmacro
;Macro to release a lock
%macro RELEASE_SPINLOCK 1
%ifdef DEBUGGING
cmp dword [%1+4],0xFEEDFACE
jne CRITICAL_ERROR_attempt_to_release_something_that_isn't_a_valid_lock
cmp dword [%1],0
jne CRITICAL_ERROR_tried_to_free_lock_when_lock_not_acquired
push ebx
mov ebx,[current_thread_ID]
or ebx,0x80000000
cmp [%1],ebx
pop ebx
jne CRITICAL_ERROR_wrong_task_tried_to_free_lock
%endif
mov dword [%1],0
%endmacro
Code: Select all
sem_down:
mov eax, 1
lock xadd [semaphore], eax ; magix happens here
.wait:
mov edx, [semaphore+4]
add edx, user_count
cmp eax, edx
jns .wait
ret
sem_up:
lock inc [semaphore+4]
ret
semaphore: dd 0, 0