[next piece of prev post]
My semaphore code:
Code: Select all
;----------------------------
PROC semaphore_acquire, sem
VARS this_cpu
;----------------------------
BEGIN
APIC_GET_ID eax
mov ebx,[cpu_ptr+4*eax]
mov [this_cpu],ebx
;----------------------------
; make sure we are the only one to work on the semaphore
CALL mutex_acquire, dword[sem]
sub dword[esi+semaphore_t.count],1
;----------------------------
; look if we have to wait or we can go right away
cmp dword[esi+semaphore_t.count],0
jge .end
;----------------------------
; we have to wait
mov ebx,[this_cpu]
mov edi,[esi+semaphore_t.end]
mov eax,[ebx+cpu_t.schdl_act_thread]
test edi,edi
jz .first
xor ebx,ebx
mov [edi+thread_t.next],eax
mov [eax+thread_t.prev],edi
mov [eax+thread_t.next],ebx
mov [esi+semaphore_t.end],eax
jmp .scheduler
;----------------------------
; we are the first thread
align 4
.first:
mov [esi+semaphore_t.start],eax
mov [esi+semaphore_t.end],eax
mov [eax+thread_t.prev],edi
mov [eax+thread_t.next],edi
;----------------------------
; scheduler have to know that this thread wants to wait
.scheduler:
mov ebx,[this_cpu]
or dword[eax+thread_t.flags],thread_wait
or dword[ebx+cpu_t.scheduler_flags],scheduler_reschedule
CALL mutex_release, dword[sem]
hlt
; int INT_SCHEDULER
.end_wait:
RETURN
;----------------------------
align 4
.end:
CALL mutex_release, dword[sem]
RETURN
ENDP
;----------------------------
;----------------------------
PROC semaphore_release, sem
;----------------------------
BEGIN
;----------------------------
; make sure we are the only one to work on the semaphore
CALL mutex_acquire, dword[sem]
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.start]
mov ebx,[eax+thread_t.next]
xor ecx,ecx
test ebx,ebx
jz .last
mov [ebx+thread_t.prev],ecx
mov [esi+semaphore_t.start],ebx
mov [eax+thread_t.prev],ecx
mov [eax+thread_t.next],ecx
jmp .scheduler
;----------------------------
; there is only one thread on the queue
align 4
.last:
mov [esi+semaphore_t.start],ebx
mov [esi+semaphore_t.end],ebx
mov [eax+thread_t.prev],ebx
mov [eax+thread_t.next],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]
CALL scheduler_add_scheduler ;par is in pushed eax
; int INT_SCHEDULER
;----------------------------
.end_awaken:
RETURN
;----------------------------
align 4
.end:
CALL mutex_release, dword[sem]
RETURN
ENDP
;----------------------------
And now the function that could do much harm to the system:
Code: Select all
;----------------------------
PROC scheduler_add_scheduler, ptr2thread
;----------------------------
BEGIN
CALL semaphore_acquire, sem_schdl_queue
cli
CALL mutex_acquire_noint, schdl_mutex
;----------------------------
; add thread to ready queue
mov esi,[ptr2thread]
mov ebx,1
mov ecx,[esi+thread_t.dyn_prio]
mov edi,[ready_queue_ptr]
shl ebx,cl
or [ready_queue_bitmap],ebx
mov eax,[edi+4*ecx]
test eax,eax
jz .first
mov ebx,[eax+thread_t.prev]
mov [esi+thread_t.next],eax
mov [esi+thread_t.prev],ebx
mov [eax+thread_t.prev],esi
mov [ebx+thread_t.next],esi
jmp .end
;----------------------------
; it is the 1st thread in this priority queue
align 4
.first:
mov [esi+thread_t.prev],esi
mov [esi+thread_t.next],esi
mov [edi+4*ecx],esi
;----------------------------
align 4
.end:
APIC_GET_ID eax
mov edx,[cpu_ptr+4*eax]
or dword[edx+cpu_t.scheduler_flags],scheduler_reschedule
CALL mutex_release_noint, schdl_mutex
sti
CALL semaphore_release, sem_schdl_queue
RETURN
ENDP
;----------------------------
You may have a look at the functions and can tell me if there is any logical fault in there or if you see anything that could not work the way it should!
Edit::
There are commented int calls, if I uncomment them the scheduler will work for some time, but then not only the threads are not running but also the scheduler isn?t!