Rev 888 | Rev 890 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
164 | serge | 7 | |
593 | mikedld | 8 | $Revision: 889 $ |
9 | |||
10 | |||
164 | serge | 11 | |
357 | serge | 12 | MEM_LIST_OFFSET equ 8 |
164 | serge | 13 | FREE_BLOCK equ 4 |
14 | USED_BLOCK equ 8 |
||
546 | diamond | 15 | DONT_FREE_BLOCK equ 10h |
164 | serge | 16 | |
17 | |||
18 | align 4 |
||
321 | diamond | 19 | proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
279 | serge | 20 | |
164 | serge | 21 | ret |
22 | endp |
||
23 | |||
24 | |||
25 | ;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
||
26 | |||
188 | serge | 27 | HEAP_TOP equ 0x5FC00000 |
28 | |||
164 | serge | 29 | align 4 |
188 | serge | 30 | proc init_heap |
164 | serge | 31 | |
465 | serge | 32 | mov ebx,[current_slot] |
33 | mov eax, [ebx+APPDATA.heap_top] |
||
172 | serge | 34 | test eax, eax |
35 | jz @F |
||
465 | serge | 36 | sub eax,[ebx+APPDATA.heap_base] |
172 | serge | 37 | sub eax, 4096 |
38 | ret |
||
39 | @@: |
||
465 | serge | 40 | mov esi, [ebx+APPDATA.mem_size] |
188 | serge | 41 | add esi, 4095 |
42 | and esi, not 4095 |
||
465 | serge | 43 | mov [ebx+APPDATA.mem_size], esi |
188 | serge | 44 | mov eax, HEAP_TOP |
465 | serge | 45 | mov [ebx+APPDATA.heap_base], esi |
46 | mov [ebx+APPDATA.heap_top], eax |
||
164 | serge | 47 | |
188 | serge | 48 | sub eax, esi |
49 | shr esi, 10 |
||
50 | mov ecx, eax |
||
164 | serge | 51 | sub eax, 4096 |
188 | serge | 52 | or ecx, FREE_BLOCK |
365 | serge | 53 | mov [page_tabs+esi], ecx |
164 | serge | 54 | ret |
55 | endp |
||
56 | |||
57 | align 4 |
||
58 | proc user_alloc stdcall, alloc_size:dword |
||
59 | |||
662 | serge | 60 | push ebx |
61 | push esi |
||
62 | push edi |
||
63 | |||
164 | serge | 64 | mov ecx, [alloc_size] |
65 | add ecx, (4095+4096) |
||
66 | and ecx, not 4095 |
||
67 | |||
465 | serge | 68 | mov ebx, [current_slot] |
69 | mov esi, dword [ebx+APPDATA.heap_base] ; heap_base |
||
70 | mov edi, dword [ebx+APPDATA.heap_top] ; heap_top |
||
164 | serge | 71 | l_0: |
72 | cmp esi, edi |
||
73 | jae m_exit |
||
74 | |||
75 | mov ebx, esi |
||
76 | shr ebx, 12 |
||
365 | serge | 77 | mov eax, [page_tabs+ebx*4] |
620 | diamond | 78 | test al, FREE_BLOCK |
164 | serge | 79 | jz test_used |
80 | and eax, 0xFFFFF000 |
||
81 | cmp eax, ecx ;alloc_size |
||
82 | jb m_next |
||
270 | diamond | 83 | jz @f |
164 | serge | 84 | |
620 | diamond | 85 | lea edx, [esi+ecx] |
86 | sub eax, ecx |
||
87 | or al, FREE_BLOCK |
||
164 | serge | 88 | shr edx, 12 |
365 | serge | 89 | mov [page_tabs+edx*4], eax |
294 | diamond | 90 | @@: |
164 | serge | 91 | or ecx, USED_BLOCK |
365 | serge | 92 | mov [page_tabs+ebx*4], ecx |
164 | serge | 93 | shr ecx, 12 |
620 | diamond | 94 | inc ebx |
164 | serge | 95 | dec ecx |
620 | diamond | 96 | jz .no |
164 | serge | 97 | @@: |
365 | serge | 98 | mov dword [page_tabs+ebx*4], 2 |
164 | serge | 99 | inc ebx |
100 | dec ecx |
||
101 | jnz @B |
||
620 | diamond | 102 | .no: |
164 | serge | 103 | |
465 | serge | 104 | mov edx, [current_slot] |
105 | mov ebx, [alloc_size] |
||
106 | add ebx, 0xFFF |
||
107 | and ebx, not 0xFFF |
||
108 | add ebx, [edx+APPDATA.mem_size] |
||
109 | call update_mem_size |
||
294 | diamond | 110 | |
620 | diamond | 111 | lea eax, [esi+4096] |
662 | serge | 112 | |
113 | pop edi |
||
114 | pop esi |
||
115 | pop ebx |
||
164 | serge | 116 | ret |
117 | test_used: |
||
620 | diamond | 118 | test al, USED_BLOCK |
164 | serge | 119 | jz m_exit |
120 | |||
121 | and eax, 0xFFFFF000 |
||
620 | diamond | 122 | m_next: |
164 | serge | 123 | add esi, eax |
124 | jmp l_0 |
||
125 | m_exit: |
||
126 | xor eax, eax |
||
662 | serge | 127 | pop edi |
128 | pop esi |
||
129 | pop ebx |
||
164 | serge | 130 | ret |
131 | endp |
||
132 | |||
133 | align 4 |
||
134 | proc user_free stdcall, base:dword |
||
135 | |||
662 | serge | 136 | push esi |
137 | |||
164 | serge | 138 | mov esi, [base] |
139 | test esi, esi |
||
140 | jz .exit |
||
141 | |||
662 | serge | 142 | push ebx |
143 | |||
294 | diamond | 144 | xor ebx, ebx |
164 | serge | 145 | shr esi, 12 |
620 | diamond | 146 | mov eax, [page_tabs+(esi-1)*4] |
546 | diamond | 147 | test al, USED_BLOCK |
620 | diamond | 148 | jz .cantfree |
889 | serge | 149 | |
546 | diamond | 150 | test al, DONT_FREE_BLOCK |
151 | jnz .cantfree |
||
164 | serge | 152 | |
888 | serge | 153 | push edi |
154 | |||
164 | serge | 155 | and eax, not 4095 |
888 | serge | 156 | mov edi, eax |
620 | diamond | 157 | or al, FREE_BLOCK |
158 | mov [page_tabs+(esi-1)*4], eax |
||
888 | serge | 159 | sub edi, 4096 |
160 | mov ebx, edi |
||
161 | shr edi, 12 |
||
620 | diamond | 162 | jz .released |
889 | serge | 163 | |
164 | serge | 164 | .release: |
888 | serge | 165 | xor ecx, ecx |
166 | xchg ecx, [page_tabs+esi*4] |
||
167 | test cl, 1 |
||
188 | serge | 168 | jz @F |
888 | serge | 169 | |
170 | call @core_free@4 |
||
448 | diamond | 171 | mov eax, esi |
172 | shl eax, 12 |
||
173 | invlpg [eax] |
||
188 | serge | 174 | @@: |
164 | serge | 175 | inc esi |
888 | serge | 176 | dec edi |
164 | serge | 177 | jnz .release |
620 | diamond | 178 | .released: |
465 | serge | 179 | mov edx, [current_slot] |
180 | mov esi, dword [edx+APPDATA.heap_base] |
||
181 | mov edi, dword [edx+APPDATA.heap_top] |
||
182 | sub ebx, [edx+APPDATA.mem_size] |
||
294 | diamond | 183 | neg ebx |
184 | call update_mem_size |
||
448 | diamond | 185 | call user_normalize |
662 | serge | 186 | pop edi |
187 | pop ebx |
||
188 | pop esi |
||
448 | diamond | 189 | ret |
190 | .exit: |
||
191 | xor eax, eax |
||
192 | inc eax |
||
662 | serge | 193 | pop esi |
448 | diamond | 194 | ret |
546 | diamond | 195 | .cantfree: |
196 | xor eax, eax |
||
662 | serge | 197 | pop ebx |
198 | pop esi |
||
546 | diamond | 199 | ret |
448 | diamond | 200 | endp |
201 | |||
202 | user_normalize: |
||
203 | ; in: esi=heap_base, edi=heap_top |
||
204 | ; out: eax=0 <=> OK |
||
205 | ; destroys: ebx,edx,esi,edi |
||
164 | serge | 206 | shr esi, 12 |
207 | shr edi, 12 |
||
208 | @@: |
||
365 | serge | 209 | mov eax, [page_tabs+esi*4] |
620 | diamond | 210 | test al, USED_BLOCK |
164 | serge | 211 | jz .test_free |
212 | shr eax, 12 |
||
213 | add esi, eax |
||
214 | jmp @B |
||
215 | .test_free: |
||
620 | diamond | 216 | test al, FREE_BLOCK |
164 | serge | 217 | jz .err |
218 | mov edx, eax |
||
219 | shr edx, 12 |
||
220 | add edx, esi |
||
221 | cmp edx, edi |
||
222 | jae .exit |
||
223 | |||
365 | serge | 224 | mov ebx, [page_tabs+edx*4] |
620 | diamond | 225 | test bl, USED_BLOCK |
164 | serge | 226 | jz .next_free |
227 | |||
228 | shr ebx, 12 |
||
229 | add edx, ebx |
||
230 | mov esi, edx |
||
231 | jmp @B |
||
232 | .next_free: |
||
620 | diamond | 233 | test bl, FREE_BLOCK |
164 | serge | 234 | jz .err |
365 | serge | 235 | and dword [page_tabs+edx*4], 0 |
164 | serge | 236 | add eax, ebx |
237 | and eax, not 4095 |
||
238 | or eax, FREE_BLOCK |
||
365 | serge | 239 | mov [page_tabs+esi*4], eax |
164 | serge | 240 | jmp @B |
241 | .exit: |
||
242 | xor eax, eax |
||
243 | inc eax |
||
244 | ret |
||
245 | .err: |
||
246 | xor eax, eax |
||
247 | ret |
||
248 | |||
448 | diamond | 249 | user_realloc: |
250 | ; in: eax = pointer, ebx = new size |
||
251 | ; out: eax = new pointer or NULL |
||
252 | test eax, eax |
||
253 | jnz @f |
||
254 | ; realloc(NULL,sz) - same as malloc(sz) |
||
255 | push ebx |
||
256 | call user_alloc |
||
257 | ret |
||
258 | @@: |
||
259 | push ecx edx |
||
465 | serge | 260 | lea ecx, [eax - 0x1000] |
448 | diamond | 261 | shr ecx, 12 |
262 | mov edx, [page_tabs+ecx*4] |
||
620 | diamond | 263 | test dl, USED_BLOCK |
448 | diamond | 264 | jnz @f |
265 | ; attempt to realloc invalid pointer |
||
266 | .ret0: |
||
267 | pop edx ecx |
||
268 | xor eax, eax |
||
269 | ret |
||
270 | @@: |
||
620 | diamond | 271 | test dl, DONT_FREE_BLOCK |
546 | diamond | 272 | jnz .ret0 |
448 | diamond | 273 | add ebx, 0x1FFF |
274 | shr edx, 12 |
||
275 | shr ebx, 12 |
||
276 | ; edx = allocated size, ebx = new size |
||
277 | add edx, ecx |
||
278 | add ebx, ecx |
||
279 | cmp edx, ebx |
||
280 | jb .realloc_add |
||
281 | ; release part of allocated memory |
||
888 | serge | 282 | |
283 | push ecx |
||
448 | diamond | 284 | .loop: |
285 | cmp edx, ebx |
||
286 | jz .release_done |
||
287 | dec edx |
||
888 | serge | 288 | xor ecx, ecx |
289 | xchg ecx, [page_tabs+edx*4] |
||
448 | diamond | 290 | test al, 1 |
291 | jz .loop |
||
888 | serge | 292 | |
293 | push edx |
||
294 | call @core_free@4 |
||
295 | pop edx |
||
448 | diamond | 296 | mov eax, edx |
297 | shl eax, 12 |
||
298 | invlpg [eax] |
||
299 | jmp .loop |
||
300 | .release_done: |
||
888 | serge | 301 | |
302 | pop ecx |
||
303 | |||
448 | diamond | 304 | sub ebx, ecx |
305 | cmp ebx, 1 |
||
306 | jnz .nofreeall |
||
307 | mov eax, [page_tabs+ecx*4] |
||
308 | and eax, not 0xFFF |
||
465 | serge | 309 | mov edx, [current_slot] |
310 | mov ebx, [APPDATA.mem_size+edx] |
||
448 | diamond | 311 | sub ebx, eax |
312 | add ebx, 0x1000 |
||
313 | or al, FREE_BLOCK |
||
314 | mov [page_tabs+ecx*4], eax |
||
315 | push esi edi |
||
465 | serge | 316 | mov esi, [APPDATA.heap_base+edx] |
317 | mov edi, [APPDATA.heap_top+edx] |
||
448 | diamond | 318 | call update_mem_size |
319 | call user_normalize |
||
320 | pop edi esi |
||
321 | jmp .ret0 ; all freed |
||
322 | .nofreeall: |
||
323 | sub edx, ecx |
||
324 | shl ebx, 12 |
||
325 | or ebx, USED_BLOCK |
||
326 | xchg [page_tabs+ecx*4], ebx |
||
327 | shr ebx, 12 |
||
328 | sub ebx, edx |
||
329 | push ebx ecx edx |
||
465 | serge | 330 | mov edx, [current_slot] |
448 | diamond | 331 | shl ebx, 12 |
465 | serge | 332 | sub ebx, [APPDATA.mem_size+edx] |
448 | diamond | 333 | neg ebx |
334 | call update_mem_size |
||
335 | pop edx ecx ebx |
||
465 | serge | 336 | lea eax, [ecx+1] |
448 | diamond | 337 | shl eax, 12 |
338 | push eax |
||
823 | diamond | 339 | add ecx, edx |
340 | lea edx, [ecx+ebx] |
||
448 | diamond | 341 | shl ebx, 12 |
342 | jz .ret |
||
343 | push esi |
||
465 | serge | 344 | mov esi, [current_slot] |
345 | mov esi, [APPDATA.heap_top+esi] |
||
448 | diamond | 346 | shr esi, 12 |
347 | @@: |
||
348 | cmp edx, esi |
||
349 | jae .merge_done |
||
350 | mov eax, [page_tabs+edx*4] |
||
351 | test al, USED_BLOCK |
||
823 | diamond | 352 | jnz .merge_done |
448 | diamond | 353 | and dword [page_tabs+edx*4], 0 |
823 | diamond | 354 | shr eax, 12 |
355 | add edx, eax |
||
356 | shl eax, 12 |
||
448 | diamond | 357 | add ebx, eax |
358 | jmp @b |
||
359 | .merge_done: |
||
360 | pop esi |
||
361 | or ebx, FREE_BLOCK |
||
362 | mov [page_tabs+ecx*4], ebx |
||
363 | .ret: |
||
364 | pop eax edx ecx |
||
365 | ret |
||
366 | .realloc_add: |
||
367 | ; get some additional memory |
||
465 | serge | 368 | mov eax, [current_slot] |
369 | mov eax, [APPDATA.heap_top+eax] |
||
448 | diamond | 370 | shr eax, 12 |
371 | cmp edx, eax |
||
372 | jae .cant_inplace |
||
373 | mov eax, [page_tabs+edx*4] |
||
620 | diamond | 374 | test al, FREE_BLOCK |
375 | jz .cant_inplace |
||
448 | diamond | 376 | shr eax, 12 |
377 | add eax, edx |
||
620 | diamond | 378 | sub eax, ebx |
448 | diamond | 379 | jb .cant_inplace |
380 | jz @f |
||
381 | shl eax, 12 |
||
382 | or al, FREE_BLOCK |
||
383 | mov [page_tabs+ebx*4], eax |
||
384 | @@: |
||
385 | mov eax, ebx |
||
386 | sub eax, ecx |
||
387 | shl eax, 12 |
||
388 | or al, USED_BLOCK |
||
389 | mov [page_tabs+ecx*4], eax |
||
465 | serge | 390 | lea eax, [ecx+1] |
448 | diamond | 391 | shl eax, 12 |
392 | push eax |
||
393 | push edi |
||
394 | lea edi, [page_tabs+edx*4] |
||
395 | mov eax, 2 |
||
396 | sub ebx, edx |
||
397 | mov ecx, ebx |
||
398 | cld |
||
399 | rep stosd |
||
400 | pop edi |
||
465 | serge | 401 | mov edx, [current_slot] |
448 | diamond | 402 | shl ebx, 12 |
465 | serge | 403 | add ebx, [APPDATA.mem_size+edx] |
448 | diamond | 404 | call update_mem_size |
405 | pop eax edx ecx |
||
406 | ret |
||
407 | .cant_inplace: |
||
408 | push esi edi |
||
465 | serge | 409 | mov eax, [current_slot] |
410 | mov esi, [APPDATA.heap_base+eax] |
||
411 | mov edi, [APPDATA.heap_top+eax] |
||
448 | diamond | 412 | shr esi, 12 |
413 | shr edi, 12 |
||
414 | sub ebx, ecx |
||
415 | .find_place: |
||
416 | cmp esi, edi |
||
417 | jae .place_not_found |
||
418 | mov eax, [page_tabs+esi*4] |
||
419 | test al, FREE_BLOCK |
||
420 | jz .next_place |
||
421 | shr eax, 12 |
||
422 | cmp eax, ebx |
||
423 | jae .place_found |
||
424 | add esi, eax |
||
425 | jmp .find_place |
||
426 | .next_place: |
||
427 | shr eax, 12 |
||
428 | add esi, eax |
||
429 | jmp .find_place |
||
430 | .place_not_found: |
||
431 | pop edi esi |
||
432 | jmp .ret0 |
||
433 | .place_found: |
||
434 | sub eax, ebx |
||
435 | jz @f |
||
436 | push esi |
||
620 | diamond | 437 | add esi, ebx |
448 | diamond | 438 | shl eax, 12 |
439 | or al, FREE_BLOCK |
||
440 | mov [page_tabs+esi*4], eax |
||
441 | pop esi |
||
442 | @@: |
||
443 | mov eax, ebx |
||
444 | shl eax, 12 |
||
445 | or al, USED_BLOCK |
||
446 | mov [page_tabs+esi*4], eax |
||
447 | inc esi |
||
448 | mov eax, esi |
||
449 | shl eax, 12 |
||
450 | push eax |
||
451 | mov eax, [page_tabs+ecx*4] |
||
452 | and eax, not 0xFFF |
||
453 | or al, FREE_BLOCK |
||
454 | sub edx, ecx |
||
455 | mov [page_tabs+ecx*4], eax |
||
456 | inc ecx |
||
620 | diamond | 457 | dec ebx |
458 | dec edx |
||
459 | jz .no |
||
448 | diamond | 460 | @@: |
461 | xor eax, eax |
||
462 | xchg eax, [page_tabs+ecx*4] |
||
463 | mov [page_tabs+esi*4], eax |
||
464 | mov eax, ecx |
||
465 | shl eax, 12 |
||
466 | invlpg [eax] |
||
620 | diamond | 467 | inc esi |
448 | diamond | 468 | inc ecx |
469 | dec ebx |
||
470 | dec edx |
||
471 | jnz @b |
||
620 | diamond | 472 | .no: |
448 | diamond | 473 | push ebx |
465 | serge | 474 | mov edx, [current_slot] |
448 | diamond | 475 | shl ebx, 12 |
465 | serge | 476 | add ebx, [APPDATA.mem_size+edx] |
448 | diamond | 477 | call update_mem_size |
478 | pop ebx |
||
479 | @@: |
||
480 | mov dword [page_tabs+esi*4], 2 |
||
481 | inc esi |
||
482 | dec ebx |
||
483 | jnz @b |
||
484 | pop eax edi esi edx ecx |
||
485 | ret |
||
486 | |||
278 | serge | 487 | if 0 |
164 | serge | 488 | align 4 |
489 | proc alloc_dll |
||
490 | pushf |
||
491 | cli |
||
492 | bsf eax, [dll_map] |
||
493 | jnz .find |
||
494 | popf |
||
495 | xor eax, eax |
||
496 | ret |
||
497 | .find: |
||
498 | btr [dll_map], eax |
||
499 | popf |
||
500 | shl eax, 5 |
||
501 | add eax, dll_tab |
||
502 | ret |
||
503 | endp |
||
504 | |||
505 | align 4 |
||
506 | proc alloc_service |
||
507 | pushf |
||
508 | cli |
||
509 | bsf eax, [srv_map] |
||
510 | jnz .find |
||
511 | popf |
||
512 | xor eax, eax |
||
513 | ret |
||
214 | serge | 514 | .find: |
515 | btr [srv_map], eax |
||
164 | serge | 516 | popf |
214 | serge | 517 | shl eax,0x02 |
518 | lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
||
164 | serge | 519 | ret |
520 | endp |
||
278 | serge | 521 | |
522 | end if=> |