Scheduler and semaphores

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
FlashBurn

Re:Scheduler and semaphores

Post by FlashBurn »

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 ::)
FlashBurn

Re:Scheduler and semaphores

Post by FlashBurn »

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!
FlashBurn

Re:Scheduler and semaphores

Post by FlashBurn »

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
;----------------------------
Post Reply