Subversion Repositories Kolibri OS

Rev

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

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