/** Free a memory block * * @param addr The address of the block. * */ void free(const void *addr) { if (addr == NULL) return; futex_down(&malloc_futex); /* Calculate the position of the header. */ heap_block_head_t *head = (heap_block_head_t *) (addr - sizeof(heap_block_head_t)); block_check(head); malloc_assert(!head->free); heap_area_t *area = head->area; area_check(area); malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area)); malloc_assert((void *) head < area->end); /* Mark the block itself as free. */ head->free = true; /* Look at the next block. If it is free, merge the two. */ heap_block_head_t *next_head = (heap_block_head_t *) (((void *) head) + head->size); if ((void *) next_head < area->end) { block_check(next_head); if (next_head->free) block_init(head, head->size + next_head->size, true, area); } /* Look at the previous block. If it is free, merge the two. */ if ((void *) head > (void *) AREA_FIRST_BLOCK_HEAD(area)) { heap_block_foot_t *prev_foot = (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t)); heap_block_head_t *prev_head = (heap_block_head_t *) (((void *) head) - prev_foot->size); block_check(prev_head); if (prev_head->free) block_init(prev_head, prev_head->size + head->size, true, area); } heap_shrink(area); futex_up(&malloc_futex); }
uint32_t nrf_mem_init(void) { NRF_LOG_DEBUG("[MM]: >> nrf_mem_init.\r\n"); SDK_MUTEX_INIT(m_mm_mutex); MM_MUTEX_LOCK(); uint32_t block_index = 0; for (block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++) { block_init(block_index); } #if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0) m_module_initialized = true; #endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS nrf_mem_diagnose(); #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS MM_MUTEX_UNLOCK(); NRF_LOG_DEBUG("[MM]: << nrf_mem_init.\r\n"); return NRF_SUCCESS; }
/** Create new heap area * * Should be called only inside the critical section. * * @param size Size of the area. * */ static bool area_create(size_t size) { /* Align the heap area size on page boundary */ size_t asize = ALIGN_UP(size, PAGE_SIZE); void *astart = as_area_create(AS_AREA_ANY, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE); if (astart == AS_MAP_FAILED) return false; heap_area_t *area = (heap_area_t *) astart; area->start = astart; area->end = (void *) ((uintptr_t) astart + asize); area->prev = NULL; area->next = NULL; area->magic = HEAP_AREA_MAGIC; void *block = (void *) AREA_FIRST_BLOCK_HEAD(area); size_t bsize = (size_t) (area->end - block); block_init(block, bsize, true, area); if (last_heap_area == NULL) { first_heap_area = area; last_heap_area = area; } else { area->prev = last_heap_area; last_heap_area->next = area; last_heap_area = area; } return true; }
void sha1_init (sha1_context* ctxt) { if (ctxt == NULL) return; sha1_init_hash (ctxt->hash); block_init (&ctxt->b, BLOCK_SIZE_512, ctxt->buffer, process_block, ctxt->hash); }
void static_allocator_init(StaticAllocator *sa) { sa->Blocks = (Block *) emalloc(sizeof(Block)); block_init(sa->Blocks, ALLOCATOR_BLOCK_SIZE); sa->num_blocks = 1; sa->current_block = 0; }
int file_mknod(int fd, int driver_pid, struct file *files[], int dev, struct memory_pool *memory_pool, struct event_monitor *event_monitor) { int result; switch(dev) { case S_IFIFO: result = fifo_init(fd, driver_pid, files, memory_pool, event_monitor); break; case S_IMSGQ: result = mq_init(fd, driver_pid, files, memory_pool, event_monitor); break; case S_IFBLK: result = block_init(fd, driver_pid, files, memory_pool, event_monitor); break; case S_IFREG: result = regfile_init(fd, driver_pid, files, memory_pool, event_monitor); break; default: result = -1; } if (result == 0) { files[fd]->fd = fd; } return result; }
void nrf_free(void * p_mem) { VERIFY_MODULE_INITIALIZED_VOID(); NULL_PARAM_CHECK_VOID(p_mem); NRF_LOG_DEBUG("[MM]: >> nrf_free %p.\r\n", (uint32_t)p_mem); MM_MUTEX_LOCK(); uint32_t index; uint32_t memory_index = 0; for (index = 0; index < TOTAL_BLOCK_COUNT; index++) { if (&m_memory[memory_index] == p_mem) { // Found a free block of memory, assign. NRF_LOG_DEBUG("[MM]: << Freeing block %d.\r\n", index); block_init(index); break; } memory_index += get_block_size(index); } MM_MUTEX_UNLOCK(); NRF_LOG_DEBUG("[MM]: << nrf_free.\r\n"); return; }
/** Split heap block and mark it as used. * * Should be called only inside the critical section. * * @param cur Heap block to split. * @param size Number of bytes to split and mark from the beginning * of the block. * */ static void split_mark(heap_block_head_t *cur, const size_t size) { malloc_assert(cur->size >= size); /* See if we should split the block. */ size_t split_limit = GROSS_SIZE(size); if (cur->size > split_limit) { /* Block big enough -> split. */ void *next = ((void *) cur) + size; block_init(next, cur->size - size, true, cur->area); block_init(cur, size, false, cur->area); } else { /* Block too small -> use as is. */ cur->free = false; } }
static block_t *_block_cache_get(block_cache_t *cache, uint64_t ino, off_t off, int *flag) { for (size_t i = 0; i < cache->cached; i++) { if (cache->ino[i] == ino && cache->off[i] == off) { block_t *result = cache->block[i]; if (i < cache->cached - 1) { size_t j = cache->cached - 1; cache->block[i] = cache->block[j]; cache->ino[i] = cache->ino[j]; cache->off[i] = cache->off[j]; cache->block[j] = NULL; cache->ino[j] = 0; cache->off[j] = 0; } else { cache->block[i] = NULL; cache->ino[i] = 0; cache->off[i] = 0; } cache->cached--; *flag = 1; return result; } } if (cache->free) { size_t i = BLOCK_CACHE_SIZE - (cache->free--); block_t *result = cache->block[i]; cache->block[i] = NULL; *flag = 0; return result; } if (cache->allocated < BLOCK_CACHE_SIZE) { block_t *new_block = malloc(sizeof(block_t)); if (block_init(new_block, cache->blksize)) { fprintf(stderr, "block_init failed\n"); free(new_block); } else { cache->allocated++; *flag = 0; return new_block; } } if (cache->cached) { size_t i = --cache->cached; block_t *result = cache->block[i]; cache->block[i] = NULL; cache->ino[i] = 0; cache->off[i] = 0; *flag = 0; return result; } assert(0); // you're probably leaking blocks return NULL; }
int GGPROTO::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam) { switch( eventType ) { case EV_PROTO_ONLOAD: { HookProtoEvent(ME_OPT_INITIALISE, &GGPROTO::options_init); HookProtoEvent(ME_USERINFO_INITIALISE, &GGPROTO::details_init); // Init misc stuff gg_icolib_init(); initpopups(); gc_init(); keepalive_init(); img_init(); block_init(); // Try to fetch user avatar getOwnAvatar(); break; } case EV_PROTO_ONEXIT: // Stop avatar request thread pth_avatar.dwThreadId = 0; // Stop main connection session thread pth_sess.dwThreadId = 0; img_shutdown(); sessions_closedlg(); break; case EV_PROTO_ONOPTIONS: return options_init(wParam, lParam); case EV_PROTO_ONMENU: menus_init(); break; case EV_PROTO_ONRENAME: if (hMenuRoot) { CLISTMENUITEM mi = { sizeof(mi) }; mi.flags = CMIM_NAME | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; mi.ptszName = m_tszUserName; Menu_ModifyItem(hMenuRoot, &mi); } break; case EV_PROTO_ONCONTACTDELETED: return contactdeleted(wParam, lParam); case EV_PROTO_DBSETTINGSCHANGED: return dbsettingchanged(wParam, lParam); } return TRUE; }
int main(){ MonopolyMap map; Block block; block_init(&block); // save( cplayer, map ); return 0; }
/** Try to enlarge a heap area * * Should be called only inside the critical section. * * @param area Heap area to grow. * @param size Gross size to grow (bytes). * * @return True if successful. * */ static bool area_grow(heap_area_t *area, size_t size) { if (size == 0) return true; area_check(area); /* New heap area size */ size_t gross_size = (size_t) (area->end - area->start) + size; size_t asize = ALIGN_UP(gross_size, PAGE_SIZE); void *end = (void *) ((uintptr_t) area->start + asize); /* Check for overflow */ if (end < area->start) return false; /* Resize the address space area */ int ret = as_area_resize(area->start, asize, 0); if (ret != EOK) return false; heap_block_head_t *last_head = (heap_block_head_t *) AREA_LAST_BLOCK_HEAD(area); if (last_head->free) { /* Add the new space to the last block. */ size_t net_size = (size_t) (end - area->end) + last_head->size; malloc_assert(net_size > 0); block_init(last_head, net_size, true, area); } else { /* Add new free block */ size_t net_size = (size_t) (end - area->end); if (net_size > 0) block_init(area->end, net_size, true, area); } /* Update heap area parameters */ area->end = end; return true; }
static int check(const struct TEST_VECTOR *test) { unsigned char out[MAX_OUT_LEN]; struct BLOCK_MODE_STATE ctx; size_t total = 0, out_len; struct BLOCK_STATE blk; if (!prim_avail(test->cipher)) return 1; ASSERT_SUCCESS(block_init(&blk, test->key, test->key_len, test->cipher, 0)); ASSERT_SUCCESS(block_mode_init(&ctx, &blk, test->iv, test->iv_len, 1, BLOCK_MODE_ECB, test->use_params ? &test->params : 0)); block_mode_update(&ctx, &blk, test->in, test->in_len, out, &out_len); total += out_len; ASSERT_SUCCESS(block_mode_final(&ctx, &blk, out + total, &out_len)); total += out_len; ASSERT_EQ(total, test->out_len); ASSERT_BUF_EQ(out, test->out, test->out_len); total = 0; ASSERT_SUCCESS(block_mode_init(&ctx, &blk, test->iv, test->iv_len, 0, BLOCK_MODE_ECB, test->use_params ? &test->params : 0)); block_mode_update(&ctx, &blk, test->out, test->out_len, out, &out_len); total += out_len; ASSERT_SUCCESS(block_mode_final(&ctx, &blk, out + total, &out_len)); total += out_len; ASSERT_EQ(total, test->in_len); ASSERT_BUF_EQ(out, test->in, test->in_len); block_final(&blk); return 1; }
int main(int argc, char *argv[]) { int p = 0; int rerrno = 0; FILE *fp; int len; uint8_t *d; // int v; printf("Running FAT tests...\n\n"); printf("[%4d] start block device emulation...", p++); printf(" %d\n", block_init()); printf("[%4d] mount filesystem, FAT32", p++); printf(" %d\n", fat_mount(0, PART_TYPE_FAT32)); // p = test_open(p); int fd; // printf("Open\n"); // fd = fat_open("/newfile.txt", O_WRONLY | O_CREAT, 0777, &rerrno); // printf("fd = %d, errno=%d (%s)\n", fd, rerrno, strerror(rerrno)); // if(fd > -1) { // printf("Write\n"); // fat_write(fd, "Hello World\n", 12, &rerrno); // printf("errno=%d (%s)\n", rerrno, strerror(rerrno)); // printf("Close\n"); // fat_close(fd, &rerrno); // printf("errno=%d (%s)\n", rerrno, strerror(rerrno)); // } printf("Open\n"); fd = fat_open("/newfile.png", O_WRONLY | O_CREAT, 0777, &rerrno); printf("fd = %d, errno=%d (%s)\n", fd, rerrno, strerror(rerrno)); if(fd > -1) { fp = fopen("/home/nathan/gowrong_draft1.png", "rb"); fseek(fp, 0, SEEK_END); len = ftell(fp); d = malloc(len); fseek(fp, 0, SEEK_SET); fread(d, 1, len, fp); fclose(fp); printf("Write PNG\n"); fat_write(fd, d, len, &rerrno); printf("errno=%d (%s)\n", rerrno, strerror(rerrno)); printf("Close\n"); fat_close(fd, &rerrno); printf("errno=%d (%s)\n", rerrno, strerror(rerrno)); } block_pc_snapshot_all("writenfs.img"); exit(0); }
struct cfile *cfile_init(char *filename) { struct cfile *cfile; struct node *node = parse(filename); if (!node) return NULL; cfile = xmalloc(sizeof(struct cfile)); cfile->name = xmalloc(strlen(filename) + 1); strcpy(cfile->name, filename); cfile->node = node; cfile->block = block_init(cfile->node); return cfile; }
double triple_scalar_product(const gsl_vector *u, const gsl_vector *v, const gsl_vector *w) { double space[3], result; gsl_block b = block_init(3, space); gsl_vector vxw = vector_init(b, 0, 3, 1); cross_product(v, w, &vxw); gsl_blas_ddot(u, &vxw, &result); return result; }
char *static_allocator_allocate(StaticAllocator *sa, zend_uint size) { char *retval; retval = block_allocate(&sa->Blocks[sa->current_block], size); if (retval) { return retval; } sa->Blocks = (Block *) erealloc(sa->Blocks, ++sa->num_blocks); sa->current_block++; block_init(&sa->Blocks[sa->current_block], (size > ALLOCATOR_BLOCK_SIZE) ? size : ALLOCATOR_BLOCK_SIZE); retval = block_allocate(&sa->Blocks[sa->current_block], size); return retval; }
void block_rebind(t_scene *sc,void *ptr) { t_block *block=(t_block *)ptr; rebind(sc,"block","bricks",(void **)&block->bricks); rebind(sc,"block","rhizome",(void **)&block->rhizome); rebind(sc,"block","set",(void **)&block->set); rebind(sc,"block","clone",(void **)&block->clone); // reset block->hover=NULL; block->submenu=NULL; t_context *C=ctx_get(); block_init(C->scene,block); }
t_node *block_make(const char *name,const char *type) { t_context *C=ctx_get(); t_node *n_block=scene_add(C->scene,nt_block,name); t_node *n_list=scene_add(C->scene,nt_list,name); t_block *block=n_block->data; set_name(block->type,type); block_init(C->scene,block); block->cls->link(block,n_list); return n_block; }
int GGPROTO::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam) { switch( eventType ) { case EV_PROTO_ONLOAD: HookProtoEvent(ME_OPT_INITIALISE, &GGPROTO::options_init); HookProtoEvent(ME_USERINFO_INITIALISE, &GGPROTO::details_init); // Init misc stuff gg_icolib_init(); initpopups(); gc_init(); keepalive_init(); img_init(); block_init(); // Try to fetch user avatar getOwnAvatar(); break; case EV_PROTO_ONEXIT: // Stop avatar request thread pth_avatar.dwThreadId = 0; // Stop main connection session thread pth_sess.dwThreadId = 0; img_shutdown(); sessions_closedlg(); break; case EV_PROTO_ONOPTIONS: return options_init(wParam, lParam); case EV_PROTO_ONMENU: menus_init(); break; case EV_PROTO_ONCONTACTDELETED: return contactdeleted(wParam, lParam); case EV_PROTO_DBSETTINGSCHANGED: return dbsettingchanged(wParam, lParam); } return TRUE; }
int main (int argc, char **argv) { if (argc < 3) { printf("Invalid number of arguments: <key> [-e | -d] <input>\n"); exit(1); } int mode = (strcmp("-d", argv[2]) == 0) ? DECRYPT : ENCRYPT; unsigned char *input; int input_size = hex_decode(argv[3], &input); unsigned char *key; int key_size = hex_decode(argv[1], &key); printf("mode: %s\n", mode == DECRYPT ? "decrypt" : "encrypt"); block_state *block = malloc(sizeof(block_state)); if (block) memset(block, 0, sizeof(block_state)); unsigned char *e_buffer = malloc(input_size); unsigned char *d_buffer = malloc(input_size); block_init(block, key, key_size); block_encrypt(block, input, e_buffer); block_decrypt(block, e_buffer, d_buffer); printf("input buffer:\n"); print_buffer(input, input_size); printf("encrypted buffer:\n"); print_buffer(e_buffer, input_size); printf("decrypted buffer:\n"); print_buffer(d_buffer, input_size); printf("\n"); free(e_buffer); free(d_buffer); free(block); free(input); free(key); }
struct render * render_init(struct render_init_args *args, void * buffer, int sz) { struct block B; block_init(&B, buffer, sz); struct render * R = (struct render *)block_slice(&B, sizeof(struct render)); memset(R, 0, sizeof(*R)); log_init(&R->log, stderr); new_array(&B, &R->buffer, args->max_buffer, sizeof(struct buffer)); new_array(&B, &R->attrib, args->max_layout, sizeof(struct attrib)); new_array(&B, &R->target, args->max_target, sizeof(struct target)); new_array(&B, &R->texture, args->max_texture, sizeof(struct texture)); new_array(&B, &R->shader, args->max_shader, sizeof(struct shader)); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &R->default_framebuffer); CHECK_GL_ERROR return R; }
void backend_init() { ph_init(); block_init(); type_init(); if (global.params.is64bit) { util_set64(); cod3_set64(); } else { util_set32(); cod3_set32(); } rtlsym_init(); // uses fregsaved, so must be after it's set inside cod3_set* out_config_init(); }
t_block *block_rebind(t_scene *sc,void *ptr) { t_block *block=(t_block *)ptr; check_init("BLOCK",block->name); rebind(sc,"block","bricks",(void **)&block->bricks); // methods block->draw=block_draw; // reset block->selected=NULL; block->submenu=NULL; t_context *C=ctx_get(); block_init(C->scene,block); check_check("BLOCK",block->name); return block; }
static int check(const struct TEST_VECTOR *test) { unsigned char out[MAX_OUT_LEN]; struct BLOCK_STATE state; ASSERT_SUCCESS(block_init(&state, test->key, test->key_len, BLOCK_AES, test->use_params ? &test->params : 0)); memcpy(out, test->in, test->in_len); block_forward(&state, out); ASSERT_BUF_EQ(out, test->out, test->out_len); block_inverse(&state, out); ASSERT_BUF_EQ(out, test->in, test->in_len); block_final(&state); return 1; }
void jacobi_init(vector< vector< vector< hpx::shared_future<block> > > > &futureList, size_t n, size_t block_size) { vector< vector<block> > blockList; block_init(blockList, block_size, n); size_t numBlocks = blockList.size(); futureList[0].resize(numBlocks); futureList[1].resize(numBlocks); for(int i = 0; i < numBlocks; i++){ futureList[0][i].resize(numBlocks); futureList[1][i].resize(numBlocks); } const size_t curr = 1; futureList[curr][0][0] = async( jacobi_kernel_BL, blockList[0][0], blockList[0][1], blockList[1][0] ); for(size_t j = 1; j < numBlocks - 1; j++) { futureList[curr][j][0] = async( jacobi_kernel_left, blockList[j ][0], blockList[j ][1], blockList[j-1][0], blockList[j+1][0] ); } futureList[curr][numBlocks-1][0] = async( jacobi_kernel_TL, blockList[numBlocks-1][0], blockList[numBlocks-1][1], blockList[numBlocks-2][0] ); for(size_t j = 1; j < numBlocks - 1; j++) { futureList[curr][0][j] = async( jacobi_kernel_bot, blockList[0][j ], blockList[0][j-1], blockList[0][j+1], blockList[1][j ] ); for(size_t k = 1; k < numBlocks - 1; k++) { futureList[curr][j][k] = async( jacobi_kernel_mid, blockList[k ][j ], blockList[k ][j-1], blockList[k ][j+1], blockList[k-1][j ], blockList[k+1][j ]); } futureList[curr][numBlocks-1][j] = async( jacobi_kernel_top, blockList[numBlocks-1][j ], blockList[numBlocks-1][j-1], blockList[numBlocks-1][j+1], blockList[numBlocks-2][j ] ); } futureList[curr][0][numBlocks-1] = async( jacobi_kernel_BR, blockList[0][numBlocks-1], blockList[0][numBlocks-2], blockList[1][numBlocks-1]); for(size_t j = 1; j < numBlocks - 1; j++) { futureList[curr][j][numBlocks-1] = async( jacobi_kernel_left, blockList[j ][numBlocks-1], blockList[j ][numBlocks-2], blockList[j-1][numBlocks-1], blockList[j+1][numBlocks-1]); } futureList[curr][numBlocks-1][numBlocks-1] = async( jacobi_kernel_TR, blockList[numBlocks-1][numBlocks-1], blockList[numBlocks-1][numBlocks-2], blockList[numBlocks-2][numBlocks-1]); }
void out_config_init( int model, // 32: 32 bit code // 64: 64 bit code // Windows: set bit 0 to generate MS-COFF instead of OMF bool exe, // true: exe file // false: dll or shared library (generate PIC code) bool trace, // add profiling code bool nofloat, // do not pull in floating point code bool verbose, // verbose compile bool optimize, // optimize code int symdebug, // add symbolic debug information // 1: D // 2: fake it with C symbolic debug info bool alwaysframe, // always create standard function frame bool stackstomp, // add stack stomping code unsigned char avx, // use AVX instruction set (0, 1, 2) bool betterC // implement "Better C" ) { #if MARS //printf("out_config_init()\n"); if (!config.target_cpu) { config.target_cpu = TARGET_PentiumPro; config.target_scheduler = config.target_cpu; } config.fulltypes = CVNONE; config.fpxmmregs = FALSE; config.inline8087 = 1; config.memmodel = 0; config.flags |= CFGuchar; // make sure TYchar is unsigned tytab[TYchar] |= TYFLuns; bool mscoff = model & 1; model &= 32 | 64; #if TARGET_WINDOS if (model == 64) { config.exe = EX_WIN64; config.fpxmmregs = TRUE; config.avx = avx; config.ehmethod = betterC ? EH_NONE : EH_DM; // Not sure we really need these two lines, try removing them later config.flags |= CFGnoebp; config.flags |= CFGalwaysframe; config.flags |= CFGromable; // put switch tables in code segment config.objfmt = OBJ_MSCOFF; } else { config.exe = EX_WIN32; config.ehmethod = betterC ? EH_NONE : EH_WIN32; config.objfmt = mscoff ? OBJ_MSCOFF : OBJ_OMF; } if (exe) config.wflags |= WFexe; // EXE file only optimizations config.flags4 |= CFG4underscore; #endif #if TARGET_LINUX if (model == 64) { config.exe = EX_LINUX64; config.ehmethod = betterC ? EH_NONE : EH_DWARF; config.fpxmmregs = TRUE; config.avx = avx; } else { config.exe = EX_LINUX; config.ehmethod = betterC ? EH_NONE : EH_DWARF; if (!exe) config.flags |= CFGromable; // put switch tables in code segment } config.flags |= CFGnoebp; if (!exe) { config.flags3 |= CFG3pic; config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups } config.objfmt = OBJ_ELF; #endif #if TARGET_OSX config.fpxmmregs = TRUE; config.avx = avx; if (model == 64) { config.exe = EX_OSX64; config.fpxmmregs = TRUE; config.ehmethod = betterC ? EH_NONE : EH_DWARF; } else { config.exe = EX_OSX; config.ehmethod = betterC ? EH_NONE : EH_DWARF; } config.flags |= CFGnoebp; if (!exe) { config.flags3 |= CFG3pic; config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups } config.flags |= CFGromable; // put switch tables in code segment config.objfmt = OBJ_MACH; #endif #if TARGET_FREEBSD if (model == 64) { config.exe = EX_FREEBSD64; config.ehmethod = betterC ? EH_NONE : EH_DWARF; config.fpxmmregs = TRUE; config.avx = avx; } else { config.exe = EX_FREEBSD; config.ehmethod = betterC ? EH_NONE : EH_DWARF; if (!exe) config.flags |= CFGromable; // put switch tables in code segment } config.flags |= CFGnoebp; if (!exe) { config.flags3 |= CFG3pic; config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups } config.objfmt = OBJ_ELF; #endif #if TARGET_OPENBSD if (model == 64) { config.exe = EX_OPENBSD64; config.fpxmmregs = TRUE; config.avx = avx; } else { config.exe = EX_OPENBSD; if (!exe) config.flags |= CFGromable; // put switch tables in code segment } config.flags |= CFGnoebp; config.flags |= CFGalwaysframe; if (!exe) config.flags3 |= CFG3pic; config.objfmt = OBJ_ELF; config.ehmethod = betterC ? EH_NONE : EH_DM; #endif #if TARGET_SOLARIS if (model == 64) { config.exe = EX_SOLARIS64; config.fpxmmregs = TRUE; config.avx = avx; } else { config.exe = EX_SOLARIS; if (!exe) config.flags |= CFGromable; // put switch tables in code segment } config.flags |= CFGnoebp; config.flags |= CFGalwaysframe; if (!exe) config.flags3 |= CFG3pic; config.objfmt = OBJ_ELF; config.ehmethod = betterC ? EH_NONE : EH_DM; #endif config.flags2 |= CFG2nodeflib; // no default library config.flags3 |= CFG3eseqds; #if 0 if (env->getEEcontext()->EEcompile != 2) config.flags4 |= CFG4allcomdat; if (env->nochecks()) config.flags4 |= CFG4nochecks; // no runtime checking #elif TARGET_OSX #else config.flags4 |= CFG4allcomdat; #endif if (trace) config.flags |= CFGtrace; // turn on profiler if (nofloat) config.flags3 |= CFG3wkfloat; configv.verbose = verbose; if (optimize) go_flag((char *)"-o"); if (symdebug) { #if SYMDEB_DWARF configv.addlinenumbers = 1; config.fulltypes = (symdebug == 1) ? CVDWARF_D : CVDWARF_C; #endif #if SYMDEB_CODEVIEW if (config.objfmt == OBJ_MSCOFF) { configv.addlinenumbers = 1; config.fulltypes = CV8; if(symdebug > 1) config.flags2 |= CFG2gms; } else { configv.addlinenumbers = 1; config.fulltypes = CV4; } #endif if (!optimize) config.flags |= CFGalwaysframe; } else { configv.addlinenumbers = 0; config.fulltypes = CVNONE; //config.flags &= ~CFGalwaysframe; } if (alwaysframe) config.flags |= CFGalwaysframe; if (stackstomp) config.flags2 |= CFG2stomp; config.betterC = betterC; ph_init(); block_init(); cod3_setdefault(); if (model == 64) { util_set64(); type_init(); cod3_set64(); } else { util_set32(); type_init(); cod3_set32(); } rtlsym_init(); // uses fregsaved, so must be after it's set inside cod3_set* #endif }
/** Reallocate memory block * * @param addr Already allocated memory or NULL. * @param size New size of the memory block. * * @return Reallocated memory or NULL. * */ void *realloc(const void *addr, const size_t size) { if (addr == NULL) return malloc(size); futex_down(&malloc_futex); /* Calculate the position of the header. */ heap_block_head_t *head = (heap_block_head_t *) (addr - sizeof(heap_block_head_t)); block_check(head); malloc_assert(!head->free); heap_area_t *area = head->area; area_check(area); malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area)); malloc_assert((void *) head < area->end); void *ptr = NULL; bool reloc = false; size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN)); size_t orig_size = head->size; if (orig_size > real_size) { /* Shrink */ if (orig_size - real_size >= STRUCT_OVERHEAD) { /* * Split the original block to a full block * and a trailing free block. */ block_init((void *) head, real_size, false, area); block_init((void *) head + real_size, orig_size - real_size, true, area); heap_shrink(area); } ptr = ((void *) head) + sizeof(heap_block_head_t); } else { /* * Look at the next block. If it is free and the size is * sufficient then merge the two. Otherwise just allocate * a new block, copy the original data into it and * free the original block. */ heap_block_head_t *next_head = (heap_block_head_t *) (((void *) head) + head->size); if (((void *) next_head < area->end) && (head->size + next_head->size >= real_size) && (next_head->free)) { block_check(next_head); block_init(head, head->size + next_head->size, false, area); split_mark(head, real_size); ptr = ((void *) head) + sizeof(heap_block_head_t); next_fit = NULL; } else reloc = true; } futex_up(&malloc_futex); if (reloc) { ptr = malloc(size); if (ptr != NULL) { memcpy(ptr, addr, NET_SIZE(orig_size)); free(addr); } } return ptr; }
/** Allocate memory from heap area starting from given block * * Should be called only inside the critical section. * As a side effect this function also sets the current * pointer on successful allocation. * * @param area Heap area where to allocate from. * @param first_block Starting heap block. * @param final_block Heap block where to finish the search * (may be NULL). * @param real_size Gross number of bytes to allocate. * @param falign Physical alignment of the block. * * @return Address of the allocated block or NULL on not enough memory. * */ static void *malloc_area(heap_area_t *area, heap_block_head_t *first_block, heap_block_head_t *final_block, size_t real_size, size_t falign) { area_check((void *) area); malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area)); malloc_assert((void *) first_block < area->end); for (heap_block_head_t *cur = first_block; (void *) cur < area->end; cur = (heap_block_head_t *) (((void *) cur) + cur->size)) { block_check(cur); /* Finish searching on the final block */ if ((final_block != NULL) && (cur == final_block)) break; /* Try to find a block that is free and large enough. */ if ((cur->free) && (cur->size >= real_size)) { /* * We have found a suitable block. * Check for alignment properties. */ void *addr = (void *) ((uintptr_t) cur + sizeof(heap_block_head_t)); void *aligned = (void *) ALIGN_UP((uintptr_t) addr, falign); if (addr == aligned) { /* Exact block start including alignment. */ split_mark(cur, real_size); next_fit = cur; return addr; } else { /* Block start has to be aligned */ size_t excess = (size_t) (aligned - addr); if (cur->size >= real_size + excess) { /* * The current block is large enough to fit * data in (including alignment). */ if ((void *) cur > (void *) AREA_FIRST_BLOCK_HEAD(area)) { /* * There is a block before the current block. * This previous block can be enlarged to * compensate for the alignment excess. */ heap_block_foot_t *prev_foot = (heap_block_foot_t *) ((void *) cur - sizeof(heap_block_foot_t)); heap_block_head_t *prev_head = (heap_block_head_t *) ((void *) cur - prev_foot->size); block_check(prev_head); size_t reduced_size = cur->size - excess; heap_block_head_t *next_head = ((void *) cur) + excess; if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) { /* * The previous block is not free and there * is enough free space left to fill in * a new free block between the previous * and current block. */ block_init(cur, excess, true, area); } else { /* * The previous block is free (thus there * is no need to induce additional * fragmentation to the heap) or the * excess is small. Therefore just enlarge * the previous block. */ block_init(prev_head, prev_head->size + excess, prev_head->free, area); } block_init(next_head, reduced_size, true, area); split_mark(next_head, real_size); next_fit = next_head; return aligned; } else { /* * The current block is the first block * in the heap area. We have to make sure * that the alignment excess is large enough * to fit a new free block just before the * current block. */ while (excess < STRUCT_OVERHEAD) { aligned += falign; excess += falign; } /* Check for current block size again */ if (cur->size >= real_size + excess) { size_t reduced_size = cur->size - excess; cur = (heap_block_head_t *) (AREA_FIRST_BLOCK_HEAD(area) + excess); block_init((void *) AREA_FIRST_BLOCK_HEAD(area), excess, true, area); block_init(cur, reduced_size, true, area); split_mark(cur, real_size); next_fit = cur; return aligned; } } } } } } return NULL; }
/** Try to shrink heap * * Should be called only inside the critical section. * In all cases the next pointer is reset. * * @param area Last modified heap area. * */ static void heap_shrink(heap_area_t *area) { area_check(area); heap_block_foot_t *last_foot = (heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area); heap_block_head_t *last_head = BLOCK_HEAD(last_foot); block_check((void *) last_head); malloc_assert(last_head->area == area); if (last_head->free) { /* * The last block of the heap area is * unused. The area might be potentially * shrunk. */ heap_block_head_t *first_head = (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(area); block_check((void *) first_head); malloc_assert(first_head->area == area); size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE); if (first_head == last_head) { /* * The entire heap area consists of a single * free heap block. This means we can get rid * of it entirely. */ heap_area_t *prev = area->prev; heap_area_t *next = area->next; if (prev != NULL) { area_check(prev); prev->next = next; } else first_heap_area = next; if (next != NULL) { area_check(next); next->prev = prev; } else last_heap_area = prev; as_area_destroy(area->start); } else if (shrink_size >= SHRINK_GRANULARITY) { /* * Make sure that we always shrink the area * by a multiple of page size and update * the block layout accordingly. */ size_t asize = (size_t) (area->end - area->start) - shrink_size; void *end = (void *) ((uintptr_t) area->start + asize); /* Resize the address space area */ int ret = as_area_resize(area->start, asize, 0); if (ret != EOK) abort(); /* Update heap area parameters */ area->end = end; size_t excess = ((size_t) area->end) - ((size_t) last_head); if (excess > 0) { if (excess >= STRUCT_OVERHEAD) { /* * The previous block cannot be free and there * is enough free space left in the area to * create a new free block. */ block_init((void *) last_head, excess, true, area); } else { /* * The excess is small. Therefore just enlarge * the previous block. */ heap_block_foot_t *prev_foot = (heap_block_foot_t *) (((uintptr_t) last_head) - sizeof(heap_block_foot_t)); heap_block_head_t *prev_head = BLOCK_HEAD(prev_foot); block_check((void *) prev_head); block_init(prev_head, prev_head->size + excess, prev_head->free, area); } } } } next_fit = NULL; }