1*c9945492SAndroid Build Coastguard Worker #include <stdlib.h> 2*c9945492SAndroid Build Coastguard Worker #include <errno.h> 3*c9945492SAndroid Build Coastguard Worker #include "meta.h" 4*c9945492SAndroid Build Coastguard Worker aligned_alloc(size_t align,size_t len)5*c9945492SAndroid Build Coastguard Workervoid *aligned_alloc(size_t align, size_t len) 6*c9945492SAndroid Build Coastguard Worker { 7*c9945492SAndroid Build Coastguard Worker if ((align & -align) != align) { 8*c9945492SAndroid Build Coastguard Worker errno = EINVAL; 9*c9945492SAndroid Build Coastguard Worker return 0; 10*c9945492SAndroid Build Coastguard Worker } 11*c9945492SAndroid Build Coastguard Worker 12*c9945492SAndroid Build Coastguard Worker if (len > SIZE_MAX - align || align >= (1ULL<<31)*UNIT) { 13*c9945492SAndroid Build Coastguard Worker errno = ENOMEM; 14*c9945492SAndroid Build Coastguard Worker return 0; 15*c9945492SAndroid Build Coastguard Worker } 16*c9945492SAndroid Build Coastguard Worker 17*c9945492SAndroid Build Coastguard Worker if (DISABLE_ALIGNED_ALLOC) { 18*c9945492SAndroid Build Coastguard Worker errno = ENOMEM; 19*c9945492SAndroid Build Coastguard Worker return 0; 20*c9945492SAndroid Build Coastguard Worker } 21*c9945492SAndroid Build Coastguard Worker 22*c9945492SAndroid Build Coastguard Worker if (align <= UNIT) align = UNIT; 23*c9945492SAndroid Build Coastguard Worker 24*c9945492SAndroid Build Coastguard Worker unsigned char *p = malloc(len + align - UNIT); 25*c9945492SAndroid Build Coastguard Worker if (!p) 26*c9945492SAndroid Build Coastguard Worker return 0; 27*c9945492SAndroid Build Coastguard Worker 28*c9945492SAndroid Build Coastguard Worker struct meta *g = get_meta(p); 29*c9945492SAndroid Build Coastguard Worker int idx = get_slot_index(p); 30*c9945492SAndroid Build Coastguard Worker size_t stride = get_stride(g); 31*c9945492SAndroid Build Coastguard Worker unsigned char *start = g->mem->storage + stride*idx; 32*c9945492SAndroid Build Coastguard Worker unsigned char *end = g->mem->storage + stride*(idx+1) - IB; 33*c9945492SAndroid Build Coastguard Worker size_t adj = -(uintptr_t)p & (align-1); 34*c9945492SAndroid Build Coastguard Worker 35*c9945492SAndroid Build Coastguard Worker if (!adj) { 36*c9945492SAndroid Build Coastguard Worker set_size(p, end, len); 37*c9945492SAndroid Build Coastguard Worker return p; 38*c9945492SAndroid Build Coastguard Worker } 39*c9945492SAndroid Build Coastguard Worker p += adj; 40*c9945492SAndroid Build Coastguard Worker uint32_t offset = (size_t)(p-g->mem->storage)/UNIT; 41*c9945492SAndroid Build Coastguard Worker if (offset <= 0xffff) { 42*c9945492SAndroid Build Coastguard Worker *(uint16_t *)(p-2) = offset; 43*c9945492SAndroid Build Coastguard Worker p[-4] = 0; 44*c9945492SAndroid Build Coastguard Worker } else { 45*c9945492SAndroid Build Coastguard Worker // use a 32-bit offset if 16-bit doesn't fit. for this, 46*c9945492SAndroid Build Coastguard Worker // 16-bit field must be zero, [-4] byte nonzero. 47*c9945492SAndroid Build Coastguard Worker *(uint16_t *)(p-2) = 0; 48*c9945492SAndroid Build Coastguard Worker *(uint32_t *)(p-8) = offset; 49*c9945492SAndroid Build Coastguard Worker p[-4] = 1; 50*c9945492SAndroid Build Coastguard Worker } 51*c9945492SAndroid Build Coastguard Worker p[-3] = idx; 52*c9945492SAndroid Build Coastguard Worker set_size(p, end, len); 53*c9945492SAndroid Build Coastguard Worker // store offset to aligned enframing. this facilitates cycling 54*c9945492SAndroid Build Coastguard Worker // offset and also iteration of heap for debugging/measurement. 55*c9945492SAndroid Build Coastguard Worker // for extreme overalignment it won't fit but these are classless 56*c9945492SAndroid Build Coastguard Worker // allocations anyway. 57*c9945492SAndroid Build Coastguard Worker *(uint16_t *)(start - 2) = (size_t)(p-start)/UNIT; 58*c9945492SAndroid Build Coastguard Worker start[-3] = 7<<5; 59*c9945492SAndroid Build Coastguard Worker return p; 60*c9945492SAndroid Build Coastguard Worker } 61