Changeset db24058 in mainline for uspace/lib/libc/generic/as.c
- Timestamp:
- 2009-06-30T15:53:15Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2d11a7d8
- Parents:
- 6db6fd1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/as.c
r6db6fd1 rdb24058 39 39 #include <sys/types.h> 40 40 #include <bitops.h> 41 #include <malloc.h> 41 42 42 /** 43 * Either 4*256M on 32-bit architecures or 16*256M on 64-bit architectures. 44 */ 45 #define MAX_HEAP_SIZE (sizeof(uintptr_t)<<28) 43 /** Last position allocated by as_get_mappable_page */ 44 static uintptr_t last_allocated = 0; 46 45 47 46 /** Create address space area. 48 47 * 49 48 * @param address Virtual address where to place new address space area. 50 * @param size Size of the area.51 * @param flags Flags describing type of the area.49 * @param size Size of the area. 50 * @param flags Flags describing type of the area. 52 51 * 53 52 * @return address on success, (void *) -1 otherwise. 53 * 54 54 */ 55 55 void *as_area_create(void *address, size_t size, int flags) 56 56 { 57 return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t 57 return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address, 58 58 (sysarg_t) size, (sysarg_t) flags); 59 59 } … … 62 62 * 63 63 * @param address Virtual address pointing into already existing address space 64 * 65 * @param size New requested size of the area.66 * @param flags Currently unused.64 * area. 65 * @param size New requested size of the area. 66 * @param flags Currently unused. 67 67 * 68 * @return Zero on success or a code from @ref errno.h on failure. 68 * @return zero on success or a code from @ref errno.h on failure. 69 * 69 70 */ 70 71 int as_area_resize(void *address, size_t size, int flags) 71 72 { 72 return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t 73 return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t) address, 73 74 (sysarg_t) size, (sysarg_t) flags); 74 75 } … … 77 78 * 78 79 * @param address Virtual address pointing into the address space area being 79 * 80 * destroyed. 80 81 * 81 * @return Zero on success or a code from @ref errno.h on failure. 82 * @return zero on success or a code from @ref errno.h on failure. 83 * 82 84 */ 83 85 int as_area_destroy(void *address) 84 86 { 85 return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t 87 return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t) address); 86 88 } 87 89 … … 89 91 * 90 92 * @param address Virtual address pointing into the address space area being 91 * 92 * @param flags New flags describing type of the area.93 * modified. 94 * @param flags New flags describing type of the area. 93 95 * 94 * @return Zero on success or a code from @ref errno.h on failure. 96 * @return zero on success or a code from @ref errno.h on failure. 97 * 95 98 */ 96 99 int as_area_change_flags(void *address, int flags) … … 100 103 } 101 104 102 static size_t heapsize = 0; 103 static size_t maxheapsize = (size_t) (-1); 104 105 static void *last_allocated = 0; 106 107 /* Start of heap linker symbol */ 108 extern char _heap; 109 110 /** Sbrk emulation 105 /** Return pointer to some unmapped area, where fits new as_area 111 106 * 112 * @param incr New area that should be allocated or negative, 113 if it should be shrinked 114 * @return Pointer to newly allocated area 107 * @param size Requested size of the allocation. 108 * 109 * @return pointer to the beginning 110 * 115 111 */ 116 void * sbrk(ssize_t incr)112 void *as_get_mappable_page(size_t size) 117 113 { 118 int rc; 119 void *res; 120 121 /* Check for invalid values */ 122 if ((incr < 0) && (((size_t) -incr) > heapsize)) 114 if (size == 0) 123 115 return NULL; 124 116 125 /* Check for too large value */ 126 if ((incr > 0) && (incr + heapsize < heapsize)) 127 return NULL; 128 129 /* Check for too small values */ 130 if ((incr < 0) && (incr + heapsize > heapsize)) 131 return NULL; 132 133 /* Check for user limit */ 134 if ((maxheapsize != (size_t) (-1)) && (heapsize + incr) > maxheapsize) 135 return NULL; 136 137 rc = as_area_resize(&_heap, heapsize + incr, 0); 138 if (rc != 0) 139 return NULL; 140 141 /* Compute start of new area */ 142 res = (void *) &_heap + heapsize; 143 144 heapsize += incr; 145 146 return res; 147 } 148 149 /** Set maximum heap size and return pointer just after the heap */ 150 void *set_maxheapsize(size_t mhs) 151 { 152 maxheapsize = mhs; 153 /* Return pointer to area not managed by sbrk */ 154 return ((void *) &_heap + maxheapsize); 155 } 156 157 /** Return pointer to some unmapped area, where fits new as_area 158 * 159 * @param sz Requested size of the allocation. 160 * 161 * @return Pointer to the beginning 162 * 163 * TODO: make some first_fit/... algorithm, we are now just incrementing 164 * the pointer to last area 165 */ 166 void *as_get_mappable_page(size_t sz) 167 { 168 void *res; 169 uint64_t asz; 170 int i; 171 172 if (!sz) 173 return NULL; 174 175 asz = 1 << (fnzb64(sz - 1) + 1); 176 177 /* Set heapsize to some meaningful value */ 178 if (maxheapsize == (size_t) -1) 179 set_maxheapsize(MAX_HEAP_SIZE); 117 size_t sz = 1 << (fnzb(size - 1) + 1); 118 if (last_allocated == 0) 119 last_allocated = get_max_heap_addr(); 180 120 181 121 /* 182 122 * Make sure we allocate from naturally aligned address. 183 123 */ 184 i = 0; 185 if (!last_allocated) { 186 last_allocated = (void *) ALIGN_UP((void *) &_heap + 187 maxheapsize, asz); 188 } else { 189 last_allocated = (void *) ALIGN_UP(((uintptr_t) 190 last_allocated) + (int) (i > 0), asz); 191 } 192 193 res = last_allocated; 194 last_allocated += ALIGN_UP(sz, PAGE_SIZE); 195 196 return res; 124 uintptr_t res = ALIGN_UP(last_allocated, sz); 125 last_allocated = res + ALIGN_UP(size, PAGE_SIZE); 126 127 return ((void *) res); 197 128 } 198 129
Note:
See TracChangeset
for help on using the changeset viewer.