Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
983 diamond 3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 serge 7
 
593 mikedld 8
$Revision: 983 $
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
macro calc_index op
42
{          shr op, 12
43
           dec op
44
           cmp op, 63
45
           jna @f
46
           mov op, 63
47
@@:
48
}
49
 
50
macro remove_from_list op
357 serge 51
{          mov edx, [op+list_fd]
52
           mov ecx, [op+list_bk]
164 serge 53
           test edx, edx
54
           jz @f
357 serge 55
           mov [edx+list_bk], ecx
164 serge 56
@@:
57
           test ecx, ecx
58
           jz @f
357 serge 59
           mov [ecx+list_fd], edx
164 serge 60
@@:
357 serge 61
           mov [op+list_fd],0
62
           mov [op+list_bk],0
164 serge 63
}
64
 
65
macro remove_from_free op
66
{
67
           remove_from_list op
68
 
69
           mov eax, [op+block_size]
70
           calc_index eax
71
           cmp [mem_block_list+eax*4], op
72
           jne @f
73
           mov [mem_block_list+eax*4], edx
74
@@:
75
           cmp [mem_block_list+eax*4], 0
76
           jne @f
77
           btr [mem_block_mask], eax
78
@@:
79
}
80
 
81
macro remove_from_used op
82
{
357 serge 83
           mov edx, [op+list_fd]
84
           mov ecx, [op+list_bk]
85
           mov [edx+list_bk], ecx
86
           mov [ecx+list_fd], edx
87
           mov [op+list_fd], 0
88
           mov [op+list_bk], 0
164 serge 89
}
90
 
91
align 4
92
proc init_kernel_heap
93
 
94
           mov ecx, 64/4
95
           mov edi, mem_block_list
96
           xor eax, eax
97
           cld
98
           rep stosd
99
 
100
           mov ecx, 512/4
101
           mov edi, mem_block_map
102
           not eax
103
           rep stosd
104
 
105
           mov [mem_block_start], mem_block_map
106
           mov [mem_block_end], mem_block_map+512
107
           mov [mem_block_arr], HEAP_BASE
108
 
357 serge 109
           mov eax, mem_used.fd-MEM_LIST_OFFSET
110
           mov [mem_used.fd], eax
111
           mov [mem_used.bk], eax
112
 
164 serge 113
           stdcall alloc_pages, dword 32
114
           mov ecx, 32
115
           mov edx, eax
116
           mov edi, HEAP_BASE
117
.l1:
118
           stdcall map_page,edi,edx,PG_SW
119
           add edi, 0x1000
120
           add edx, 0x1000
121
           dec ecx
122
           jnz .l1
123
 
124
           mov edi, HEAP_BASE
357 serge 125
           mov ebx, HEAP_BASE+MEM_BLOCK_SIZE
164 serge 126
           xor eax, eax
127
           mov [edi+block_next], ebx
128
           mov [edi+block_prev], eax
357 serge 129
           mov [edi+list_fd], eax
130
           mov [edi+list_bk], eax
164 serge 131
           mov [edi+block_base], HEAP_BASE
132
           mov [edi+block_size], 4096*MEM_BLOCK_SIZE
133
           mov [edi+block_flags], USED_BLOCK
134
 
135
           mov [ebx+block_next], eax
136
           mov [ebx+block_prev], eax
357 serge 137
           mov [ebx+list_fd], eax
138
           mov [ebx+list_bk], eax
164 serge 139
           mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
140
 
141
           mov ecx, [MEM_AMOUNT]
793 serge 142
           sub ecx, (HEAP_BASE - OS_BASE + 4096*MEM_BLOCK_SIZE)
170 serge 143
           mov [heap_size], ecx
144
           mov [heap_free], ecx
164 serge 145
           mov [ebx+block_size], ecx
146
           mov [ebx+block_flags], FREE_BLOCK
147
 
148
           mov [mem_block_mask], eax
149
           mov [mem_block_mask+4],0x80000000
150
 
151
           mov [mem_block_list+63*4], ebx
152
           mov byte [mem_block_map], 0xFC
279 serge 153
           and [heap_mutex], 0
170 serge 154
           mov [heap_blocks], 4095
155
           mov [free_blocks], 4095
164 serge 156
           ret
157
endp
158
 
369 serge 159
; param
160
;  eax= required size
161
;
162
; retval
163
;  edi= memory block descriptor
164
;  ebx= descriptor index
165
 
164 serge 166
align 4
819 serge 167
get_small_block:
164 serge 168
           mov ecx, eax
369 serge 169
           shr ecx, 12
170
           dec ecx
171
           cmp ecx, 63
172
           jle .get_index
173
           mov ecx, 63
174
.get_index:
175
           lea esi, [mem_block_mask]
164 serge 176
           xor ebx, ebx
369 serge 177
           or edx, -1
164 serge 178
 
179
           cmp ecx, 32
180
           jb .bit_test
181
 
182
           sub ecx, 32
183
           add ebx, 32
184
           add esi, 4
185
.bit_test:
186
           shl edx, cl
369 serge 187
           and edx, [esi]
188
.find:
189
           bsf edi, edx
164 serge 190
           jz .high_mask
369 serge 191
           add ebx, edi
192
           mov edi, [mem_block_list+ebx*4]
193
.check_size:
194
           cmp eax, [edi+block_size]
195
           ja .next
164 serge 196
           ret
197
 
198
.high_mask:
199
           add esi, 4
369 serge 200
           cmp esi, mem_block_mask+8
201
           jae .err
164 serge 202
           add ebx, 32
369 serge 203
           mov edx, [esi]
204
           jmp .find
205
.next:
206
           mov edi, [edi+list_fd]
207
           test edi, edi
208
           jnz .check_size
209
.err:
210
           xor edi, edi
164 serge 211
           ret
212
 
213
align 4
819 serge 214
alloc_mem_block:
164 serge 215
 
216
           mov ebx, [mem_block_start]
217
           mov ecx, [mem_block_end]
218
.l1:
219
           bsf eax,[ebx];
220
           jnz found
221
           add ebx,4
222
           cmp ebx, ecx
223
           jb .l1
224
           xor eax,eax
225
           ret
226
 
227
found:
228
           btr [ebx], eax
229
           mov [mem_block_start],ebx
230
           sub ebx, mem_block_map
254 serge 231
           lea eax,[eax+ebx*8]
164 serge 232
           shl eax, 5
233
           add eax, [mem_block_arr]
170 serge 234
           dec [free_blocks]
164 serge 235
           ret
819 serge 236
align 4
237
free_mem_block:
357 serge 238
           mov dword [eax], 0
239
           mov dword [eax+4], 0
240
           mov dword [eax+8], 0
241
           mov dword [eax+12], 0
242
           mov dword [eax+16], 0
243
;           mov dword [eax+20], 0
244
           mov dword [eax+24], 0
245
           mov dword [eax+28], 0
246
 
164 serge 247
           sub eax, [mem_block_arr]
248
           shr eax, 5
249
 
250
           mov ebx, mem_block_map
251
           bts [ebx], eax
170 serge 252
           inc [free_blocks]
164 serge 253
           shr eax, 3
254
           and eax, not 3
255
           add eax, ebx
256
           cmp [mem_block_start], eax
257
           ja @f
258
           ret
259
@@:
260
           mov [mem_block_start], eax
261
	   ret
262
.err:
263
           xor eax, eax
264
	   ret
265
 
266
align 4
267
proc alloc_kernel_space stdcall, size:dword
268
           local block_ind:DWORD
269
 
660 serge 270
           push ebx
271
           push esi
272
           push edi
273
 
164 serge 274
           mov eax, [size]
206 serge 275
           add eax, 4095
276
           and eax, not 4095
164 serge 277
           mov [size], eax
279 serge 278
 
279
           mov ebx, heap_mutex
280
           call wait_mutex    ;ebx
281
 
170 serge 282
           cmp eax, [heap_free]
283
           ja .error
164 serge 284
 
819 serge 285
           call get_small_block ; eax
369 serge 286
           test edi, edi
164 serge 287
           jz .error
288
 
289
           cmp [edi+block_flags], FREE_BLOCK
290
           jne .error
291
 
292
           mov [block_ind], ebx   ;index of allocated block
293
 
294
           mov eax, [edi+block_size]
295
           cmp eax, [size]
296
           je .m_eq_size
297
 
298
           call alloc_mem_block
299
           and eax, eax
300
           jz .error
301
 
302
           mov esi, eax           ;esi - splitted block
303
 
304
           mov [esi+block_next], edi
305
           mov eax, [edi+block_prev]
306
           mov [esi+block_prev], eax
307
           mov [edi+block_prev], esi
357 serge 308
           mov [esi+list_fd], 0
309
           mov [esi+list_bk], 0
164 serge 310
           and eax, eax
311
           jz @f
312
           mov [eax+block_next], esi
313
@@:
314
           mov ebx, [edi+block_base]
315
           mov [esi+block_base], ebx
316
           mov edx, [size]
317
           mov [esi+block_size], edx
318
           add [edi+block_base], edx
319
           sub [edi+block_size], edx
320
 
321
           mov eax, [edi+block_size]
322
           shr eax, 12
323
           sub eax, 1
324
           cmp eax, 63
325
           jna @f
326
           mov eax, 63
327
@@:
328
           cmp eax, [block_ind]
329
           je .m_eq_ind
330
 
192 serge 331
           remove_from_list edi
164 serge 332
 
333
           mov ecx, [block_ind]
211 serge 334
           mov [mem_block_list+ecx*4], edx
164 serge 335
 
211 serge 336
           test edx, edx
164 serge 337
           jnz @f
338
           btr [mem_block_mask], ecx
339
@@:
340
           mov edx, [mem_block_list+eax*4]
357 serge 341
           mov [edi+list_fd], edx
164 serge 342
           test edx, edx
343
           jz @f
357 serge 344
           mov [edx+list_bk], edi
164 serge 345
@@:
346
           mov [mem_block_list+eax*4], edi
347
           bts [mem_block_mask], eax
348
.m_eq_ind:
357 serge 349
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
350
           mov edx, [ecx+list_fd]
351
           mov [esi+list_fd], edx
352
           mov [esi+list_bk], ecx
353
           mov [ecx+list_fd], esi
354
           mov [edx+list_bk], esi
355
 
164 serge 356
           mov [esi+block_flags], USED_BLOCK
357
           mov eax, [esi+block_base]
170 serge 358
           mov ebx, [size]
359
           sub [heap_free], ebx
279 serge 360
           and [heap_mutex], 0
660 serge 361
           pop edi
362
           pop esi
363
           pop ebx
164 serge 364
           ret
365
.m_eq_size:
366
           remove_from_list edi
192 serge 367
           mov [mem_block_list+ebx*4], edx
164 serge 368
           and edx, edx
369
           jnz @f
192 serge 370
           btr [mem_block_mask], ebx
164 serge 371
@@:
357 serge 372
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
373
           mov edx, [ecx+list_fd]
374
           mov [edi+list_fd], edx
375
           mov [edi+list_bk], ecx
376
           mov [ecx+list_fd], edi
377
           mov [edx+list_bk], edi
378
 
164 serge 379
           mov [edi+block_flags], USED_BLOCK
380
           mov eax, [edi+block_base]
170 serge 381
           mov ebx, [size]
382
           sub [heap_free], ebx
279 serge 383
           and [heap_mutex], 0
660 serge 384
           pop edi
385
           pop esi
386
           pop ebx
164 serge 387
           ret
388
.error:
389
           xor eax, eax
279 serge 390
           mov [heap_mutex], eax
660 serge 391
           pop edi
392
           pop esi
393
           pop ebx
164 serge 394
           ret
395
endp
396
 
397
align 4
321 diamond 398
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
660 serge 399
           push ebx
400
           push esi
401
           push edi
279 serge 402
           mov ebx, heap_mutex
403
           call wait_mutex    ;ebx
404
 
164 serge 405
           mov eax, [base]
357 serge 406
           mov esi, [mem_used.fd]
164 serge 407
@@:
357 serge 408
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
409
           je .fail
164 serge 410
 
411
           cmp [esi+block_base], eax
412
           je .found
357 serge 413
           mov esi, [esi+list_fd]
164 serge 414
           jmp @b
415
.found:
416
           cmp [esi+block_flags], USED_BLOCK
417
           jne .fail
418
 
170 serge 419
           mov eax, [esi+block_size]
420
           add [heap_free], eax
421
 
164 serge 422
           mov edi, [esi+block_next]
423
           test edi, edi
424
           jz .prev
425
 
426
           cmp [edi+block_flags], FREE_BLOCK
427
           jne .prev
428
 
429
           remove_from_free edi
430
 
431
           mov edx, [edi+block_next]
432
           mov [esi+block_next], edx
433
           test edx, edx
434
           jz @f
435
 
436
           mov [edx+block_prev], esi
437
@@:
438
           mov ecx, [edi+block_size]
439
           add [esi+block_size], ecx
440
 
441
           mov eax, edi
442
           call free_mem_block
443
.prev:
444
           mov edi, [esi+block_prev]
445
           test edi, edi
446
           jz .insert
447
 
448
           cmp [edi+block_flags], FREE_BLOCK
449
           jne .insert
450
 
451
           remove_from_used esi
452
 
453
           mov edx, [esi+block_next]
454
           mov [edi+block_next], edx
455
           test edx, edx
456
           jz @f
457
           mov [edx+block_prev], edi
458
@@:
459
           mov eax, esi
460
           call free_mem_block
461
 
462
           mov ecx, [edi+block_size]
463
           mov eax, [esi+block_size]
464
           add eax, ecx
465
           mov [edi+block_size], eax
466
 
467
           calc_index eax
468
           calc_index ecx
469
           cmp eax, ecx
470
           je .m_eq
471
 
472
           push ecx
473
           remove_from_list edi
474
           pop ecx
475
 
476
           cmp [mem_block_list+ecx*4], edi
477
           jne @f
478
           mov [mem_block_list+ecx*4], edx
479
@@:
480
           cmp [mem_block_list+ecx*4], 0
481
           jne @f
482
           btr [mem_block_mask], ecx
483
@@:
484
           mov esi, [mem_block_list+eax*4]
485
           mov [mem_block_list+eax*4], edi
357 serge 486
           mov [edi+list_fd], esi
164 serge 487
           test esi, esi
488
           jz @f
357 serge 489
           mov [esi+list_bk], edi
164 serge 490
@@:
491
           bts [mem_block_mask], eax
492
.m_eq:
493
           xor eax, eax
279 serge 494
           mov [heap_mutex], eax
321 diamond 495
           dec eax
660 serge 496
           pop edi
497
           pop esi
498
           pop ebx
164 serge 499
           ret
500
.insert:
501
           remove_from_used esi
502
 
503
           mov eax, [esi+block_size]
504
           calc_index eax
505
 
506
           mov edi, [mem_block_list+eax*4]
507
           mov [mem_block_list+eax*4], esi
357 serge 508
           mov [esi+list_fd], edi
164 serge 509
           test edi, edi
510
           jz @f
357 serge 511
           mov [edi+list_bk], esi
164 serge 512
@@:
513
           bts [mem_block_mask], eax
514
           mov [esi+block_flags],FREE_BLOCK
515
           xor eax, eax
279 serge 516
           mov [heap_mutex], eax
321 diamond 517
           dec eax
660 serge 518
           pop edi
519
           pop esi
520
           pop ebx
164 serge 521
           ret
522
.fail:
523
           xor eax, eax
279 serge 524
           mov [heap_mutex], eax
660 serge 525
           pop edi
526
           pop esi
527
           pop ebx
164 serge 528
           ret
529
endp
530
 
531
align 4
532
proc kernel_alloc stdcall, size:dword
533
           locals
534
             lin_addr    dd ?
535
             pages_count dd ?
536
           endl
537
 
662 serge 538
           push ebx
539
           push edi
540
 
164 serge 541
           mov eax, [size]
206 serge 542
           add eax, 4095
543
           and eax, not 4095;
164 serge 544
           mov [size], eax
545
           and eax, eax
357 serge 546
           jz .err
164 serge 547
           mov ebx, eax
548
           shr ebx, 12
549
           mov [pages_count], ebx
550
 
551
           stdcall alloc_kernel_space, eax
357 serge 552
           test eax, eax
553
           jz .err
164 serge 554
           mov [lin_addr], eax
555
 
556
           mov ecx, [pages_count]
557
           mov edx, eax
558
           mov ebx, ecx
559
 
560
           shr ecx, 3
561
           jz .next
562
 
563
           and ebx, not 7
564
           push ebx
565
           stdcall alloc_pages, ebx
566
           pop ecx                   ; yes ecx!!!
567
           and eax, eax
357 serge 568
           jz .err
164 serge 569
 
570
           mov edi, eax
571
           mov edx, [lin_addr]
572
@@:
573
           stdcall map_page,edx,edi,dword PG_SW
574
           add edx, 0x1000
575
           add edi, 0x1000
576
           dec ecx
577
           jnz @B
578
.next:
579
           mov ecx, [pages_count]
580
           and ecx, 7
581
           jz .end
357 serge 582
@@:
583
           push ecx
164 serge 584
           call alloc_page
585
           pop ecx
586
           test eax, eax
357 serge 587
           jz .err
164 serge 588
 
589
           stdcall map_page,edx,eax,dword PG_SW
590
           add edx, 0x1000
591
           dec ecx
592
           jnz @B
593
.end:
594
           mov eax, [lin_addr]
662 serge 595
           pop edi
596
           pop ebx
164 serge 597
           ret
357 serge 598
.err:
164 serge 599
           xor eax, eax
662 serge 600
           pop edi
601
           pop ebx
164 serge 602
           ret
603
endp
604
 
605
align 4
606
proc kernel_free stdcall, base:dword
321 diamond 607
           push ebx esi
164 serge 608
 
279 serge 609
           mov ebx, heap_mutex
610
           call wait_mutex    ;ebx
611
 
164 serge 612
           mov eax, [base]
357 serge 613
           mov esi, [mem_used.fd]
164 serge 614
@@:
357 serge 615
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
616
           je .fail
164 serge 617
 
618
           cmp [esi+block_base], eax
619
           je .found
357 serge 620
           mov esi, [esi+list_fd]
164 serge 621
           jmp @b
622
.found:
623
           cmp [esi+block_flags], USED_BLOCK
624
           jne .fail
625
 
279 serge 626
           and [heap_mutex], 0
627
 
321 diamond 628
           push ecx
164 serge 629
           mov ecx, [esi+block_size];
281 serge 630
           shr ecx, 12
279 serge 631
           call release_pages   ;eax, ecx
321 diamond 632
           pop ecx
164 serge 633
           stdcall free_kernel_space, [base]
321 diamond 634
           pop esi ebx
279 serge 635
           ret
164 serge 636
.fail:
279 serge 637
           and [heap_mutex], 0
321 diamond 638
           pop esi ebx
164 serge 639
           ret
640
endp
641
 
642
restore block_next
643
restore block_prev
644
restore block_list
645
restore block_base
646
restore block_size
647
restore block_flags
648
 
649
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
650
 
188 serge 651
HEAP_TOP  equ 0x5FC00000
652
 
164 serge 653
align 4
188 serge 654
proc init_heap
164 serge 655
 
465 serge 656
           mov ebx,[current_slot]
657
           mov eax, [ebx+APPDATA.heap_top]
172 serge 658
           test eax, eax
659
           jz @F
465 serge 660
           sub eax,[ebx+APPDATA.heap_base]
172 serge 661
           sub eax, 4096
662
           ret
663
@@:
465 serge 664
           mov esi, [ebx+APPDATA.mem_size]
188 serge 665
           add esi, 4095
666
           and esi, not 4095
465 serge 667
           mov [ebx+APPDATA.mem_size], esi
188 serge 668
           mov eax, HEAP_TOP
465 serge 669
           mov [ebx+APPDATA.heap_base], esi
670
           mov [ebx+APPDATA.heap_top], eax
164 serge 671
 
188 serge 672
           sub eax, esi
673
           shr esi, 10
674
           mov ecx, eax
164 serge 675
           sub eax, 4096
188 serge 676
           or ecx, FREE_BLOCK
365 serge 677
           mov [page_tabs+esi], ecx
164 serge 678
           ret
679
endp
680
 
681
align 4
682
proc user_alloc stdcall, alloc_size:dword
683
 
662 serge 684
           push ebx
685
           push esi
686
           push edi
687
 
164 serge 688
           mov ecx, [alloc_size]
689
           add ecx, (4095+4096)
690
           and ecx, not 4095
691
 
465 serge 692
           mov ebx, [current_slot]
693
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
694
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
164 serge 695
l_0:
696
           cmp esi, edi
697
           jae m_exit
698
 
699
           mov ebx, esi
700
           shr ebx, 12
365 serge 701
           mov eax, [page_tabs+ebx*4]
620 diamond 702
           test al, FREE_BLOCK
164 serge 703
           jz test_used
704
           and eax, 0xFFFFF000
705
           cmp eax, ecx    ;alloc_size
706
           jb  m_next
940 serge 707
           jz  @f
164 serge 708
 
620 diamond 709
           lea edx, [esi+ecx]
710
           sub eax, ecx
711
           or al, FREE_BLOCK
164 serge 712
           shr edx, 12
365 serge 713
           mov [page_tabs+edx*4], eax
294 diamond 714
@@:
164 serge 715
           or ecx, USED_BLOCK
365 serge 716
           mov [page_tabs+ebx*4], ecx
164 serge 717
           shr ecx, 12
620 diamond 718
           inc ebx
164 serge 719
           dec ecx
620 diamond 720
           jz  .no
164 serge 721
@@:
365 serge 722
           mov dword [page_tabs+ebx*4], 2
164 serge 723
           inc ebx
724
           dec ecx
725
           jnz @B
620 diamond 726
.no:
164 serge 727
 
465 serge 728
           mov     edx, [current_slot]
729
           mov     ebx, [alloc_size]
730
           add     ebx, 0xFFF
731
           and     ebx, not 0xFFF
732
           add     ebx, [edx+APPDATA.mem_size]
733
           call    update_mem_size
294 diamond 734
 
620 diamond 735
           lea eax, [esi+4096]
662 serge 736
 
737
           pop edi
738
           pop esi
739
           pop ebx
164 serge 740
           ret
741
test_used:
620 diamond 742
           test al, USED_BLOCK
164 serge 743
           jz m_exit
744
 
745
           and eax, 0xFFFFF000
620 diamond 746
m_next:
164 serge 747
           add esi, eax
748
           jmp l_0
749
m_exit:
750
           xor eax, eax
662 serge 751
           pop edi
752
           pop esi
753
           pop ebx
164 serge 754
           ret
755
endp
756
 
757
align 4
758
proc user_free stdcall, base:dword
759
 
662 serge 760
           push esi
761
 
164 serge 762
           mov esi, [base]
763
           test esi, esi
764
           jz .exit
765
 
662 serge 766
           push ebx
767
 
294 diamond 768
           xor ebx, ebx
164 serge 769
           shr esi, 12
620 diamond 770
           mov eax, [page_tabs+(esi-1)*4]
546 diamond 771
           test al, USED_BLOCK
620 diamond 772
           jz .cantfree
546 diamond 773
           test al, DONT_FREE_BLOCK
774
           jnz .cantfree
164 serge 775
 
776
           and eax, not 4095
777
           mov ecx, eax
620 diamond 778
           or al, FREE_BLOCK
779
           mov [page_tabs+(esi-1)*4], eax
164 serge 780
           sub ecx, 4096
620 diamond 781
           mov ebx, ecx
164 serge 782
           shr ecx, 12
620 diamond 783
           jz .released
164 serge 784
.release:
188 serge 785
           xor eax, eax
365 serge 786
           xchg eax, [page_tabs+esi*4]
620 diamond 787
           test al, 1
188 serge 788
           jz @F
940 serge 789
           test eax, PG_SHARED
790
           jnz @F
164 serge 791
           call free_page
448 diamond 792
           mov eax, esi
793
           shl eax, 12
794
           invlpg [eax]
188 serge 795
@@:
164 serge 796
           inc esi
797
           dec ecx
798
           jnz .release
620 diamond 799
.released:
662 serge 800
           push edi
801
 
465 serge 802
           mov edx, [current_slot]
803
           mov esi, dword [edx+APPDATA.heap_base]
804
           mov edi, dword [edx+APPDATA.heap_top]
805
           sub ebx, [edx+APPDATA.mem_size]
294 diamond 806
           neg ebx
807
           call update_mem_size
448 diamond 808
           call user_normalize
662 serge 809
           pop edi
810
           pop ebx
811
           pop esi
448 diamond 812
           ret
813
.exit:
814
           xor eax, eax
815
           inc eax
662 serge 816
           pop esi
448 diamond 817
           ret
546 diamond 818
.cantfree:
819
           xor eax, eax
662 serge 820
           pop ebx
821
           pop esi
546 diamond 822
           ret
448 diamond 823
endp
824
 
825
user_normalize:
826
; in: esi=heap_base, edi=heap_top
827
; out: eax=0 <=> OK
828
; destroys: ebx,edx,esi,edi
164 serge 829
           shr esi, 12
830
           shr edi, 12
831
@@:
365 serge 832
           mov eax, [page_tabs+esi*4]
620 diamond 833
           test al, USED_BLOCK
164 serge 834
           jz .test_free
835
           shr eax, 12
836
           add esi, eax
837
           jmp @B
838
.test_free:
620 diamond 839
           test al, FREE_BLOCK
164 serge 840
           jz .err
841
           mov edx, eax
842
           shr edx, 12
843
           add edx, esi
844
           cmp edx, edi
845
           jae .exit
846
 
365 serge 847
           mov ebx, [page_tabs+edx*4]
620 diamond 848
           test bl, USED_BLOCK
164 serge 849
           jz .next_free
850
 
851
           shr ebx, 12
852
           add edx, ebx
853
           mov esi, edx
854
           jmp @B
855
.next_free:
620 diamond 856
           test bl, FREE_BLOCK
164 serge 857
           jz .err
365 serge 858
           and dword [page_tabs+edx*4], 0
164 serge 859
           add eax, ebx
860
           and eax, not 4095
861
           or eax, FREE_BLOCK
365 serge 862
           mov [page_tabs+esi*4], eax
164 serge 863
           jmp @B
864
.exit:
865
           xor eax, eax
866
           inc eax
867
           ret
868
.err:
869
           xor eax, eax
870
           ret
871
 
448 diamond 872
user_realloc:
873
; in: eax = pointer, ebx = new size
874
; out: eax = new pointer or NULL
875
        test    eax, eax
876
        jnz     @f
877
; realloc(NULL,sz) - same as malloc(sz)
878
        push    ebx
879
        call    user_alloc
880
        ret
881
@@:
882
        push    ecx edx
465 serge 883
        lea     ecx, [eax - 0x1000]
448 diamond 884
        shr     ecx, 12
885
        mov     edx, [page_tabs+ecx*4]
620 diamond 886
        test    dl, USED_BLOCK
448 diamond 887
        jnz     @f
888
; attempt to realloc invalid pointer
889
.ret0:
890
        pop     edx ecx
891
        xor     eax, eax
892
        ret
893
@@:
620 diamond 894
        test    dl, DONT_FREE_BLOCK
546 diamond 895
        jnz     .ret0
448 diamond 896
        add     ebx, 0x1FFF
897
        shr     edx, 12
898
        shr     ebx, 12
899
; edx = allocated size, ebx = new size
900
        add     edx, ecx
901
        add     ebx, ecx
902
        cmp     edx, ebx
903
        jb      .realloc_add
904
; release part of allocated memory
905
.loop:
906
        cmp     edx, ebx
907
        jz      .release_done
908
        dec     edx
909
        xor     eax, eax
910
        xchg    eax, [page_tabs+edx*4]
911
        test    al, 1
912
        jz      .loop
913
        call    free_page
914
        mov     eax, edx
915
        shl     eax, 12
916
        invlpg  [eax]
917
        jmp     .loop
918
.release_done:
919
        sub     ebx, ecx
920
        cmp     ebx, 1
921
        jnz     .nofreeall
922
        mov     eax, [page_tabs+ecx*4]
923
        and     eax, not 0xFFF
465 serge 924
        mov     edx, [current_slot]
925
        mov     ebx, [APPDATA.mem_size+edx]
448 diamond 926
        sub     ebx, eax
927
        add     ebx, 0x1000
928
        or      al, FREE_BLOCK
929
        mov     [page_tabs+ecx*4], eax
930
        push    esi edi
465 serge 931
        mov     esi, [APPDATA.heap_base+edx]
932
        mov     edi, [APPDATA.heap_top+edx]
448 diamond 933
        call    update_mem_size
934
        call    user_normalize
935
        pop     edi esi
936
        jmp     .ret0   ; all freed
937
.nofreeall:
938
        sub     edx, ecx
939
        shl     ebx, 12
940
        or      ebx, USED_BLOCK
941
        xchg    [page_tabs+ecx*4], ebx
942
        shr     ebx, 12
943
        sub     ebx, edx
944
        push    ebx ecx edx
465 serge 945
        mov     edx, [current_slot]
448 diamond 946
        shl     ebx, 12
465 serge 947
        sub     ebx, [APPDATA.mem_size+edx]
448 diamond 948
        neg     ebx
949
        call    update_mem_size
950
        pop     edx ecx ebx
465 serge 951
        lea     eax, [ecx+1]
448 diamond 952
        shl     eax, 12
953
        push    eax
823 diamond 954
        add     ecx, edx
955
        lea     edx, [ecx+ebx]
448 diamond 956
        shl     ebx, 12
957
        jz      .ret
958
        push    esi
465 serge 959
        mov     esi, [current_slot]
960
        mov     esi, [APPDATA.heap_top+esi]
448 diamond 961
        shr     esi, 12
962
@@:
963
        cmp     edx, esi
964
        jae     .merge_done
965
        mov     eax, [page_tabs+edx*4]
966
        test    al, USED_BLOCK
823 diamond 967
        jnz     .merge_done
448 diamond 968
        and     dword [page_tabs+edx*4], 0
823 diamond 969
        shr     eax, 12
970
        add     edx, eax
971
        shl     eax, 12
448 diamond 972
        add     ebx, eax
973
        jmp     @b
974
.merge_done:
975
        pop     esi
976
        or      ebx, FREE_BLOCK
977
        mov     [page_tabs+ecx*4], ebx
978
.ret:
979
        pop     eax edx ecx
980
        ret
981
.realloc_add:
982
; get some additional memory
465 serge 983
        mov     eax, [current_slot]
984
        mov     eax, [APPDATA.heap_top+eax]
448 diamond 985
        shr     eax, 12
986
        cmp     edx, eax
987
        jae     .cant_inplace
988
        mov     eax, [page_tabs+edx*4]
620 diamond 989
        test    al, FREE_BLOCK
990
        jz      .cant_inplace
448 diamond 991
        shr     eax, 12
992
        add     eax, edx
620 diamond 993
        sub     eax, ebx
448 diamond 994
        jb      .cant_inplace
995
        jz      @f
996
        shl     eax, 12
997
        or      al, FREE_BLOCK
998
        mov     [page_tabs+ebx*4], eax
999
@@:
1000
        mov     eax, ebx
1001
        sub     eax, ecx
1002
        shl     eax, 12
1003
        or      al, USED_BLOCK
1004
        mov     [page_tabs+ecx*4], eax
465 serge 1005
        lea     eax, [ecx+1]
448 diamond 1006
        shl     eax, 12
1007
        push    eax
1008
        push    edi
1009
        lea     edi, [page_tabs+edx*4]
1010
        mov     eax, 2
1011
        sub     ebx, edx
1012
        mov     ecx, ebx
1013
        cld
1014
        rep     stosd
1015
        pop     edi
465 serge 1016
        mov     edx, [current_slot]
448 diamond 1017
        shl     ebx, 12
465 serge 1018
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1019
        call    update_mem_size
1020
        pop     eax edx ecx
1021
        ret
1022
.cant_inplace:
1023
        push    esi edi
465 serge 1024
        mov     eax, [current_slot]
1025
        mov     esi, [APPDATA.heap_base+eax]
1026
        mov     edi, [APPDATA.heap_top+eax]
448 diamond 1027
        shr     esi, 12
1028
        shr     edi, 12
1029
        sub     ebx, ecx
1030
.find_place:
1031
        cmp     esi, edi
1032
        jae     .place_not_found
1033
        mov     eax, [page_tabs+esi*4]
1034
        test    al, FREE_BLOCK
1035
        jz      .next_place
1036
        shr     eax, 12
1037
        cmp     eax, ebx
1038
        jae     .place_found
1039
        add     esi, eax
1040
        jmp     .find_place
1041
.next_place:
1042
        shr     eax, 12
1043
        add     esi, eax
1044
        jmp     .find_place
1045
.place_not_found:
1046
        pop     edi esi
1047
        jmp     .ret0
1048
.place_found:
1049
        sub     eax, ebx
1050
        jz      @f
1051
        push    esi
620 diamond 1052
        add     esi, ebx
448 diamond 1053
        shl     eax, 12
1054
        or      al, FREE_BLOCK
1055
        mov     [page_tabs+esi*4], eax
1056
        pop     esi
1057
@@:
1058
        mov     eax, ebx
1059
        shl     eax, 12
1060
        or      al, USED_BLOCK
1061
        mov     [page_tabs+esi*4], eax
1062
        inc     esi
1063
        mov     eax, esi
1064
        shl     eax, 12
1065
        push    eax
1066
        mov     eax, [page_tabs+ecx*4]
1067
        and     eax, not 0xFFF
1068
        or      al, FREE_BLOCK
1069
        sub     edx, ecx
1070
        mov     [page_tabs+ecx*4], eax
1071
        inc     ecx
620 diamond 1072
        dec     ebx
1073
        dec     edx
1074
        jz      .no
448 diamond 1075
@@:
1076
        xor     eax, eax
1077
        xchg    eax, [page_tabs+ecx*4]
1078
        mov     [page_tabs+esi*4], eax
940 serge 1079
        mov     eax, ecx
1080
        shl     eax, 12
1081
        invlpg  [eax]
620 diamond 1082
        inc     esi
448 diamond 1083
        inc     ecx
1084
        dec     ebx
1085
        dec     edx
1086
        jnz     @b
620 diamond 1087
.no:
448 diamond 1088
        push    ebx
465 serge 1089
        mov     edx, [current_slot]
448 diamond 1090
        shl     ebx, 12
465 serge 1091
        add     ebx, [APPDATA.mem_size+edx]
448 diamond 1092
        call    update_mem_size
1093
        pop     ebx
1094
@@:
1095
        mov     dword [page_tabs+esi*4], 2
1096
        inc     esi
1097
        dec     ebx
1098
        jnz     @b
1099
        pop     eax edi esi edx ecx
1100
        ret
1101
 
278 serge 1102
if 0
164 serge 1103
align 4
1104
proc alloc_dll
1105
           pushf
1106
           cli
1107
           bsf eax, [dll_map]
1108
           jnz .find
1109
           popf
1110
           xor eax, eax
1111
           ret
1112
.find:
1113
           btr [dll_map], eax
1114
           popf
1115
           shl eax, 5
1116
           add eax, dll_tab
1117
           ret
1118
endp
1119
 
1120
align 4
1121
proc alloc_service
1122
           pushf
1123
           cli
1124
           bsf eax, [srv_map]
1125
           jnz .find
1126
           popf
1127
           xor eax, eax
1128
           ret
214 serge 1129
.find:
1130
           btr [srv_map], eax
164 serge 1131
           popf
214 serge 1132
           shl eax,0x02
1133
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
164 serge 1134
           ret
1135
endp
278 serge 1136
 
1137
end if
940 serge 1138
 
1139
 
1140
;;;;;;;;;;;;;;      SHARED      ;;;;;;;;;;;;;;;;;
1141
 
1142
 
1143
; param
1144
;  eax= shm_map object
1145
 
1146
align 4
1147
destroy_smap:
1148
 
1149
           pushfd
1150
           cli
1151
 
945 serge 1152
           push esi
1153
           push edi
940 serge 1154
 
945 serge 1155
           mov edi, eax
1156
           mov esi, [eax+SMAP.parent]
1157
           test esi, esi
1158
           jz .done
940 serge 1159
 
945 serge 1160
           lock dec [esi+SMEM.refcount]
1161
           jnz .done
940 serge 1162
 
945 serge 1163
           mov ecx, [esi+SMEM.bk]
1164
           mov edx, [esi+SMEM.fd]
1165
 
1166
           mov [ecx+SMEM.fd], edx
1167
           mov [edx+SMEM.bk], ecx
1168
 
1169
           stdcall kernel_free, [esi+SMEM.base]
1170
           mov eax, esi
1171
           call free
1172
.done:
1173
           mov eax, edi
940 serge 1174
           call destroy_kernel_object
1175
 
945 serge 1176
           pop edi
1177
           pop esi
940 serge 1178
           popfd
1179
 
1180
           ret
1181
 
1182
E_NOTFOUND      equ  5
1183
E_ACCESS        equ 10
1184
E_NOMEM         equ 30
1185
E_PARAM         equ 33
1186
 
1187
SHM_READ        equ 0
1188
SHM_WRITE       equ 1
1189
 
1190
SHM_ACCESS_MASK equ 3
1191
 
1192
SHM_OPEN        equ (0 shl 2)
1193
SHM_OPEN_ALWAYS equ (1 shl 2)
1194
SHM_CREATE      equ (2 shl 2)
1195
 
1196
SHM_OPEN_MASK   equ (3 shl 2)
1197
 
1198
align 4
1199
proc shmem_open stdcall name:dword, size:dword, access:dword
1200
           locals
1201
              action         dd ?
1202
              owner_access   dd ?
1203
              mapped         dd ?
1204
           endl
1205
 
1206
           push ebx
1207
           push esi
1208
           push edi
1209
 
1210
           mov [mapped], 0
1211
           mov [owner_access], 0
1212
 
1213
           pushfd                      ;mutex required
1214
           cli
1215
 
1216
           mov eax, [access]
1217
           and eax, SHM_OPEN_MASK
1218
           mov [action], eax
1219
 
1220
           mov eax, [name]
1221
           test eax, eax
1222
           mov edx, E_PARAM
1223
           jz .exit
1224
 
1225
           mov esi, [shmem_list.fd]
1226
align 4
1227
@@:
1228
           cmp esi, shmem_list
1229
           je .not_found
1230
 
943 serge 1231
           lea edx, [esi+SMEM.name] ; link , base, size
940 serge 1232
           stdcall strncmp, edx, eax, 32
1233
           test eax, eax
1234
           je .found
1235
 
943 serge 1236
           mov esi, [esi+SMEM.fd]
940 serge 1237
           jmp @B
1238
 
1239
.not_found:
1240
           mov eax, [action]
1241
 
1242
           cmp eax, SHM_OPEN
1243
           mov edx, E_NOTFOUND
1244
           je .exit
1245
 
1246
           cmp eax, SHM_CREATE
1247
           mov edx, E_PARAM
1248
           je .create_shm
1249
 
1250
           cmp eax, SHM_OPEN_ALWAYS
1251
           jne .exit
1252
 
1253
.create_shm:
1254
 
1255
           mov ecx, [size]
1256
           test ecx, ecx
1257
           jz .exit
1258
 
1259
           add ecx, 4095
1260
           and ecx, -4096
1261
           mov [size], ecx
1262
 
943 serge 1263
           mov eax, SMEM.sizeof
940 serge 1264
           call malloc
1265
           test eax, eax
1266
           mov esi, eax
1267
           mov edx, E_NOMEM
1268
           jz .exit
1269
 
1270
           stdcall kernel_alloc, [size]
1271
           test eax, eax
1272
           mov [mapped], eax
1273
           mov edx, E_NOMEM
1274
           jz .cleanup
1275
 
1276
           mov ecx, [size]
1277
           mov edx, [access]
1278
           and edx, SHM_ACCESS_MASK
1279
 
943 serge 1280
           mov [esi+SMEM.base], eax
1281
           mov [esi+SMEM.size], ecx
1282
           mov [esi+SMEM.access], edx
1283
           mov [esi+SMEM.refcount], 0
1284
           mov [esi+SMEM.name+28], 0
940 serge 1285
 
943 serge 1286
           lea eax, [esi+SMEM.name]
940 serge 1287
           stdcall strncpy, eax, [name], 31
1288
 
1289
           mov eax, [shmem_list.fd]
943 serge 1290
           mov [esi+SMEM.bk], shmem_list
1291
           mov [esi+SMEM.fd], eax
940 serge 1292
 
943 serge 1293
           mov [eax+SMEM.bk], esi
940 serge 1294
           mov [shmem_list.fd], esi
1295
 
1296
           mov [action], SHM_OPEN
1297
           mov [owner_access], SHM_WRITE
1298
 
1299
.found:
1300
           mov eax, [action]
1301
 
1302
           cmp eax, SHM_CREATE
1303
           mov edx, E_ACCESS
1304
           je .exit
1305
 
1306
           cmp eax, SHM_OPEN
1307
           mov edx, E_PARAM
1308
           je .create_map
1309
 
1310
           cmp eax, SHM_OPEN_ALWAYS
1311
           jne .exit
1312
 
1313
.create_map:
1314
 
1315
           mov eax, [access]
1316
           and eax, SHM_ACCESS_MASK
943 serge 1317
           cmp eax, [esi+SMEM.access]
940 serge 1318
           mov [access], eax
1319
           mov edx, E_ACCESS
1320
           ja .exit
1321
 
1322
           mov ebx, [CURRENT_TASK]
1323
           shl ebx, 5
1324
           mov ebx, [CURRENT_TASK+ebx+4]
943 serge 1325
           mov eax, SMAP.sizeof
940 serge 1326
 
1327
           call create_kernel_object
1328
           test eax, eax
1329
           mov edi, eax
1330
           mov edx, E_NOMEM
1331
           jz .exit
1332
 
943 serge 1333
           mov [edi+SMAP.magic], 'SMAP'
1334
           mov [edi+SMAP.destroy], destroy_smap
1335
           mov [edi+SMAP.base], 0
1336
           mov [edi+SMAP.parent], 0
940 serge 1337
 
943 serge 1338
           stdcall user_alloc, [esi+SMEM.size]
940 serge 1339
           test eax, eax
1340
           mov [mapped], eax
1341
           mov edx, E_NOMEM
1342
           jz .cleanup2
1343
 
943 serge 1344
           lock inc [esi+SMEM.refcount]
1345
           mov [edi+SMAP.base], eax
1346
           mov [edi+SMAP.parent], esi
940 serge 1347
 
943 serge 1348
           mov ecx, [esi+SMEM.size]
940 serge 1349
           mov [size], ecx
1350
 
1351
           shr ecx, 12
1352
           shr eax, 10
1353
 
943 serge 1354
           mov esi, [esi+SMEM.base]
940 serge 1355
           shr esi, 10
1356
           lea edi, [page_tabs+eax]
1357
           add esi, page_tabs
1358
 
1359
           mov edx, [access]
1360
           or edx, [owner_access]
1361
           shl edx, 1
1362
           or edx, PG_USER+PG_SHARED
1363
@@:
1364
           lodsd
1365
           and eax, 0xFFFFF000
1366
           or eax, edx
1367
           stosd
1368
           loop @B
1369
 
1370
           xor edx, edx
1371
 
1372
           cmp [owner_access], 0
1373
           jne .exit
1374
 
1375
           mov edx, [size]
1376
.exit:
1377
           mov eax, [mapped]
1378
 
1379
           popfd
1380
           pop edi
1381
           pop esi
1382
           pop ebx
1383
           ret
1384
 
1385
.cleanup:
1386
           mov eax, esi
1387
           call free
1388
           jmp .exit
1389
 
1390
.cleanup2:
1391
           mov eax, edi
1392
           call destroy_smap
1393
           jmp .exit
1394
endp
943 serge 1395
 
1396
align 4
1397
proc shmem_close stdcall, name:dword
1398
 
1399
           mov eax, [name]
1400
           test eax, eax
1401
           jz .fail
1402
 
1403
           push esi
1404
           push edi
945 serge 1405
           pushfd
1406
           cli
943 serge 1407
 
1408
           mov esi, [current_slot]
1409
           add esi, APP_OBJ_OFFSET
1410
.next:
1411
           mov eax, [esi+APPOBJ.fd]
1412
           test eax, eax
1413
           jz @F
1414
 
1415
           cmp eax, esi
1416
           mov esi, eax
1417
           je @F
1418
 
1419
           cmp [eax+SMAP.magic], 'SMAP'
1420
           jne .next
1421
 
1422
           mov edi, [eax+SMAP.parent]
1423
           test edi, edi
1424
           jz .next
1425
 
1426
           lea eax, [edi+SMEM.name]
1427
           stdcall strncmp, [name], edi, 32
1428
           test eax, eax
1429
           jne .next
1430
 
945 serge 1431
           stdcall user_free, [esi+SMAP.base]
1432
 
943 serge 1433
           call [esi+APPOBJ.destroy]
1434
@@:
945 serge 1435
           popfd
943 serge 1436
           pop edi
1437
           pop esi
1438
.fail:
1439
           ret
1440
endp