It seems that I found the problem. For a reason which I do not know yet the scheduler for smp systems is running - although this one should work to! I think that it finds a MP table because of the IO-APIC, but then there should be only 1 cpu in the table. I have to check this.
Edit::
Now all works just fine on my 2nd PC, the scheduler (smp) and the semaphores. I found also the reason why the kernel used the smp scheduler, I was setting up the smp scheduler when I found a MP structure, but before checking how mayn cpus there are ::)
Scheduler and semaphores
Re:Scheduler and semaphores
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.
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!
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
;----------------------------
Re:Scheduler and semaphores
Ok, I found the problem it was the release function. If anyone is interessted here is the code:
Code: Select all
;----------------------------
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]
mov ebx,[eax+thread_t.next]
mov ecx,[eax+thread_t.prev]
test ebx,ebx
jz .last
;----------------------------
; put the 2nd thread onto the top of the queue and put the last thread onto the 2nd threads prev ptr
mov [ebx+thread_t.prev],ecx
mov [esi+semaphore_t.threads],ebx
jmp .scheduler
;----------------------------
; there is no more thread on the queue
align 4
.last:
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
;----------------------------