Subversion Repositories Kolibri OS

Rev

Rev 7136 | Rev 7967 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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