Subversion Repositories Kolibri OS

Rev

Rev 1710 | Details | Compare with Previous | Last modification | View Log | RSS feed

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