Changeset 3292623 in mainline
- Timestamp:
- 2010-04-17T01:16:55Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e1da7ec
- Parents:
- 596d65c
- Location:
- uspace/lib/c/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/libc.c
r596d65c r3292623 62 62 void __main(void *pcb_ptr) 63 63 { 64 int retval; 65 64 /* Initialize user task run-time environment */ 66 65 __heap_init(); 67 66 __async_init(); … … 75 74 char **argv; 76 75 76 /* Get command line arguments and initialize 77 standard input and output */ 77 78 if (__pcb == NULL) { 78 79 argc = 0; … … 86 87 } 87 88 88 retval = main(argc, argv); 89 90 __stdio_done(); 91 (void) task_retval(retval); 89 /* Run main() and set task return value 90 according the result */ 91 (void) task_retval(main(argc, argv)); 92 92 } 93 93 94 94 void __exit(void) 95 95 { 96 __stdio_done(); 96 97 fibril_teardown(__tcb_get()->fibril_data); 97 98 _exit(0); -
uspace/lib/c/generic/malloc.c
r596d65c r3292623 43 43 #include <bitops.h> 44 44 #include <mem.h> 45 #include <futex.h> 45 46 #include <adt/gcdlcm.h> 46 47 … … 75 76 #define NET_SIZE(size) ((size) - STRUCT_OVERHEAD) 76 77 77 78 78 /** Header of a heap block 79 79 * … … 104 104 extern char _heap; 105 105 106 /** Futex for thread-safe heap manipulation */ 107 static futex_t malloc_futex = FUTEX_INITIALIZER; 108 106 109 /** Address of heap start */ 107 110 static void *heap_start = 0; … … 119 122 * 120 123 * Fills in the structures related to a heap block. 124 * Should be called only inside the critical section. 121 125 * 122 126 * @param addr Address of the block. … … 144 148 * Verifies that the structures related to a heap block still contain 145 149 * the magic constants. This helps detect heap corruption early on. 150 * Should be called only inside the critical section. 146 151 * 147 152 * @param addr Address of the block. … … 161 166 } 162 167 168 /** Increase the heap area size 169 * 170 * Should be called only inside the critical section. 171 * 172 * @param size Number of bytes to grow the heap by. 173 * 174 */ 163 175 static bool grow_heap(size_t size) 164 176 { … … 189 201 } 190 202 203 /** Decrease the heap area 204 * 205 * Should be called only inside the critical section. 206 * 207 * @param size Number of bytes to shrink the heap by. 208 * 209 */ 191 210 static void shrink_heap(void) 192 211 { … … 196 215 /** Initialize the heap allocator 197 216 * 198 * Find s how much physical memory we have and creates217 * Find how much physical memory we have and create 199 218 * the heap management structures that mark the whole 200 219 * physical memory as a single free block. … … 203 222 void __heap_init(void) 204 223 { 224 futex_down(&malloc_futex); 225 205 226 if (as_area_create((void *) &_heap, PAGE_SIZE, 206 227 AS_AREA_WRITE | AS_AREA_READ)) { … … 213 234 block_init(heap_start, heap_end - heap_start, true); 214 235 } 215 } 216 236 237 futex_up(&malloc_futex); 238 } 239 240 /** Get maximum heap address 241 * 242 */ 217 243 uintptr_t get_max_heap_addr(void) 218 244 { 245 futex_down(&malloc_futex); 246 219 247 if (max_heap_size == (size_t) -1) 220 248 max_heap_size = 221 249 max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE); 222 250 223 return ((uintptr_t) heap_start + max_heap_size); 224 } 225 251 uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size; 252 253 futex_up(&malloc_futex); 254 255 return max_heap_addr; 256 } 257 258 /** Split heap block and mark it as used. 259 * 260 * Should be called only inside the critical section. 261 * 262 * @param cur Heap block to split. 263 * @param size Number of bytes to split and mark from the beginning 264 * of the block. 265 * 266 */ 226 267 static void split_mark(heap_block_head_t *cur, const size_t size) 227 268 { … … 243 284 244 285 /** Allocate a memory block 286 * 287 * Should be called only inside the critical section. 245 288 * 246 289 * @param size The size of the block to allocate. … … 356 399 } 357 400 401 /** Allocate memory by number of elements 402 * 403 * @param nmemb Number of members to allocate. 404 * @param size Size of one member in bytes. 405 * 406 * @return Allocated memory or NULL. 407 * 408 */ 358 409 void *calloc(const size_t nmemb, const size_t size) 359 410 { … … 361 412 if (block == NULL) 362 413 return NULL; 363 414 364 415 memset(block, 0, nmemb * size); 365 416 return block; 366 417 } 367 418 419 /** Allocate memory 420 * 421 * @param size Number of bytes to allocate. 422 * 423 * @return Allocated memory or NULL. 424 * 425 */ 368 426 void *malloc(const size_t size) 369 427 { 370 return malloc_internal(size, BASE_ALIGN); 371 } 372 428 futex_down(&malloc_futex); 429 void *block = malloc_internal(size, BASE_ALIGN); 430 futex_up(&malloc_futex); 431 432 return block; 433 } 434 435 /** Allocate memory with specified alignment 436 * 437 * @param align Alignment in byes. 438 * @param size Number of bytes to allocate. 439 * 440 * @return Allocated memory or NULL. 441 * 442 */ 373 443 void *memalign(const size_t align, const size_t size) 374 444 { … … 379 449 1 << (fnzb(max(sizeof(void *), align) - 1) + 1); 380 450 381 return malloc_internal(size, palign); 382 } 383 451 futex_down(&malloc_futex); 452 void *block = malloc_internal(size, palign); 453 futex_up(&malloc_futex); 454 455 return block; 456 } 457 458 /** Reallocate memory block 459 * 460 * @param addr Already allocated memory or NULL. 461 * @param size New size of the memory block. 462 * 463 * @return Reallocated memory or NULL. 464 * 465 */ 384 466 void *realloc(const void *addr, const size_t size) 385 467 { 386 468 if (addr == NULL) 387 469 return malloc(size); 470 471 futex_down(&malloc_futex); 388 472 389 473 /* Calculate the position of the header. */ … … 398 482 399 483 void *ptr = NULL; 484 bool reloc = false; 400 485 size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN)); 401 486 size_t orig_size = head->size; … … 415 500 } else { 416 501 /* Look at the next block. If it is free and the size is 417 sufficient then merge the two. */ 502 sufficient then merge the two. Otherwise just allocate 503 a new block, copy the original data into it and 504 free the original block. */ 418 505 heap_block_head_t *next_head = 419 506 (heap_block_head_t *) (((void *) head) + head->size); … … 427 514 428 515 ptr = ((void *) head) + sizeof(heap_block_head_t); 429 } else { 430 ptr = malloc(size); 431 if (ptr != NULL) { 432 memcpy(ptr, addr, NET_SIZE(orig_size)); 433 free(addr); 434 } 516 } else 517 reloc = true; 518 } 519 520 futex_up(&malloc_futex); 521 522 if (reloc) { 523 ptr = malloc(size); 524 if (ptr != NULL) { 525 memcpy(ptr, addr, NET_SIZE(orig_size)); 526 free(addr); 435 527 } 436 528 } … … 442 534 * 443 535 * @param addr The address of the block. 536 * 444 537 */ 445 538 void free(const void *addr) 446 539 { 540 futex_down(&malloc_futex); 541 447 542 /* Calculate the position of the header. */ 448 543 heap_block_head_t *head … … 483 578 484 579 shrink_heap(); 580 581 futex_up(&malloc_futex); 485 582 } 486 583
Note:
See TracChangeset
for help on using the changeset viewer.