Subversion Repositories Kolibri OS

Rev

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