Back to the semaphore problem
I got all cpus in a smp system running and wanted to test the smp scheduler. There was 1 failure in the code but I found it fast. Now there is a problem with my semaphore code! I changed the code a little bit since last time.
Code: Select all
;----------------------------
PROC semaphore_acquire_smp, sem
;----------------------------
BEGIN
;----------------------------
; make sure we are the only one to work on the semaphore
cli
CALL mutex_acquire, dword[sem]
lock sub dword[esi+semaphore_t.count],1
jz .end
;----------------------------
; look if we have to wait or we can go right away
cmp dword[esi+semaphore_t.count],0
jg .end
;----------------------------
; we have to wait
APIC_GET_ID eax
mov ebx,[cpu_ptr+4*eax]
mov edi,[esi+semaphore_t.threads]
mov eax,[ebx+cpu_t.schdl_act_thread]
test edi,edi
jz .first
mov ebx,[edi+thread_t.prev]
xor ecx,ecx
mov [eax+thread_t.prev],ebx
mov [eax+thread_t.next],ecx
mov [edi+thread_t.prev],eax
mov [ebx+thread_t.next],eax
jmp .scheduler
;----------------------------
; we are the first thread
align 4
.first:
mov [esi+semaphore_t.threads],eax
mov [eax+thread_t.prev],eax
mov [eax+thread_t.next],edi
;----------------------------
; scheduler have to know that this thread wants to wait
.scheduler:
or dword[eax+thread_t.flags],THREAD_WAIT
or dword[schdl_flags],SCHEDULER_RESCHEDULE
CALL mutex_release, dword[sem]
sti
int INT_SCHEDULER - 1
.end_wait:
RETURN
;----------------------------
align 4
.end:
CALL mutex_release, dword[sem]
sti
RETURN
ENDP
;----------------------------
;----------------------------
PROC semaphore_release, sem
;----------------------------
BEGIN
;----------------------------
; make sure we are the only one to work on the semaphore
cli
CALL mutex_acquire, dword[sem]
lock add dword[esi+semaphore_t.count],1
;----------------------------
; look if we need to awake a thread
cmp dword[esi+semaphore_t.count],0
jg .end
;----------------------------
; we have to awake the thread on the top of the queue
mov eax,[esi+semaphore_t.threads]
test eax,eax
jnz .go_on
mov eax,[esi+semaphore_t.count]
int 0
align 4
.go_on:
mov ebx,[eax+thread_t.next]
mov ecx,[eax+thread_t.prev]
test ebx,ebx
jz .last
mov [ecx+thread_t.prev],ebx
mov [esi+semaphore_t.threads],ecx
jmp .scheduler
;----------------------------
; there is no more thread on the queue
align 4
.last:
cmp dword[esi+semaphore_t.count],0
je .last@go_on
mov eax,[esi+semaphore_t.count]
int 0
align 4
.last@go_on:
mov [esi+semaphore_t.threads],ebx
;----------------------------
; scheduler needs to awaken the thread in eax
.scheduler:
and dword[eax+thread_t.flags],not THREAD_WAIT
push eax
CALL mutex_release, dword[sem]
sti
CALL scheduler_add_scheduler ;par is in pushed eax
;----------------------------
.end_awaken:
RETURN
;----------------------------
align 4
.end:
CALL mutex_release, dword[sem]
sti
RETURN
ENDP
;----------------------------
As you can see I put debug code in the release function. And this debug code gets called
If I get to the ".last" label in "semaphore_release" the count is 0xfffffffe! I don?t know how this can be but maybe you see the point where my code is wrong!