OLD | NEW |
1 // Copyright (c) 2016, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dartino project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 // This code is ported from the LK repository. To keep the code in | 5 // This code is ported from the LK repository. To keep the code in |
6 // sync the define DARTINO_TARGET_OS_LK provides the code from the LK | 6 // sync the define DARTINO_TARGET_OS_LK provides the code from the LK |
7 // repository. Without the define DARTINO_TARGET_OS_LK this code will | 7 // repository. Without the define DARTINO_TARGET_OS_LK this code will |
8 // build and link for the disco_dartino project. | 8 // build and link for the disco_dartino project. |
9 #ifdef DARTINO_TARGET_OS_LK | 9 #ifdef DARTINO_TARGET_OS_LK |
10 | 10 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 } | 617 } |
618 | 618 |
619 static void *large_alloc(size_t size) | 619 static void *large_alloc(size_t size) |
620 { | 620 { |
621 #ifdef CMPCT_DEBUG | 621 #ifdef CMPCT_DEBUG |
622 size_t requested_size = size; | 622 size_t requested_size = size; |
623 #endif | 623 #endif |
624 size = ROUNDUP(size, 8); | 624 size = ROUNDUP(size, 8); |
625 free_t *free_area = NULL; | 625 free_t *free_area = NULL; |
626 lock(); | 626 lock(); |
627 heap_grow(size, &free_area); | 627 if (heap_grow(size, &free_area) < 0) { |
| 628 return 0; |
| 629 } |
628 void *result = | 630 void *result = |
629 create_allocation_header(free_area, 0, free_area->header.size, free_area
->header.left); | 631 create_allocation_header(free_area, 0, free_area->header.size, free_area
->header.left); |
630 // Normally the 'remaining free space' counter would be decremented when we | 632 // Normally the 'remaining free space' counter would be decremented when we |
631 // unlink the free area from its bucket. However in this case the free | 633 // unlink the free area from its bucket. However in this case the free |
632 // area was too big to go in any bucket and we had it in our own | 634 // area was too big to go in any bucket and we had it in our own |
633 // "free_area" variable so there is no unlinking and we have to adjust the | 635 // "free_area" variable so there is no unlinking and we have to adjust the |
634 // counter here. | 636 // counter here. |
635 theheap.remaining -= free_area->header.size; | 637 theheap.remaining -= free_area->header.size; |
636 unlock(); | 638 unlock(); |
637 #ifdef CMPCT_DEBUG | 639 #ifdef CMPCT_DEBUG |
638 memset(result, ALLOC_FILL, requested_size); | 640 memset(result, ALLOC_FILL, requested_size); |
639 memset((char *)result + requested_size, PADDING_FILL, free_area->header.size
- requested_size); | 641 memset((char *)result + requested_size, PADDING_FILL, |
| 642 free_area->header.size - (requested_size + sizeof(header_t))); |
640 #endif | 643 #endif |
641 return result; | 644 return result; |
642 } | 645 } |
643 | 646 |
644 void cmpct_trim(void) | 647 void cmpct_trim(void) |
645 { | 648 { |
646 // Look at free list entries that are at least as large as one page plus a | 649 // Look at free list entries that are at least as large as one page plus a |
647 // header. They might be at the start or the end of a block, so we can trim | 650 // header. They might be at the start or the end of a block, so we can trim |
648 // them and free the page(s). | 651 // them and free the page(s). |
649 lock(); | 652 lock(); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 | 864 |
862 // Create a new free-list entry of at least size bytes (including the | 865 // Create a new free-list entry of at least size bytes (including the |
863 // allocation header). Called with the lock, apart from during init. | 866 // allocation header). Called with the lock, apart from during init. |
864 static ssize_t heap_grow(size_t size, free_t **bucket) | 867 static ssize_t heap_grow(size_t size, free_t **bucket) |
865 { | 868 { |
866 // The new free list entry will have a header on each side (the | 869 // The new free list entry will have a header on each side (the |
867 // sentinels) so we need to grow the gross heap size by this much more. | 870 // sentinels) so we need to grow the gross heap size by this much more. |
868 size += 2 * sizeof(header_t); | 871 size += 2 * sizeof(header_t); |
869 size = ROUNDUP(size, PAGE_SIZE); | 872 size = ROUNDUP(size, PAGE_SIZE); |
870 void *ptr = page_alloc(size >> PAGE_SIZE_SHIFT, ANY_ARENA); | 873 void *ptr = page_alloc(size >> PAGE_SIZE_SHIFT, ANY_ARENA); |
| 874 if (ptr == NULL) return -1; |
871 theheap.size += size; | 875 theheap.size += size; |
872 if (ptr == NULL) return -1; | |
873 LTRACEF("growing heap by 0x%zx bytes, new ptr %p\n", size, ptr); | 876 LTRACEF("growing heap by 0x%zx bytes, new ptr %p\n", size, ptr); |
874 add_to_heap(ptr, size, bucket); | 877 add_to_heap(ptr, size, bucket); |
875 return size; | 878 return size; |
876 } | 879 } |
877 | 880 |
878 void cmpct_init(void) | 881 void cmpct_init(void) |
879 { | 882 { |
880 LTRACE_ENTRY; | 883 LTRACE_ENTRY; |
881 | 884 |
882 // Create a mutex. | 885 // Create a mutex. |
883 #ifdef DARTINO_TARGET_OS_LK | 886 #ifdef DARTINO_TARGET_OS_LK |
884 mutex_init(&theheap.lock); | 887 mutex_init(&theheap.lock); |
885 #endif | 888 #endif |
886 | 889 |
887 // Initialize the free list. | 890 // Initialize the free list. |
888 for (int i = 0; i < NUMBER_OF_BUCKETS; i++) { | 891 for (int i = 0; i < NUMBER_OF_BUCKETS; i++) { |
889 theheap.free_lists[i] = NULL; | 892 theheap.free_lists[i] = NULL; |
890 } | 893 } |
891 for (int i = 0; i < BUCKET_WORDS; i++) { | 894 for (int i = 0; i < BUCKET_WORDS; i++) { |
892 theheap.free_list_bits[i] = 0; | 895 theheap.free_list_bits[i] = 0; |
893 } | 896 } |
894 | 897 |
895 size_t initial_alloc = HEAP_GROW_SIZE - 2 * sizeof(header_t); | 898 size_t initial_alloc = HEAP_GROW_SIZE - 2 * sizeof(header_t); |
896 | 899 |
897 theheap.remaining = 0; | 900 theheap.remaining = 0; |
898 | 901 |
899 heap_grow(initial_alloc, NULL); | 902 heap_grow(initial_alloc, NULL); |
900 } | 903 } |
OLD | NEW |