Changeset c47e1a8 in mainline for uspace/lib/c/generic/malloc.c
- Timestamp:
- 2010-05-21T07:50:04Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d51ee2b
- Parents:
- cf8cc36 (diff), 15b592b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 moved
-
uspace/lib/c/generic/malloc.c (moved) (moved from uspace/lib/libc/generic/malloc.c ) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/malloc.c
rcf8cc36 rc47e1a8 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 { 165 177 if (size == 0) 178 return false; 179 180 if ((heap_start + size < heap_start) || (heap_end + size < heap_end)) 166 181 return false; 167 182 … … 186 201 } 187 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 */ 188 210 static void shrink_heap(void) 189 211 { … … 193 215 /** Initialize the heap allocator 194 216 * 195 * Find s how much physical memory we have and creates217 * Find how much physical memory we have and create 196 218 * the heap management structures that mark the whole 197 219 * physical memory as a single free block. … … 200 222 void __heap_init(void) 201 223 { 224 futex_down(&malloc_futex); 225 202 226 if (as_area_create((void *) &_heap, PAGE_SIZE, 203 227 AS_AREA_WRITE | AS_AREA_READ)) { … … 210 234 block_init(heap_start, heap_end - heap_start, true); 211 235 } 212 } 213 236 237 futex_up(&malloc_futex); 238 } 239 240 /** Get maximum heap address 241 * 242 */ 214 243 uintptr_t get_max_heap_addr(void) 215 244 { 245 futex_down(&malloc_futex); 246 216 247 if (max_heap_size == (size_t) -1) 217 248 max_heap_size = 218 249 max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE); 219 250 220 return ((uintptr_t) heap_start + max_heap_size); 221 } 222 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 */ 223 267 static void split_mark(heap_block_head_t *cur, const size_t size) 224 268 { … … 240 284 241 285 /** Allocate a memory block 286 * 287 * Should be called only inside the critical section. 242 288 * 243 289 * @param size The size of the block to allocate. … … 353 399 } 354 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 */ 355 409 void *calloc(const size_t nmemb, const size_t size) 356 410 { … … 358 412 if (block == NULL) 359 413 return NULL; 360 414 361 415 memset(block, 0, nmemb * size); 362 416 return block; 363 417 } 364 418 419 /** Allocate memory 420 * 421 * @param size Number of bytes to allocate. 422 * 423 * @return Allocated memory or NULL. 424 * 425 */ 365 426 void *malloc(const size_t size) 366 427 { 367 return malloc_internal(size, BASE_ALIGN); 368 } 369 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 */ 370 443 void *memalign(const size_t align, const size_t size) 371 444 { … … 376 449 1 << (fnzb(max(sizeof(void *), align) - 1) + 1); 377 450 378 return malloc_internal(size, palign); 379 } 380 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 */ 381 466 void *realloc(const void *addr, const size_t size) 382 467 { 383 468 if (addr == NULL) 384 469 return malloc(size); 470 471 futex_down(&malloc_futex); 385 472 386 473 /* Calculate the position of the header. */ … … 395 482 396 483 void *ptr = NULL; 484 bool reloc = false; 397 485 size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN)); 398 486 size_t orig_size = head->size; … … 412 500 } else { 413 501 /* Look at the next block. If it is free and the size is 414 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. */ 415 505 heap_block_head_t *next_head = 416 506 (heap_block_head_t *) (((void *) head) + head->size); … … 424 514 425 515 ptr = ((void *) head) + sizeof(heap_block_head_t); 426 } else { 427 ptr = malloc(size); 428 if (ptr != NULL) { 429 memcpy(ptr, addr, NET_SIZE(orig_size)); 430 free(addr); 431 } 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); 432 527 } 433 528 } … … 439 534 * 440 535 * @param addr The address of the block. 536 * 441 537 */ 442 538 void free(const void *addr) 443 539 { 540 futex_down(&malloc_futex); 541 444 542 /* Calculate the position of the header. */ 445 543 heap_block_head_t *head … … 480 578 481 579 shrink_heap(); 580 581 futex_up(&malloc_futex); 482 582 } 483 583
Note:
See TracChangeset
for help on using the changeset viewer.
