irq: reset fail counter

all kernel: replace old non-blocking mutexes

git-svn-id: svn://kolibrios.org@2129 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2011-08-27 10:59:48 +00:00
parent ceb9879cd5
commit 246c135659
12 changed files with 248 additions and 218 deletions

View File

@ -645,7 +645,7 @@ virtual at 0
end virtual end virtual
struc MEM_STATE struc MEM_STATE
{ .mutex rd 1 { .mutex MUTEX
.smallmap rd 1 .smallmap rd 1
.treemap rd 1 .treemap rd 1
.topsize rd 1 .topsize rd 1
@ -664,7 +664,7 @@ struc PG_DATA
.kernel_pages dd ? .kernel_pages dd ?
.kernel_tables dd ? .kernel_tables dd ?
.sys_page_dir dd ? .sys_page_dir dd ?
.pg_mutex dd ? .mutex MUTEX
} }
;struc LIB ;struc LIB

View File

@ -151,7 +151,8 @@ proc init_kernel_heap
mov [mem_block_list+63*4], ebx mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC mov byte [mem_block_map], 0xFC
and [heap_mutex], 0 mov ecx, heap_mutex
call mutex_init
mov [heap_blocks], 4095 mov [heap_blocks], 4095
mov [free_blocks], 4094 mov [free_blocks], 4094
ret ret
@ -272,14 +273,14 @@ proc alloc_kernel_space stdcall, size:dword
push esi push esi
push edi push edi
mov ecx, heap_mutex
call mutex_lock
mov eax, [size] mov eax, [size]
add eax, 4095 add eax, 4095
and eax, not 4095 and eax, not 4095
mov [size], eax mov [size], eax
mov ebx, heap_mutex
call wait_mutex ;ebx
cmp eax, [heap_free] cmp eax, [heap_free]
ja .error ja .error
@ -355,10 +356,11 @@ proc alloc_kernel_space stdcall, size:dword
mov [edx+list_bk], esi mov [edx+list_bk], esi
mov [esi+block_flags], USED_BLOCK mov [esi+block_flags], USED_BLOCK
mov eax, [esi+block_base]
mov ebx, [size] mov ebx, [size]
sub [heap_free], ebx sub [heap_free], ebx
and [heap_mutex], 0 mov ecx, heap_mutex
call mutex_unlock
mov eax, [esi+block_base]
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
@ -378,17 +380,19 @@ proc alloc_kernel_space stdcall, size:dword
mov [edx+list_bk], edi mov [edx+list_bk], edi
mov [edi+block_flags], USED_BLOCK mov [edi+block_flags], USED_BLOCK
mov eax, [edi+block_base]
mov ebx, [size] mov ebx, [size]
sub [heap_free], ebx sub [heap_free], ebx
and [heap_mutex], 0 mov ecx, heap_mutex
call mutex_unlock
mov eax, [edi+block_base]
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
ret ret
.error: .error:
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax xor eax, eax
mov [heap_mutex], eax
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
@ -400,8 +404,9 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
push ebx push ebx
push esi push esi
push edi push edi
mov ebx, heap_mutex
call wait_mutex ;ebx mov ecx, heap_mutex
call mutex_lock
mov eax, [base] mov eax, [base]
mov esi, [mem_used.fd] mov esi, [mem_used.fd]
@ -491,9 +496,10 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
@@: @@:
bts [mem_block_mask], eax bts [mem_block_mask], eax
.m_eq: .m_eq:
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax xor eax, eax
mov [heap_mutex], eax not eax
dec eax
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
@ -513,16 +519,18 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
@@: @@:
bts [mem_block_mask], eax bts [mem_block_mask], eax
mov [esi+block_flags],FREE_BLOCK mov [esi+block_flags],FREE_BLOCK
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax xor eax, eax
mov [heap_mutex], eax not eax
dec eax
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
ret ret
.fail: .fail:
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax xor eax, eax
mov [heap_mutex], eax
pop edi pop edi
pop esi pop esi
pop ebx pop ebx
@ -607,8 +615,8 @@ align 4
proc kernel_free stdcall, base:dword proc kernel_free stdcall, base:dword
push ebx esi push ebx esi
mov ebx, heap_mutex mov ecx, heap_mutex
call wait_mutex ;ebx call mutex_lock
mov eax, [base] mov eax, [base]
mov esi, [mem_used.fd] mov esi, [mem_used.fd]
@ -624,19 +632,17 @@ proc kernel_free stdcall, base:dword
cmp [esi+block_flags], USED_BLOCK cmp [esi+block_flags], USED_BLOCK
jne .fail jne .fail
and [heap_mutex], 0 call mutex_unlock
push ecx
mov ecx, [esi+block_size]; mov ecx, [esi+block_size];
shr ecx, 12 shr ecx, 12
call release_pages ;eax, ecx call release_pages ;eax, ecx
pop ecx
stdcall free_kernel_space, [base] stdcall free_kernel_space, [base]
pop esi ebx pop esi ebx
ret ret
.fail: .fail:
call mutex_unlock
xor eax, eax xor eax, eax
mov [heap_mutex], eax
pop esi ebx pop esi ebx
ret ret
endp endp

View File

@ -72,8 +72,6 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
.irqh dd ? .irqh dd ?
endl endl
xchg bx, bx
and [.irqh], 0 and [.irqh], 0
push ebx push ebx
@ -100,17 +98,17 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
mov eax, [ecx] mov eax, [ecx]
mov [next_irqh], eax mov [next_irqh], eax
mov [.irqh], ecx mov [.irqh], ecx
mov [irq_failed+ebx*4], 0 ;clear counter
mov eax, [user_data] mov eax, [user_data]
mov [ecx+IRQH.handler], edx mov [ecx+IRQH.handler], edx
mov [ecx+IRQH.data], eax mov [ecx+IRQH.data], eax
lea edx, [irqh_tab+ebx*8] lea edx, [irqh_tab+ebx*8]
list_add_tail ecx, edx ;clobber eax list_add_tail ecx, edx ;clobber eax
stdcall enable_irq, ebx
stdcall enable_irq, [irq]
.fail: .fail:
popfd popfd

View File

@ -20,7 +20,7 @@ $Revision$
; esi= nb ; esi= nb
; ebx= idx ; ebx= idx
; ;
align 16 align 4
malloc: malloc:
push esi push esi
@ -31,8 +31,8 @@ malloc:
and esi, -8 and esi, -8
add esi, 8 add esi, 8
mov ebx, mst.mutex mov ecx, mst.mutex
call wait_mutex ;ebx call mutex_lock
cmp esi, 256 cmp esi, 256
jae .large jae .large
@ -92,9 +92,13 @@ malloc:
pop edi pop edi
pop ebp pop ebp
.done: .done:
mov esi, eax
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi pop esi
mov [mst.mutex], 0
ret ret
.split: .split:
lea ebx, [edx+8] ;ebx=mem lea ebx, [edx+8] ;ebx=mem
@ -133,10 +137,10 @@ malloc:
mov [edx+12], eax ; F->bk = r; mov [edx+12], eax ; F->bk = r;
mov [eax+8], edx ; r->fd = F; mov [eax+8], edx ; r->fd = F;
mov [eax+12], ecx ; r->bk = B; mov [eax+12], ecx ; r->bk = B;
mov eax, ebx mov eax, ebx
pop esi jmp .done
mov [mst.mutex], 0
ret
.small: .small:
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) ; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
@ -150,9 +154,8 @@ malloc:
call malloc_small call malloc_small
test eax, eax test eax, eax
jz .from_top jz .from_top
pop esi jmp .done
and [mst.mutex], 0
ret
.large: .large:
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) ; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
@ -189,18 +192,15 @@ malloc:
mov [edx+4], eax mov [edx+4], eax
mov [ecx+4], esi mov [ecx+4], esi
lea eax, [ecx+8] lea eax, [ecx+8]
pop esi jmp .done
and [mst.mutex], 0
ret
.fail: .fail:
xor eax, eax xor eax, eax
pop esi jmp .done
and [mst.mutex], 0
ret
; param ; param
; eax= mem ; eax= mem
align 4
free: free:
push edi push edi
mov edi, eax mov edi, eax
@ -211,8 +211,8 @@ free:
test byte [edi+4], 2 test byte [edi+4], 2
je .fail je .fail
mov ebx, mst.mutex mov ecx, mst.mutex
call wait_mutex ;ebx call mutex_lock
; psize = p->head & (~3); ; psize = p->head & (~3);
@ -289,7 +289,10 @@ free:
mov [mst.top], edi mov [mst.top], edi
mov [edi+4], eax mov [edi+4], eax
.fail2: .fail2:
and [mst.mutex], 0 mov esi, eax
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi pop esi
.fail: .fail:
pop edi pop edi
@ -410,13 +413,15 @@ insert_chunk:
mov [esi+8], edx ;P->fd = F mov [esi+8], edx ;P->fd = F
mov [esi+12], eax ;P->bk = B mov [esi+12], eax ;P->bk = B
pop esi pop esi
and [mst.mutex], 0 mov ecx, mst.mutex
call mutex_unlock
ret ret
.large: .large:
mov ebx, eax mov ebx, eax
call insert_large_chunk call insert_large_chunk
pop esi pop esi
and [mst.mutex], 0 mov ecx, mst.mutex
call mutex_unlock
ret ret
@ -591,21 +596,21 @@ unlink_large_chunk:
btr [mst.treemap], ecx btr [mst.treemap], ecx
pop edi pop edi
ret ret
.l3: .l3:
cmp [edi+16], edx cmp [edi+16], edx
jne @F jne @F
mov [edi+16], eax mov [edi+16], eax
jmp .l4 jmp .l4
@@: @@:
mov [edi+20], eax mov [edi+20], eax
.l4: .l4:
test eax, eax test eax, eax
je .done je .done
.l5: .l5:
mov [eax+24], edi mov [eax+24], edi
mov ecx, [edx+16] mov ecx, [edx+16]
@ -614,7 +619,7 @@ unlink_large_chunk:
mov [eax+16], ecx mov [eax+16], ecx
mov [ecx+24], eax mov [ecx+24], eax
.l6: .l6:
mov edx, [edx+20] mov edx, [edx+20]
test edx, edx test edx, edx
@ -622,7 +627,7 @@ unlink_large_chunk:
mov [eax+20], edx mov [eax+20], edx
mov [edx+24], eax mov [edx+24], eax
.done: .done:
pop edi pop edi
ret ret
@ -644,10 +649,10 @@ malloc_small:
mov edi, [ecx+4] mov edi, [ecx+4]
and edi, -4 and edi, -4
sub edi, esi sub edi, esi
.loop: .loop:
mov ebx, ecx mov ebx, ecx
.loop_1: .loop_1:
; while ((t = leftmost_child(t)) != 0) ; while ((t = leftmost_child(t)) != 0)
@ -657,10 +662,10 @@ malloc_small:
jz @F jz @F
mov ecx, eax mov ecx, eax
jmp .l1 jmp .l1
@@: @@:
mov ecx, [ecx+20] mov ecx, [ecx+20]
.l1: .l1:
test ecx, ecx test ecx, ecx
jz .unlink jz .unlink
@ -711,7 +716,7 @@ malloc_small:
lea eax, [ebx+8] lea eax, [ebx+8]
ret ret
.split: .split:
; v->head = nb|PINUSE_BIT|CINUSE_BIT; ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
@ -744,7 +749,7 @@ malloc_small:
pop ebp pop ebp
lea eax, [ebx+8] lea eax, [ebx+8]
ret ret
.large: .large:
lea eax, [ebx+8] lea eax, [ebx+8]
push eax push eax
@ -798,20 +803,20 @@ malloc_large:
jne @F jne @F
xor ecx, ecx xor ecx, ecx
jmp .l1 jmp .l1
@@: @@:
mov edx, ecx mov edx, ecx
shr edx, 1 shr edx, 1
mov ecx, 37 mov ecx, 37
sub ecx, edx sub ecx, edx
.l1: .l1:
mov edx, ebx mov edx, ebx
shl edx, cl shl edx, cl
; rst = 0; ; rst = 0;
mov [.rst], ebp mov [.rst], ebp
.loop: .loop:
; trem = (t->head & ~INUSE_BITS) - nb; ; trem = (t->head & ~INUSE_BITS) - nb;
@ -831,7 +836,7 @@ malloc_large:
mov ebp, eax mov ebp, eax
mov edi, ecx mov edi, ecx
je .l2 je .l2
@@: @@:
; rt = t->child[1]; ; rt = t->child[1];
@ -853,7 +858,7 @@ malloc_large:
; rst = rt; ; rst = rt;
mov [.rst], ecx mov [.rst], ecx
@@: @@:
; if (t == 0) ; if (t == 0)
@ -864,11 +869,11 @@ malloc_large:
add edx, edx add edx, edx
jmp .loop jmp .loop
@@: @@:
; t = rst; ; t = rst;
mov eax, [.rst] mov eax, [.rst]
.l2: .l2:
; if (t == 0 && v == 0) ; if (t == 0 && v == 0)
@ -877,7 +882,7 @@ malloc_large:
test ebp, ebp test ebp, ebp
jne .l7 jne .l7
mov ecx, [.idx] mov ecx, [.idx]
.l3: .l3:
; leftbits = (-1<<idx) & ms.treemap; ; leftbits = (-1<<idx) & ms.treemap;
@ -891,13 +896,13 @@ malloc_large:
bsf eax, edx bsf eax, edx
; t = ms.treebins[i]; ; t = ms.treebins[i];
mov eax, [mst.treebins+eax*4] mov eax, [mst.treebins+eax*4]
@@: @@:
; while (t != 0) ; while (t != 0)
test eax, eax test eax, eax
jz .l5 jz .l5
.l4: .l4:
; trem = (t->head & ~INUSE_BITS) - nb; ; trem = (t->head & ~INUSE_BITS) - nb;
@ -915,7 +920,7 @@ malloc_large:
mov edi, ecx mov edi, ecx
; v = t; ; v = t;
mov ebp, eax mov ebp, eax
@@: @@:
; t = leftmost_child(t); ; t = leftmost_child(t);
@ -925,24 +930,24 @@ malloc_large:
je @F je @F
mov eax, ecx mov eax, ecx
jmp .l6 jmp .l6
@@: @@:
mov eax, [eax+20] mov eax, [eax+20]
.l6: .l6:
; while (t != 0) ; while (t != 0)
test eax, eax test eax, eax
jne .l4 jne .l4
.l5: .l5:
; if (v != 0) ; if (v != 0)
test ebp, ebp test ebp, ebp
jz .done jz .done
.l7: .l7:
; r = chunk_plus_offset((mchunkptr)v, nb); ; r = chunk_plus_offset((mchunkptr)v, nb);
@ -974,7 +979,7 @@ malloc_large:
pop esi pop esi
pop ebp pop ebp
ret ret
.large: .large:
; v->head = nb|PINUSE_BIT|CINUSE_BIT; ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
@ -1000,7 +1005,7 @@ malloc_large:
pop esi pop esi
pop ebp pop ebp
ret ret
.done: .done:
add esp, 8 add esp, 8
pop edi pop edi
@ -1017,7 +1022,7 @@ init_malloc:
mov [mst.topsize], 128*1024 mov [mst.topsize], 128*1024
mov dword [eax+4], (128*1024) or 1 mov dword [eax+4], (128*1024) or 1
mov eax, mst.smallbins mov eax, mst.smallbins
@@: @@:
mov [eax+8], eax mov [eax+8], eax
mov [eax+12], eax mov [eax+12], eax
@ -1025,5 +1030,8 @@ init_malloc:
cmp eax, mst.smallbins+512 cmp eax, mst.smallbins+512
jb @B jb @B
mov ecx, mst.mutex
call mutex_init
ret ret

View File

@ -214,30 +214,32 @@ endp
align 4 align 4
commit_pages: commit_pages:
push edi
test ecx, ecx test ecx, ecx
jz .fail jz .fail
mov edi, ebx push edi
mov ebx, pg_data.pg_mutex push eax
call wait_mutex ;ebx push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
pop eax
mov edx, 0x1000 mov edi, ebx
mov ebx, edi shr edi, 12
shr ebx, 12 lea edi, [page_tabs+edi*4]
@@: @@:
mov [page_tabs+ebx*4], eax stosd
; push eax invlpg [ebx]
invlpg [edi] add eax, 0x1000
; pop eax add ebx, 0x1000
add edi, edx loop @B
add eax, edx
inc ebx
dec ecx
jnz @B
mov [pg_data.pg_mutex],ecx
.fail:
pop edi pop edi
mov ecx, pg_data.mutex
call mutex_unlock
.fail:
ret ret
@ -248,15 +250,21 @@ commit_pages:
align 4 align 4
release_pages: release_pages:
pushad push ebp
mov ebx, pg_data.pg_mutex push esi
call wait_mutex ;ebx push edi
push ebx
mov esi, eax mov esi, eax
mov edi, eax mov edi, eax
shr esi, 10 shr esi, 12
add esi, page_tabs lea esi, [page_tabs+esi*4]
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
mov ebp, [pg_data.pages_free] mov ebp, [pg_data.pages_free]
mov ebx, [page_start] mov ebx, [page_start]
@ -264,9 +272,7 @@ release_pages:
@@: @@:
xor eax, eax xor eax, eax
xchg eax, [esi] xchg eax, [esi]
push eax
invlpg [edi] invlpg [edi]
pop eax
test eax, 1 test eax, 1
jz .next jz .next
@ -285,11 +291,16 @@ release_pages:
.next: .next:
add edi, 0x1000 add edi, 0x1000
add esi, 4 add esi, 4
dec ecx loop @B
jnz @B
mov [pg_data.pages_free], ebp mov [pg_data.pages_free], ebp
and [pg_data.pg_mutex],0 mov ecx, pg_data.mutex
popad call mutex_unlock
pop ebx
pop edi
pop esi
pop ebp
ret ret
; param ; param
@ -423,8 +434,8 @@ endp
align 4 align 4
proc new_mem_resize stdcall, new_size:dword proc new_mem_resize stdcall, new_size:dword
mov ebx, pg_data.pg_mutex mov ecx, pg_data.mutex
call wait_mutex ;ebx call mutex_lock
mov edi, [new_size] mov edi, [new_size]
add edi,4095 add edi,4095
@ -464,8 +475,10 @@ proc new_mem_resize stdcall, new_size:dword
mov ebx, [new_size] mov ebx, [new_size]
call update_mem_size call update_mem_size
mov ecx, pg_data.mutex
call mutex_unlock
xor eax, eax xor eax, eax
dec [pg_data.pg_mutex]
ret ret
.expand: .expand:
@ -539,9 +552,11 @@ proc new_mem_resize stdcall, new_size:dword
pop edi pop edi
pop esi pop esi
.exit: .exit:
mov ecx, pg_data.mutex
call mutex_unlock
xor eax, eax xor eax, eax
inc eax inc eax
dec [pg_data.pg_mutex]
ret ret
endp endp

View File

@ -360,8 +360,8 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
app_tabs dd ? app_tabs dd ?
endl endl
mov ebx, pg_data.pg_mutex mov ecx, pg_data.mutex
call wait_mutex ;ebx call mutex_lock
xor eax, eax xor eax, eax
mov [dir_addr], eax mov [dir_addr], eax
@ -387,11 +387,11 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
shr ecx, 12 shr ecx, 12
mov [img_pages], ecx mov [img_pages], ecx
if GREEDY_KERNEL if GREEDY_KERNEL
lea eax, [ecx+ebx+2] ;only image size lea eax, [ecx+ebx+2] ;only image size
else else
lea eax, [eax+ebx+2] ;all requested memory lea eax, [eax+ebx+2] ;all requested memory
end if end if
cmp eax, [pg_data.pages_free] cmp eax, [pg_data.pages_free]
ja .fail ja .fail
@ -480,11 +480,13 @@ end if
.done: .done:
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
dec [pg_data.pg_mutex] mov ecx, pg_data.mutex
call mutex_unlock
mov eax, [dir_addr] mov eax, [dir_addr]
ret ret
.fail: .fail:
dec [pg_data.pg_mutex] mov ecx, pg_data.mutex
call mutex_unlock
cmp [dir_addr], 0 cmp [dir_addr], 0
je @f je @f
stdcall destroy_app_space, [dir_addr], 0 stdcall destroy_app_space, [dir_addr], 0
@ -554,10 +556,10 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
jg .ret jg .ret
;if there isn't threads then clear memory. ;if there isn't threads then clear memory.
mov esi, [dlls_list] mov esi, [dlls_list]
call destroy_all_hdlls call destroy_all_hdlls ;ecx=APPDATA
mov ebx, pg_data.pg_mutex mov ecx, pg_data.mutex
call wait_mutex ;ebx call mutex_lock
mov eax, [pg_dir] mov eax, [pg_dir]
and eax, not 0xFFF and eax, not 0xFFF
@ -583,7 +585,8 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
.exit: .exit:
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP stdcall map_page,[tmp_task_ptab],0,PG_UNMAP
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP stdcall map_page,[tmp_task_pdir],0,PG_UNMAP
dec [pg_data.pg_mutex] mov ecx, pg_data.mutex
call mutex_unlock
.ret: .ret:
ret ret
endp endp
@ -956,24 +959,6 @@ proc new_sys_threads
ret ret
endp endp
; param
; ebx=mutex
align 4
wait_mutex:
;;Maxis use atomic bts for mutex 4.4.2009
push eax
push ebx
.do_wait:
bts dword [ebx],0
jnc .locked
call change_task
jmp .do_wait
.locked:
pop ebx
pop eax
ret
align 4 align 4
tls_app_entry: tls_app_entry:

View File

@ -310,7 +310,7 @@ mem_block_arr rd 1
mem_block_start rd 1 mem_block_start rd 1
mem_block_end rd 1 mem_block_end rd 1
heap_mutex rd 1 heap_mutex MUTEX
heap_size rd 1 heap_size rd 1
heap_free rd 1 heap_free rd 1
heap_blocks rd 1 heap_blocks rd 1

View File

@ -119,7 +119,7 @@ struct DISK
; The structure is destroyed when the reference count decrements to zero: ; The structure is destroyed when the reference count decrements to zero:
; this usually occurs in 'disk_del', but can be delayed to the end of last ; this usually occurs in 'disk_del', but can be delayed to the end of last
; filesystem operation, if one is active. ; filesystem operation, if one is active.
.MediaLock dd ? .MediaLock MUTEX
; Lock to protect the MEDIA structure. See the description after ; Lock to protect the MEDIA structure. See the description after
; 'disk_list_mutex' for the locking strategy. ; 'disk_list_mutex' for the locking strategy.
; Fields of media object ; Fields of media object
@ -150,7 +150,7 @@ ends
; This structure represents one partition for the kernel. This is a base ; This structure represents one partition for the kernel. This is a base
; template, the actual contents after common fields is determined by the ; template, the actual contents after common fields is determined by the
; file system code for this partition. ; file system code for this partition.
struct PARTITION struct PARTITION
.FirstSector dq ? .FirstSector dq ?
; First sector of the partition. ; First sector of the partition.
@ -198,7 +198,7 @@ disk_list:
endg endg
uglobal uglobal
; This mutex guards all operations with the global list of DISK structures. ; This mutex guards all operations with the global list of DISK structures.
disk_list_mutex dd 0 disk_list_mutex MUTEX
; * There are two dependent objects, a disk and a media. In the simplest case ; * There are two dependent objects, a disk and a media. In the simplest case
; disk and media are both non-removable. However, in the general case both ; disk and media are both non-removable. However, in the general case both
; can be removed at any time, simultaneously or only media, this makes things ; can be removed at any time, simultaneously or only media, this makes things
@ -345,27 +345,24 @@ disk_add:
; 4. Initialize other fields of the DISK structure. ; 4. Initialize other fields of the DISK structure.
; Media is not inserted, initialized state of mutex is zero, ; Media is not inserted, initialized state of mutex is zero,
; reference counter is 1. ; reference counter is 1.
lea ecx, [ebx+DISK.MediaLock]
call mutex_init
xor eax, eax xor eax, eax
mov dword [ebx+DISK.MediaInserted], eax mov dword [ebx+DISK.MediaInserted], eax
mov [ebx+DISK.MediaLock], eax
inc eax inc eax
mov [ebx+DISK.RefCount], eax mov [ebx+DISK.RefCount], eax
; The DISK structure is initialized. ; The DISK structure is initialized.
; 5. Insert the new structure to the global list. ; 5. Insert the new structure to the global list.
xchg eax, ebx ; now eax = pointer to DISK
; 5a. Acquire the mutex. ; 5a. Acquire the mutex.
mov ebx, disk_list_mutex mov ecx, disk_list_mutex
call wait_mutex call mutex_lock
; 5b. Insert item to the tail of double-linked list. ; 5b. Insert item to the tail of double-linked list.
mov edx, disk_list mov edx, disk_list
mov ecx, [edx+DISK.Prev] list_add_tail ebx, edx ;ebx= new edx= list head
mov [eax+DISK.Prev], ecx
mov [eax+DISK.Next], edx
mov [edx+DISK.Prev], eax
mov [ecx+DISK.Next], eax
; 5c. Release the mutex. ; 5c. Release the mutex.
mov dword [ebx], 0 call mutex_unlock
; 6. Return with eax = pointer to DISK. ; 6. Return with eax = pointer to DISK.
xchg eax, ebx
jmp .nothing jmp .nothing
.free: .free:
; Memory allocation for DISK structure succeeded, but for disk name failed. ; Memory allocation for DISK structure succeeded, but for disk name failed.
@ -388,28 +385,28 @@ disk_add:
; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure. ; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure.
; Return value: none. ; Return value: none.
disk_del: disk_del:
push ebx esi ; save used registers to be stdcall push esi ; save used registers to be stdcall
; 1. Force media to be removed. If the media is already removed, the ; 1. Force media to be removed. If the media is already removed, the
; call does nothing. ; call does nothing.
mov esi, [esp+4+8] ; esi = handle of the disk mov esi, [esp+4+8] ; esi = handle of the disk
stdcall disk_media_changed, esi, 0 stdcall disk_media_changed, esi, 0
; 2. Delete the structure from the global list. ; 2. Delete the structure from the global list.
; 2a. Acquire the mutex. ; 2a. Acquire the mutex.
mov ebx, disk_list_mutex mov ecx, disk_list_mutex
call wait_mutex call mutex_lock
; 2b. Delete item from double-linked list. ; 2b. Delete item from double-linked list.
mov eax, [esi+DISK.Next] mov eax, [esi+DISK.Next]
mov edx, [esi+DISK.Prev] mov edx, [esi+DISK.Prev]
mov [eax+DISK.Prev], edx mov [eax+DISK.Prev], edx
mov [edx+DISK.Next], eax mov [edx+DISK.Next], eax
; 2c. Release the mutex. ; 2c. Release the mutex.
mov dword [ebx], 0 call mutex_unlock
; 3. The structure still has one reference created in disk_add. Remove this ; 3. The structure still has one reference created in disk_add. Remove this
; reference. If there are no other references, disk_dereference will free the ; reference. If there are no other references, disk_dereference will free the
; structure. ; structure.
call disk_dereference call disk_dereference
; 4. Return. ; 4. Return.
pop esi ebx ; restore used registers to be stdcall pop esi ; restore used registers to be stdcall
ret 4 ; purge 1 dword argument to be stdcall ret 4 ; purge 1 dword argument to be stdcall
; This is an internal function which removes a previously obtained reference ; This is an internal function which removes a previously obtained reference
@ -502,12 +499,12 @@ disk_media_changed:
jz .noremove jz .noremove
; We really need to remove the media. ; We really need to remove the media.
; 1b. Acquire mutex. ; 1b. Acquire mutex.
lea ebx, [esi+DISK.MediaLock] lea ecx, [esi+DISK.MediaLock]
call wait_mutex call mutex_lock
; 1c. Clear the flag. ; 1c. Clear the flag.
mov [esi+DISK.MediaInserted], 0 mov [esi+DISK.MediaInserted], 0
; 1d. Release mutex. ; 1d. Release mutex.
mov dword [ebx], 0 call mutex_unlock
; 1e. Remove the "lifetime" reference and possibly destroy the structure. ; 1e. Remove the "lifetime" reference and possibly destroy the structure.
call disk_media_dereference call disk_media_dereference
.noremove: .noremove:
@ -968,19 +965,19 @@ end virtual
dyndisk_handler: dyndisk_handler:
push ebx edi ; save registers used in file_system_lfn push ebx edi ; save registers used in file_system_lfn
; 1. Acquire the mutex. ; 1. Acquire the mutex.
mov ebx, disk_list_mutex mov ecx, disk_list_mutex
call wait_mutex call mutex_lock
; 2. Loop over the list of DISK structures. ; 2. Loop over the list of DISK structures.
; 2a. Initialize. ; 2a. Initialize.
mov ecx, disk_list mov ebx, disk_list
.scan: .scan:
; 2b. Get the next item. ; 2b. Get the next item.
mov ecx, [ecx+DISK.Next] mov ebx, [ebx+DISK.Next]
; 2c. Check whether the list is done. If so, go to 3. ; 2c. Check whether the list is done. If so, go to 3.
cmp ecx, disk_list cmp ebx, disk_list
jz .notfound jz .notfound
; 2d. Compare names. If names match, go to 5. ; 2d. Compare names. If names match, go to 5.
mov edi, [ecx+DISK.Name] mov edi, [ebx+DISK.Name]
push esi push esi
@@: @@:
; esi points to the name from fs operation; it is terminated by zero or slash. ; esi points to the name from fs operation; it is terminated by zero or slash.
@ -1005,7 +1002,7 @@ dyndisk_handler:
.notfound: .notfound:
; The loop is done and no name matches. ; The loop is done and no name matches.
; 3. Release the mutex. ; 3. Release the mutex.
mov dword [ebx], 0 call mutex_unlock
; 4. Return normally. ; 4. Return normally.
pop edi ebx ; restore registers used in file_system_lfn pop edi ebx ; restore registers used in file_system_lfn
ret ret
@ -1018,24 +1015,25 @@ dyndisk_handler:
jnz .wrongname jnz .wrongname
; We found the addressed DISK structure. ; We found the addressed DISK structure.
; 5. Reference the disk. ; 5. Reference the disk.
lock inc [ecx+DISK.RefCount] lock inc [ebx+DISK.RefCount]
; 6. Now we are sure that the DISK structure is not going to die at least ; 6. Now we are sure that the DISK structure is not going to die at least
; while we are working with it, so release the global mutex. ; while we are working with it, so release the global mutex.
mov dword [ebx], 0 call mutex_unlock
; 7. Acquire the mutex for media object. ; 7. Acquire the mutex for media object.
pop edi ; restore edi pop edi ; restore edi
lea ebx, [ecx+DISK.MediaLock] lea ecx, [ebx+DISK.MediaLock]
call wait_mutex call mutex_lock
; 8. Get the media object. If it is not NULL, reference it. ; 8. Get the media object. If it is not NULL, reference it.
xor edx, edx xor edx, edx
cmp [ecx+DISK.MediaInserted], dl cmp [ebx+DISK.MediaInserted], dl
jz @f jz @f
mov edx, ecx mov edx, ebx
inc [ecx+DISK.MediaRefCount] inc [ebx+DISK.MediaRefCount]
@@: @@:
; 9. Now we are sure that the media object, if it exists, is not going to die ; 9. Now we are sure that the media object, if it exists, is not going to die
; at least while we are working with it, so release the mutex for media object. ; at least while we are working with it, so release the mutex for media object.
mov dword [ebx], 0 call mutex_unlock
mov ecx, ebx
pop ebx eax ; restore ebx, pop return address pop ebx eax ; restore ebx, pop return address
; 10. Check whether the fs operation wants to enumerate partitions (go to 11) ; 10. Check whether the fs operation wants to enumerate partitions (go to 11)
; or work with some concrete partition (go to 12). ; or work with some concrete partition (go to 12).
@ -1152,24 +1150,25 @@ fs_dyndisk:
; if the driver does not support insert notifications and we are the only fs ; if the driver does not support insert notifications and we are the only fs
; operation with this disk, issue the fake insert notification; if media is ; operation with this disk, issue the fake insert notification; if media is
; still not inserted, 'disk_media_changed' will detect this and do nothing ; still not inserted, 'disk_media_changed' will detect this and do nothing
push ebx ;;; push ebx
lea ebx, [edx+DISK.MediaLock] lea ecx, [edx+DISK.MediaLock]
call wait_mutex call mutex_lock
cmp [edx+DISK.MediaRefCount], 1 cmp [edx+DISK.MediaRefCount], 1
jnz .noluck jnz .noluck
mov dword [ebx], 0 call mutex_unlock
push edx push edx
stdcall disk_media_changed, edx, 1 stdcall disk_media_changed, edx, 1
pop edx pop edx
call wait_mutex lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaInserted], 0 cmp [edx+DISK.MediaInserted], 0
jz .noluck jz .noluck
lock inc [edx+DISK.MediaRefCount] lock inc [edx+DISK.MediaRefCount]
mov dword [ebx], 0 call mutex_unlock
xor ecx, ecx xor ecx, ecx
jmp .main jmp .main
.noluck: .noluck:
mov dword [ebx], 0 call mutex_unlock
.deverror: .deverror:
mov dword [esp+32], ERROR_DEVICE mov dword [esp+32], ERROR_DEVICE
mov esi, edx mov esi, edx
@ -1185,11 +1184,11 @@ lock inc [edx+DISK.MediaRefCount]
; eax != 0 => buffer pointed to by edi contains name of item ; eax != 0 => buffer pointed to by edi contains name of item
dyndisk_enum_root: dyndisk_enum_root:
push ebx ; save register used in file_system_lfn push ebx ; save register used in file_system_lfn
mov ebx, disk_list_mutex ; it will be useful mov ecx, disk_list_mutex ; it will be useful
; 1. If this is the first call, acquire the mutex and initialize. ; 1. If this is the first call, acquire the mutex and initialize.
test eax, eax test eax, eax
jnz .notfirst jnz .notfirst
call wait_mutex call mutex_lock
mov eax, disk_list mov eax, disk_list
.notfirst: .notfirst:
; 2. Get next item. ; 2. Get next item.
@ -1211,7 +1210,7 @@ dyndisk_enum_root:
ret ret
.last: .last:
; 6. Release the mutex and return with eax = 0. ; 6. Release the mutex and return with eax = 0.
call mutex_unlock
xor eax, eax xor eax, eax
mov dword [ebx], eax
pop ebx ; restore register used in file_system_lfn pop ebx ; restore register used in file_system_lfn
ret ret

View File

@ -141,7 +141,7 @@ proc init_mem
mov [edx], eax mov [edx], eax
add edx, 4 add edx, 4
mov edi, [tmp_page_tabs] mov edi, [tmp_page_tabs]
jmp .map_kernel_heap ; new kernel fits to the first 4Mb - nothing to do with ".map_low" jmp .map_kernel_heap ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
.no_PSE: .no_PSE:
mov eax, PG_SW mov eax, PG_SW
@ -165,7 +165,7 @@ proc init_mem
mov eax, [tmp_page_tabs] mov eax, [tmp_page_tabs]
or eax, PG_SW or eax, PG_SW
mov edi, edx mov edi, edx
.map_kernel_tabs: .map_kernel_tabs:
stosd stosd
add eax, 0x1000 add eax, 0x1000
@ -266,7 +266,6 @@ proc init_page_map
add ebx, [pg_data.pagemap_size-OS_BASE] add ebx, [pg_data.pagemap_size-OS_BASE]
mov [page_end-OS_BASE], ebx mov [page_end-OS_BASE], ebx
mov [pg_data.pg_mutex-OS_BASE], 0
ret ret
endp endp
@ -331,7 +330,7 @@ init_BIOS32:
; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat ; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat
.BIOS32_not_found: .BIOS32_not_found:
.end: .end:
ret ret
align 4 align 4
proc test_cpu proc test_cpu

View File

@ -321,6 +321,12 @@ high_code:
mov eax, cr3 mov eax, cr3
mov cr3, eax ; flush TLB mov cr3, eax ; flush TLB
mov ecx, pg_data.mutex
call mutex_init
mov ecx, disk_list_mutex
call mutex_init
; SAVE REAL MODE VARIABLES ; SAVE REAL MODE VARIABLES
mov ax, [BOOT_VAR + 0x9031] mov ax, [BOOT_VAR + 0x9031]
mov [IDEContrRegsBaseAddr], ax mov [IDEContrRegsBaseAddr], ax

View File

@ -54,7 +54,7 @@ struct SOCKET
.SEG_LEN dd ? ; segment length .SEG_LEN dd ? ; segment length
.SEG_WND dd ? ; segment window .SEG_WND dd ? ; segment window
.wndsizeTimer dd ? ; window size timer .wndsizeTimer dd ? ; window size timer
.lock dd ? ; lock mutex .lock MUTEX ; lock mutex
.rxData dd ? ; receive data buffer here .rxData dd ? ; receive data buffer here
ends ends
@ -99,6 +99,11 @@ proc net_socket_alloc stdcall uses ebx ecx edx edi
rep stosd rep stosd
pop eax pop eax
mov ebx, eax
lea ecx, [eax+SOCKET.lock]
call mutex_init
mov eax, ebx
; add socket to the list by changing pointers ; add socket to the list by changing pointers
mov ebx, net_sockets mov ebx, net_sockets
push [ebx + SOCKET.NextPtr] push [ebx + SOCKET.NextPtr]
@ -703,10 +708,10 @@ proc socket_read stdcall
or eax, eax or eax, eax
jz .error jz .error
lea ebx, [eax + SOCKET.lock] mov ebx, eax
call wait_mutex lea ecx, [eax + SOCKET.lock]
call mutex_lock
mov ebx, eax
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax test eax, eax
jz .error_release jz .error_release
@ -727,15 +732,18 @@ proc socket_read stdcall
and ecx, 3 and ecx, 3
rep movsb rep movsb
mov [ebx + SOCKET.lock], 0 lea ecx, [ebx + SOCKET.lock]
mov ebx, eax mov ebx, eax
call mutex_unlock
mov eax, ebx
ret ret
.error_release: .error_release:
mov [ebx + SOCKET.lock], 0 lea ecx, [ebx + SOCKET.lock]
call mutex_unlock
.error: .error:
xor ebx, ebx xor ebx, ebx
xor eax, eax
ret ret
endp endp
@ -756,10 +764,11 @@ proc socket_read_packet stdcall
or eax, eax or eax, eax
jz .error jz .error
lea ebx, [eax + SOCKET.lock] mov ebx, eax
call wait_mutex
lea ecx, [eax + SOCKET.lock]
call mutex_lock
mov ebx, eax
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax ; if count of bytes is zero.. test eax, eax ; if count of bytes is zero..
jz .exit ; exit function (eax will be zero) jz .exit ; exit function (eax will be zero)
@ -789,8 +798,10 @@ proc socket_read_packet stdcall
rep movsb ; copy remaining bytes rep movsb ; copy remaining bytes
.exit: .exit:
mov [ebx + SOCKET.lock], 0 lea ecx, [ebx + SOCKET.lock]
ret ; at last, exit call mutex_unlock
mov eax, edx
ret ; at last, exit
.error: .error:
xor eax, eax xor eax, eax
@ -800,7 +811,9 @@ proc socket_read_packet stdcall
xor esi, esi xor esi, esi
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero)
call .start_copy call .start_copy
mov [ebx + SOCKET.lock], 0 lea ecx, [ebx + SOCKET.lock]
call mutex_unlock
mov eax, edx
ret ret
.start_copy: .start_copy:

View File

@ -697,7 +697,7 @@ endp
; ;
; Description ; Description
; Signals about network event to socket owner ; Signals about network event to socket owner
; This is a kernel function, called from TCP handler ; This is a kernel function, called from TCP handler
; ;
; Socket/TCB address in ebx ; Socket/TCB address in ebx
;*************************************************************************** ;***************************************************************************
@ -925,7 +925,7 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
test [edx + 20 + TCP_PACKET.Flags], TH_RST test [edx + 20 + TCP_PACKET.Flags], TH_RST
je @f je @f
mov [ebx + SOCKET.TCBState], TCB_CLOSED mov [ebx + SOCKET.TCBState], TCB_CLOSED
@@: @@:
call signal_network_event call signal_network_event
lea esi, [ebx + SOCKET.RCV_NXT] lea esi, [ebx + SOCKET.RCV_NXT]
mov eax, [esi] ; save original mov eax, [esi] ; save original
@ -963,12 +963,10 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
jmp .exit jmp .exit
.data: .data:
push ebx push ecx
add ebx, SOCKET.lock lea ecx, [ebx+SOCKET.lock]
call wait_mutex call mutex_lock
pop ebx
push ecx
push ebx push ebx
mov eax, [ebx + SOCKET.rxDataCount] mov eax, [ebx + SOCKET.rxDataCount]
add eax, ecx add eax, ecx
@ -986,7 +984,9 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
cld cld
rep movsb ; copy the data across rep movsb ; copy the data across
mov [ebx + SOCKET.lock], 0 ; release mutex
lea ecx,[ebx + SOCKET.lock]
call mutex_unlock
; flag an event to the application ; flag an event to the application
pop ebx pop ebx
@ -1031,9 +1031,10 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
.overflow: .overflow:
; no place in buffer ; no place in buffer
; so simply restore stack and exit ; so simply restore stack and exit
pop eax ecx lea ecx, [ebx + SOCKET.lock]
mov [ebx + SOCKET.lock], 0 call mutex_unlock
ret pop eax ecx
ret
endp endp