Subversion Repositories Kolibri OS

Rev

Rev 854 | Rev 864 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 serge 7
 
593 mikedld 8
$Revision: 859 $
9
 
10
 
164 serge 11
struc MEM_BLOCK
12
{  .next_block  dd ?
13
   .prev_block  dd ? ;+4
357 serge 14
   .list_fd     dd ? ;+8
15
   .list_bk     dd ? ;+12
164 serge 16
   .base        dd ? ;+16
17
   .size        dd ? ;+20
18
   .flags       dd ? ;+24
19
   .handle      dd ? ;+28
20
}
21
 
357 serge 22
MEM_LIST_OFFSET equ  8
164 serge 23
FREE_BLOCK      equ  4
24
USED_BLOCK      equ  8
546 diamond 25
DONT_FREE_BLOCK equ  10h
164 serge 26
 
27
virtual at 0
28
  MEM_BLOCK MEM_BLOCK
29
end virtual
30
 
31
MEM_BLOCK_SIZE equ 8*4
32
 
33
block_next   equ MEM_BLOCK.next_block
34
block_prev   equ MEM_BLOCK.prev_block
357 serge 35
list_fd      equ MEM_BLOCK.list_fd
36
list_bk      equ MEM_BLOCK.list_bk
164 serge 37
block_base   equ MEM_BLOCK.base
38
block_size   equ MEM_BLOCK.size
39
block_flags  equ MEM_BLOCK.flags
40
 
41
 
42
align 4
321 diamond 43
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
279 serge 44
 
164 serge 45
           ret
46
endp
47
 
48
align 4
49
proc kernel_alloc stdcall, size:dword
50
           locals
51
             lin_addr    dd ?
52
             pages_count dd ?
53
           endl
54
 
662 serge 55
           push ebx
56
           push edi
57
 
164 serge 58
           mov eax, [size]
206 serge 59
           add eax, 4095
60
           and eax, not 4095;
164 serge 61
           mov [size], eax
859 serge 62
           test eax, eax
357 serge 63
           jz .err
859 serge 64
 
164 serge 65
           mov ebx, eax
66
           shr ebx, 12
67
           mov [pages_count], ebx
68
 
69
           stdcall alloc_kernel_space, eax
357 serge 70
           test eax, eax
71
           jz .err
164 serge 72
           mov [lin_addr], eax
73
 
74
           mov ecx, [pages_count]
75
           mov edx, eax
76
           mov ebx, ecx
77
 
78
           shr ecx, 3
79
           jz .next
80
 
81
           and ebx, not 7
82
           push ebx
854 serge 83
           stdcall _alloc_pages, ebx
164 serge 84
           pop ecx                   ; yes ecx!!!
843 serge 85
           test eax, eax
357 serge 86
           jz .err
164 serge 87
 
88
           mov edi, eax
89
           mov edx, [lin_addr]
90
@@:
91
           stdcall map_page,edx,edi,dword PG_SW
92
           add edx, 0x1000
93
           add edi, 0x1000
94
           dec ecx
95
           jnz @B
96
.next:
97
           mov ecx, [pages_count]
98
           and ecx, 7
99
           jz .end
357 serge 100
@@:
101
           push ecx
854 serge 102
           call _alloc_page
164 serge 103
           pop ecx
104
           test eax, eax
357 serge 105
           jz .err
164 serge 106
 
107
           stdcall map_page,edx,eax,dword PG_SW
108
           add edx, 0x1000
109
           dec ecx
110
           jnz @B
111
.end:
112
           mov eax, [lin_addr]
662 serge 113
           pop edi
114
           pop ebx
164 serge 115
           ret
357 serge 116
.err:
164 serge 117
           xor eax, eax
662 serge 118
           pop edi
119
           pop ebx
164 serge 120
           ret
121
endp
122
 
123
align 4
124
proc kernel_free stdcall, base:dword
125
 
279 serge 126
           ret
164 serge 127
endp
128
 
837 serge 129
 
130
 
164 serge 131
restore block_next
132
restore block_prev
133
restore block_list
134
restore block_base
135
restore block_size
136
restore block_flags
137
 
138
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
139
 
188 serge 140
HEAP_TOP  equ 0x5FC00000
141
 
164 serge 142
align 4
188 serge 143
proc init_heap
164 serge 144
 
465 serge 145
           mov ebx,[current_slot]
146
           mov eax, [ebx+APPDATA.heap_top]
172 serge 147
           test eax, eax
148
           jz @F
465 serge 149
           sub eax,[ebx+APPDATA.heap_base]
172 serge 150
           sub eax, 4096
151
           ret
152
@@:
465 serge 153
           mov esi, [ebx+APPDATA.mem_size]
188 serge 154
           add esi, 4095
155
           and esi, not 4095
465 serge 156
           mov [ebx+APPDATA.mem_size], esi
188 serge 157
           mov eax, HEAP_TOP
465 serge 158
           mov [ebx+APPDATA.heap_base], esi
159
           mov [ebx+APPDATA.heap_top], eax
164 serge 160
 
188 serge 161
           sub eax, esi
162
           shr esi, 10
163
           mov ecx, eax
164 serge 164
           sub eax, 4096
188 serge 165
           or ecx, FREE_BLOCK
365 serge 166
           mov [page_tabs+esi], ecx
164 serge 167
           ret
168
endp
169
 
170
align 4
171
proc user_alloc stdcall, alloc_size:dword
172
 
662 serge 173
           push ebx
174
           push esi
175
           push edi
176
 
164 serge 177
           mov ecx, [alloc_size]
178
           add ecx, (4095+4096)
179
           and ecx, not 4095
180
 
465 serge 181
           mov ebx, [current_slot]
182
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
183
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
164 serge 184
l_0:
185
           cmp esi, edi
186
           jae m_exit
187
 
188
           mov ebx, esi
189
           shr ebx, 12
365 serge 190
           mov eax, [page_tabs+ebx*4]
620 diamond 191
           test al, FREE_BLOCK
164 serge 192
           jz test_used
193
           and eax, 0xFFFFF000
194
           cmp eax, ecx    ;alloc_size
195
           jb  m_next
270 diamond 196
	   jz  @f
164 serge 197
 
620 diamond 198
           lea edx, [esi+ecx]
199
           sub eax, ecx
200
           or al, FREE_BLOCK
164 serge 201
           shr edx, 12
365 serge 202
           mov [page_tabs+edx*4], eax
294 diamond 203
@@:
164 serge 204
           or ecx, USED_BLOCK
365 serge 205
           mov [page_tabs+ebx*4], ecx
164 serge 206
           shr ecx, 12
620 diamond 207
           inc ebx
164 serge 208
           dec ecx
620 diamond 209
           jz  .no
164 serge 210
@@:
365 serge 211
           mov dword [page_tabs+ebx*4], 2
164 serge 212
           inc ebx
213
           dec ecx
214
           jnz @B
620 diamond 215
.no:
164 serge 216
 
465 serge 217
           mov     edx, [current_slot]
218
           mov     ebx, [alloc_size]
219
           add     ebx, 0xFFF
220
           and     ebx, not 0xFFF
221
           add     ebx, [edx+APPDATA.mem_size]
222
           call    update_mem_size
294 diamond 223
 
620 diamond 224
           lea eax, [esi+4096]
662 serge 225
 
226
           pop edi
227
           pop esi
228
           pop ebx
164 serge 229
           ret
230
test_used:
620 diamond 231
           test al, USED_BLOCK
164 serge 232
           jz m_exit
233
 
234
           and eax, 0xFFFFF000
620 diamond 235
m_next:
164 serge 236
           add esi, eax
237
           jmp l_0
238
m_exit:
239
           xor eax, eax
662 serge 240
           pop edi
241
           pop esi
242
           pop ebx
164 serge 243
           ret
244
endp
245
 
246
align 4
247
proc user_free stdcall, base:dword
248
 
662 serge 249
           push esi
250
 
164 serge 251
           mov esi, [base]
252
           test esi, esi
253
           jz .exit
254
 
662 serge 255
           push ebx
256
 
294 diamond 257
           xor ebx, ebx
164 serge 258
           shr esi, 12
620 diamond 259
           mov eax, [page_tabs+(esi-1)*4]
546 diamond 260
           test al, USED_BLOCK
620 diamond 261
           jz .cantfree
546 diamond 262
           test al, DONT_FREE_BLOCK
263
           jnz .cantfree
164 serge 264
 
265
           and eax, not 4095
266
           mov ecx, eax
620 diamond 267
           or al, FREE_BLOCK
268
           mov [page_tabs+(esi-1)*4], eax
164 serge 269
           sub ecx, 4096
620 diamond 270
           mov ebx, ecx
164 serge 271
           shr ecx, 12
620 diamond 272
           jz .released
164 serge 273
.release:
188 serge 274
           xor eax, eax
365 serge 275
           xchg eax, [page_tabs+esi*4]
620 diamond 276
           test al, 1
188 serge 277
           jz @F
164 serge 278
           call free_page
448 diamond 279
           mov eax, esi
280
           shl eax, 12
281
           invlpg [eax]
188 serge 282
@@:
164 serge 283
           inc esi
284
           dec ecx
285
           jnz .release
620 diamond 286
.released:
662 serge 287
           push edi
288
 
465 serge 289
           mov edx, [current_slot]
290
           mov esi, dword [edx+APPDATA.heap_base]
291
           mov edi, dword [edx+APPDATA.heap_top]
292
           sub ebx, [edx+APPDATA.mem_size]
294 diamond 293
           neg ebx
294
           call update_mem_size
448 diamond 295
           call user_normalize
662 serge 296
           pop edi
297
           pop ebx
298
           pop esi
448 diamond 299
           ret
300
.exit:
301
           xor eax, eax
302
           inc eax
662 serge 303
           pop esi
448 diamond 304
           ret
546 diamond 305
.cantfree:
306
           xor eax, eax
662 serge 307
           pop ebx
308
           pop esi
546 diamond 309
           ret
448 diamond 310
endp
311
 
312
user_normalize:
313
; in: esi=heap_base, edi=heap_top
314
; out: eax=0 <=> OK
315
; destroys: ebx,edx,esi,edi
164 serge 316
           shr esi, 12
317
           shr edi, 12
318
@@:
365 serge 319
           mov eax, [page_tabs+esi*4]
620 diamond 320
           test al, USED_BLOCK
164 serge 321
           jz .test_free
322
           shr eax, 12
323
           add esi, eax
324
           jmp @B
325
.test_free:
620 diamond 326
           test al, FREE_BLOCK
164 serge 327
           jz .err
328
           mov edx, eax
329
           shr edx, 12
330
           add edx, esi
331
           cmp edx, edi
332
           jae .exit
333
 
365 serge 334
           mov ebx, [page_tabs+edx*4]
620 diamond 335
           test bl, USED_BLOCK
164 serge 336
           jz .next_free
337
 
338
           shr ebx, 12
339
           add edx, ebx
340
           mov esi, edx
341
           jmp @B
342
.next_free:
620 diamond 343
           test bl, FREE_BLOCK
164 serge 344
           jz .err
365 serge 345
           and dword [page_tabs+edx*4], 0
164 serge 346
           add eax, ebx
347
           and eax, not 4095
348
           or eax, FREE_BLOCK
365 serge 349
           mov [page_tabs+esi*4], eax
164 serge 350
           jmp @B
351
.exit:
352
           xor eax, eax
353
           inc eax
354
           ret
355
.err:
356
           xor eax, eax
357
           ret
358
 
448 diamond 359
user_realloc:
360
; in: eax = pointer, ebx = new size
361
; out: eax = new pointer or NULL
362
        test    eax, eax
363
        jnz     @f
364
; realloc(NULL,sz) - same as malloc(sz)
365
        push    ebx
366
        call    user_alloc
367
        ret
368
@@:
369
        push    ecx edx
465 serge 370
        lea     ecx, [eax - 0x1000]
448 diamond 371
        shr     ecx, 12
372
        mov     edx, [page_tabs+ecx*4]
620 diamond 373
        test    dl, USED_BLOCK
448 diamond 374
        jnz     @f
375
; attempt to realloc invalid pointer
376
.ret0:
377
        pop     edx ecx
378
        xor     eax, eax
379
        ret
380
@@:
620 diamond 381
        test    dl, DONT_FREE_BLOCK
546 diamond 382
        jnz     .ret0
448 diamond 383
        add     ebx, 0x1FFF
384
        shr     edx, 12
385
        shr     ebx, 12
386
; edx = allocated size, ebx = new size
387
        add     edx, ecx
388
        add     ebx, ecx
389
        cmp     edx, ebx
390
        jb      .realloc_add
391
; release part of allocated memory
392
.loop:
393
        cmp     edx, ebx
394
        jz      .release_done
395
        dec     edx
396
        xor     eax, eax
397
        xchg    eax, [page_tabs+edx*4]
398
        test    al, 1
399
        jz      .loop
400
        call    free_page
401
        mov     eax, edx
402
        shl     eax, 12
403
        invlpg  [eax]
404
        jmp     .loop
405
.release_done:
406
        sub     ebx, ecx
407
        cmp     ebx, 1
408
        jnz     .nofreeall
409
        mov     eax, [page_tabs+ecx*4]
410
        and     eax, not 0xFFF
465 serge 411
        mov     edx, [current_slot]
412
        mov     ebx, [APPDATA.mem_size+edx]
448 diamond 413
        sub     ebx, eax
414
        add     ebx, 0x1000
415
        or      al, FREE_BLOCK
416
        mov     [page_tabs+ecx*4], eax
417
        push    esi edi
465 serge 418
        mov     esi, [APPDATA.heap_base+edx]
419
        mov     edi, [APPDATA.heap_top+edx]
448 diamond 420
        call    update_mem_size
421
        call    user_normalize
422
        pop     edi esi
423
        jmp     .ret0   ; all freed
424
.nofreeall:
425
        sub     edx, ecx
426
        shl     ebx, 12
427
        or      ebx, USED_BLOCK
428
        xchg    [page_tabs+ecx*4], ebx
429
        shr     ebx, 12
430
        sub     ebx, edx
431
        push    ebx ecx edx
465 serge 432
        mov     edx, [current_slot]
448 diamond 433
        shl     ebx, 12
465 serge 434
        sub     ebx, [APPDATA.mem_size+edx]
448 diamond 435
        neg     ebx
436
        call    update_mem_size
437
        pop     edx ecx ebx
465 serge 438
        lea     eax, [ecx+1]
448 diamond 439
        shl     eax, 12
440
        push    eax
823 diamond 441
        add     ecx, edx
442
        lea     edx, [ecx+ebx]
448 diamond 443
        shl     ebx, 12
444
        jz      .ret
445
        push    esi
465 serge 446
        mov     esi, [current_slot]
447
        mov     esi, [APPDATA.heap_top+esi]
448 diamond 448
        shr     esi, 12
449
@@:
450
        cmp     edx, esi
451
        jae     .merge_done
452
        mov     eax, [page_tabs+edx*4]
453
        test    al, USED_BLOCK
823 diamond 454
        jnz     .merge_done
448 diamond 455
        and     dword [page_tabs+edx*4], 0
823 diamond 456
        shr     eax, 12
457
        add     edx, eax
458
        shl     eax, 12
448 diamond 459
        add     ebx, eax
460
        jmp     @b
461
.merge_done:
462
        pop     esi
463
        or      ebx, FREE_BLOCK
464
        mov     [page_tabs+ecx*4], ebx
465
.ret:
466
        pop     eax edx ecx
467
        ret
468
.realloc_add:
469
; get some additional memory
465 serge 470
        mov     eax, [current_slot]
471
        mov     eax, [APPDATA.heap_top+eax]
448 diamond 472
        shr     eax, 12
473
        cmp     edx, eax
474
        jae     .cant_inplace
475
        mov     eax, [page_tabs+edx*4]
620 diamond 476
        test    al, FREE_BLOCK
477
        jz      .cant_inplace
448 diamond 478
        shr     eax, 12
479
        add     eax, edx
620 diamond 480
        sub     eax, ebx
448 diamond 481
        jb      .cant_inplace
482
        jz      @f
483
        shl     eax, 12
484
        or      al, FREE_BLOCK
485
        mov     [page_tabs+ebx*4], eax
486
@@:
487
        mov     eax, ebx
488
        sub     eax, ecx
489
        shl     eax, 12
490
        or      al, USED_BLOCK
491
        mov     [page_tabs+ecx*4], eax
465 serge 492
        lea     eax, [ecx+1]
448 diamond 493
        shl     eax, 12
494
        push    eax
495
        push    edi
496
        lea     edi, [page_tabs+edx*4]
497
        mov     eax, 2
498
        sub     ebx, edx
499
        mov     ecx, ebx
500
        cld
501
        rep     stosd
502
        pop     edi
465 serge 503
        mov     edx, [current_slot]
448 diamond 504
        shl     ebx, 12
465 serge 505
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 506
        call    update_mem_size
507
        pop     eax edx ecx
508
        ret
509
.cant_inplace:
510
        push    esi edi
465 serge 511
        mov     eax, [current_slot]
512
        mov     esi, [APPDATA.heap_base+eax]
513
        mov     edi, [APPDATA.heap_top+eax]
448 diamond 514
        shr     esi, 12
515
        shr     edi, 12
516
        sub     ebx, ecx
517
.find_place:
518
        cmp     esi, edi
519
        jae     .place_not_found
520
        mov     eax, [page_tabs+esi*4]
521
        test    al, FREE_BLOCK
522
        jz      .next_place
523
        shr     eax, 12
524
        cmp     eax, ebx
525
        jae     .place_found
526
        add     esi, eax
527
        jmp     .find_place
528
.next_place:
529
        shr     eax, 12
530
        add     esi, eax
531
        jmp     .find_place
532
.place_not_found:
533
        pop     edi esi
534
        jmp     .ret0
535
.place_found:
536
        sub     eax, ebx
537
        jz      @f
538
        push    esi
620 diamond 539
        add     esi, ebx
448 diamond 540
        shl     eax, 12
541
        or      al, FREE_BLOCK
542
        mov     [page_tabs+esi*4], eax
543
        pop     esi
544
@@:
545
        mov     eax, ebx
546
        shl     eax, 12
547
        or      al, USED_BLOCK
548
        mov     [page_tabs+esi*4], eax
549
        inc     esi
550
        mov     eax, esi
551
        shl     eax, 12
552
        push    eax
553
        mov     eax, [page_tabs+ecx*4]
554
        and     eax, not 0xFFF
555
        or      al, FREE_BLOCK
556
        sub     edx, ecx
557
        mov     [page_tabs+ecx*4], eax
558
        inc     ecx
620 diamond 559
        dec     ebx
560
        dec     edx
561
        jz      .no
448 diamond 562
@@:
563
        xor     eax, eax
564
        xchg    eax, [page_tabs+ecx*4]
565
        mov     [page_tabs+esi*4], eax
566
	mov     eax, ecx
567
	shl     eax, 12
568
	invlpg  [eax]
620 diamond 569
        inc     esi
448 diamond 570
        inc     ecx
571
        dec     ebx
572
        dec     edx
573
        jnz     @b
620 diamond 574
.no:
448 diamond 575
        push    ebx
465 serge 576
        mov     edx, [current_slot]
448 diamond 577
        shl     ebx, 12
465 serge 578
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 579
        call    update_mem_size
580
        pop     ebx
581
@@:
582
        mov     dword [page_tabs+esi*4], 2
583
        inc     esi
584
        dec     ebx
585
        jnz     @b
586
        pop     eax edi esi edx ecx
587
        ret
588
 
278 serge 589
if 0
164 serge 590
align 4
591
proc alloc_dll
592
           pushf
593
           cli
594
           bsf eax, [dll_map]
595
           jnz .find
596
           popf
597
           xor eax, eax
598
           ret
599
.find:
600
           btr [dll_map], eax
601
           popf
602
           shl eax, 5
603
           add eax, dll_tab
604
           ret
605
endp
606
 
607
align 4
608
proc alloc_service
609
           pushf
610
           cli
611
           bsf eax, [srv_map]
612
           jnz .find
613
           popf
614
           xor eax, eax
615
           ret
214 serge 616
.find:
617
           btr [srv_map], eax
164 serge 618
           popf
214 serge 619
           shl eax,0x02
620
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
164 serge 621
           ret
622
endp
278 serge 623
 
624
end if