Subversion Repositories Kolibri OS

Rev

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

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