/* _lib7_win32_IO_read_vec : (one_word_unt * int) -> word8vector.Vector * handle nbytes * * Read the specified number of bytes from the specified handle, * returning them in a vector. * * Note: Read operations on console devices do not trap ctrl-C. * ctrl-Cs are placed in the input buffer. */ Val _lib7_win32_IO_read_vec(Task *task, Val arg) { HANDLE h = (HANDLE) WORD_LIB7toC(GET_TUPLE_SLOT_AS_VAL(arg, 0)); DWORD nbytes = (DWORD) GET_TUPLE_SLOT_AS_INT(arg, 1); DWORD n; // Allocate the vector. // Note that this might cause a GC: // Val vec = allocate_nonempty_int1_vector( task, BYTES_TO_WORDS (nbytes) ); if (ReadFile( h, PTR_CAST(void*, vec), nbytes, &n, NULL)) { if (n == 0) { #ifdef WIN32_DEBUG debug_say("_lib7_win32_IO_read_vec: eof on device\n"); #endif return ZERO_LENGTH_STRING__GLOBAL; } if (n < nbytes) { // shrink_fresh_int1_vector( task, vec, BYTES_TO_WORDS(n) ); } /* Allocate header: */ { Val result; SEQHDR_ALLOC (task, result, STRING_TAGWORD, vec, n); return result; } } else {
Val _lib7_P_IO_read (Task* task, Val arg) { //=============== // // Mythryl type: (Int, Int) -> vector_of_one_byte_unts::Vector // fd nbytes // // Read the specified number of bytes from the specified file, // returning them in a vector. // // This fn gets bound as read' in: // // src/lib/std/src/psx/posix-io.pkg // src/lib/std/src/psx/posix-io-64.pkg ENTER_MYTHRYL_CALLABLE_C_FN(__func__); Val vec; int n; int fd = GET_TUPLE_SLOT_AS_INT( arg, 0 ); int nbytes = GET_TUPLE_SLOT_AS_INT( arg, 1 ); if (nbytes == 0) return ZERO_LENGTH_STRING__GLOBAL; // We cannot reference anything on the Mythryl // heap between RELEASE_MYTHRYL_HEAP and RECOVER_MYTHRYL_HEAP // because garbage collection might be moving // it around, so allocate C space in which to do the read: // Mythryl_Heap_Value_Buffer vec_buf; // { char* c_vec = buffer_mythryl_heap_nonvalue( &vec_buf, nbytes ); // buffer_mythryl_heap_nonvalue is from src/c/main/runtime-state.c do { RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL ); // n = read (fd, c_vec, nbytes); // RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ ); // } while (n < 0 && errno == EINTR); // Restart if interrupted by a SIGALRM or SIGCHLD or whatever. if (n < 0) { unbuffer_mythryl_heap_value( &vec_buf ); return RAISE_SYSERR__MAY_HEAPCLEAN(task, n, NULL); } if (n == 0) { unbuffer_mythryl_heap_value( &vec_buf ); return ZERO_LENGTH_STRING__GLOBAL; } // Allocate the vector. // Note that this might trigger a heapcleaning, moving things around: // vec = allocate_nonempty_wordslots_vector__may_heapclean( task, BYTES_TO_WORDS(n), NULL ); memcpy( PTR_CAST(char*, vec), c_vec, n ); unbuffer_mythryl_heap_value( &vec_buf ); } Val result = make_vector_header(task, STRING_TAGWORD, vec, n); EXIT_MYTHRYL_CALLABLE_C_FN(__func__); return result; }
/* This version assumes we do hold the allocation lock. */ ptr_t GC_store_debug_info_inner(ptr_t p, word sz, char *string, word integer) { register word * result = (word *)((oh *)p + 1); /* There is some argument that we should disable signals here. */ /* But that's expensive. And this way things should only appear */ /* inconsistent while we're in the handler. */ GC_ASSERT(GC_size(p) >= sizeof(oh) + sz); GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz))); # ifdef KEEP_BACK_PTRS ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); # endif # ifdef MAKE_BACK_GRAPH ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0); # endif ((oh *)p) -> oh_string = string; ((oh *)p) -> oh_int = integer; # ifndef SHORT_DBG_HDRS ((oh *)p) -> oh_sz = sz; ((oh *)p) -> oh_sf = START_FLAG ^ (word)result; ((word *)p)[BYTES_TO_WORDS(GC_size(p))-1] = result[SIMPLE_ROUNDED_UP_WORDS(sz)] = END_FLAG ^ (word)result; # endif return((ptr_t)result); }
ret_code_t pm_peer_data_load(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, void * p_data, uint16_t * p_length) { VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_data); VERIFY_PARAM_NOT_NULL(p_length); if (ALIGN_NUM(4, *p_length) != *p_length) { return NRF_ERROR_INVALID_PARAM; } pm_peer_data_t peer_data; memset(&peer_data, 0, sizeof(peer_data)); peer_data.length_words = BYTES_TO_WORDS(*p_length); peer_data.data_id = data_id; peer_data.p_all_data = p_data; ret_code_t err_code = pdb_peer_data_load(peer_id, data_id, &peer_data); *p_length = peer_data.length_words * BYTES_PER_WORD; return err_code; }
// Split a large block into two sub-blocks. // spaceLeft and size are in words void *splitFreeBlock(void* blockToSplit, uint64_t spaceLeft, uint32_t size, void* currentFreeBlock, struct freeBlockLinks *currentBlockLinks) { // Reinitialise header of first sub-block. void* block = ADDRESS_MINUS_OFFSET(blockToSplit, blockHeader); struct blockHeader *allocatedBlock = INIT_STRUCT(blockHeader, block); allocatedBlock->attribute = size; // Create and initialise new node. uint32_t sizeNewNode = spaceLeft - BYTES_TO_WORDS(sizeof(blockHeader)); uint64_t sizeOffset = WORDS_TO_BYTES(size); void* endUserRequestedBlock = blockToSplit + sizeOffset; // initialise new block. void* prevBlock = PREV_BLOCK(currentBlockLinks); totalFreeSpace -= WORDS_TO_BYTES(spaceLeft); totalFreeSpace -= WORDS_TO_BYTES(size); // Stats initialiseFreeBlock(endUserRequestedBlock, sizeNewNode, prevBlock, currentFreeBlock, false, true); insertFreeBlock(endUserRequestedBlock, currentBlockLinks); return endUserRequestedBlock; }
GC_INNER GC_bool GC_check_leaked(ptr_t base) { size_t i; size_t obj_sz; word *p; if ( # if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) (*(word *)base & 1) != 0 && # endif GC_has_other_debug_info(base) >= 0) return TRUE; /* object has leaked */ /* Validate freed object's content. */ p = (word *)(base + sizeof(oh)); obj_sz = BYTES_TO_WORDS(HDR(base)->hb_sz - sizeof(oh)); for (i = 0; i < obj_sz; ++i) if (p[i] != GC_FREED_MEM_MARKER) { GC_set_mark_bit(base); /* do not reclaim it in this cycle */ GC_add_smashed((ptr_t)(&p[i])); /* alter-after-free detected */ break; /* don't report any other smashed locations in the object */ } return FALSE; /* GC_debug_free() has been called */ }
/* _lib7_Sock_recv : (Socket, Int, Bool, Bool) -> unt8_vector::Vector * * The arguments are: socket, number of bytes, OOB flag and peek flag; the * result is the vector of bytes received. * * This function gets imported into the Mythryl world via: * src/lib/std/src/socket/socket-guts.pkg */ lib7_val_t _lib7_Sock_recv (lib7_state_t *lib7_state, lib7_val_t arg) { lib7_val_t vec; lib7_val_t result; int n; int socket = REC_SELINT(arg, 0); int nbytes = REC_SELINT(arg, 1); lib7_val_t oob = REC_SEL( arg, 2); lib7_val_t peek = REC_SEL( arg, 3); int flag = 0; if (oob == LIB7_true) flag |= MSG_OOB; if (peek == LIB7_true) flag |= MSG_PEEK; /* Allocate the vector. * Note that this might cause a GC: */ vec = LIB7_AllocRaw32 (lib7_state, BYTES_TO_WORDS(nbytes)); print_if("recv.c/before: socket d=%d nbytes d=%d oob=%s peek=%s\n",socket,nbytes,(oob == LIB7_true)?"TRUE":"FALSE",(peek == LIB7_true)?"TRUE":"FALSE"); errno = 0; /* do { */ /* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c */ n = recv (socket, PTR_LIB7toC(char, vec), nbytes, flag); /* } while (n < 0 && errno == EINTR); */ /* Restart if interrupted by a SIGALRM or SIGCHLD or whatever. */ print_if( "recv.c/after: n d=%d errno d=%d (%s)\n", n, errno, errno ? strerror(errno) : ""); hexdump_if( "recv.c/after: Received data: ", PTR_LIB7toC(unsigned char, vec), n ); if (n < 0) return RAISE_SYSERR(lib7_state, status); else if (n == 0) return LIB7_string0; if (n < nbytes) { /* we need to shrink the vector */ LIB7_ShrinkRaw32 (lib7_state, vec, BYTES_TO_WORDS(n)); } SEQHDR_ALLOC (lib7_state, result, DESC_string, vec, n); return result; }
// lengthMmapRegion in bytes bool coalesceMmapRegions(void* mmapsList, void* newMmapRegion, uint64_t lengthMmapRegion) { void* currentMmapRegion = mmapsList; struct headerMmapRegion *headerMmap = INIT_STRUCT(headerMmapRegion, currentMmapRegion); do { uint64_t oldLength = WORDS_TO_BYTES(headerMmap->length); void* endMmapRegion = currentMmapRegion + oldLength; if(endMmapRegion == newMmapRegion) { // Coalesce mmap regions. uint32_t newLength = headerMmap->length + BYTES_TO_WORDS(lengthMmapRegion); // update size mmap region. headerMmap->length = newLength; // Initialize footer mmap setMmapFooter(currentMmapRegion, WORDS_TO_BYTES(newLength)); // Calculate size new free region. void* beginningFreeRegion = ADDRESS_MINUS_OFFSET(endMmapRegion, blockHeader); uint64_t newFreeSpaceSize = lengthMmapRegion - sizeof(blockHeader); // size free region. struct blockHeader *footerPrevMmapRegion = INIT_STRUCT(blockHeader, beginningFreeRegion); uint32_t flag = GET_FLAG(footerPrevMmapRegion->attribute); // Coalesce with prev block if free. if (flag == MSB_TO_ONE) { void* previous = ADDRESS_MINUS_OFFSET(beginningFreeRegion, freeBlockFooter); struct freeBlockFooter *prevUsableBlockFooter = INIT_STRUCT(freeBlockFooter, previous); uint64_t sizePrevBlock = WORDS_TO_BYTES(prevUsableBlockFooter->size); // Footer has no flag beginningFreeRegion = beginningFreeRegion - sizePrevBlock - sizeof(blockHeader); newFreeSpaceSize += sizeof(blockHeader) + sizePrevBlock; numberFreeBlocks--; totalFreeSpace += newFreeSpaceSize; // Stats uint32_t newFreeSpaceSizeInWords = BYTES_TO_WORDS(newFreeSpaceSize); coalesceWithPrevBlock(beginningFreeRegion, newFreeSpaceSizeInWords); } else { initialiseFreeMmapRegion(beginningFreeRegion, newFreeSpaceSize); } return true; // coalescing. } else { // Check next mmap region currentMmapRegion = NEXT_MMAP_ADDRESS(headerMmap); headerMmap = currentMmapRegion; } } while (headerMmap != NULL && NEXT_MMAP_ADDRESS(headerMmap) != NULL); return false; // no coalescing. }
ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id, pm_peer_data_bonding_t * p_bonding_data, pm_store_token_t * p_token) { ret_code_t err_code; pm_peer_id_t peer_id; pm_peer_data_flash_t peer_data; VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_bonding_data); VERIFY_PARAM_NOT_NULL(p_new_peer_id); memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); // Search through existing bonds to look for a duplicate. pds_peer_data_iterate_prepare(); // @note emdi: should maybe use a critical section, since data is not copied while iterating. while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) { if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data)) { *p_new_peer_id = peer_id; return NRF_SUCCESS; } } // If no duplicate data is found, prepare to write a new bond to flash. *p_new_peer_id = pdb_peer_allocate(); if (*p_new_peer_id == PM_PEER_ID_INVALID) { return NRF_ERROR_NO_MEM; } memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); peer_data.data_id = PM_PEER_DATA_ID_BONDING; peer_data.p_bonding_data = p_bonding_data; peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t)); err_code = pdb_raw_store(*p_new_peer_id, &peer_data, p_token); if (err_code != NRF_SUCCESS) { if (im_peer_free(*p_new_peer_id) != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } // NRF_ERROR_STORAGE_FULL, if no space in flash. // NRF_ERROR_BUSY, if flash filesystem was busy. // NRF_ERROR_INTENRAL, on internal error. return err_code; } return NRF_SUCCESS; }
/* Descriptor is a GC_DS_LENGTH or GC_DS_BITMAP descriptor. */ STATIC GC_descr GC_double_descr(GC_descr descriptor, word nwords) { if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)]; }; descriptor |= (descriptor & ~GC_DS_TAGS) >> nwords; return(descriptor); }
GC_API void GC_CALL GC_debug_free(void * p) { ptr_t base; if (0 == p) return; base = GC_base(p); if (base == 0) { GC_err_printf("Attempt to free invalid pointer %p\n", p); ABORT("Invalid pointer passed to free()"); } if ((ptr_t)p - (ptr_t)base != sizeof(oh)) { GC_err_printf( "GC_debug_free called on pointer %p w/o debugging info\n", p); } else { # ifndef SHORT_DBG_HDRS ptr_t clobbered = GC_check_annotated_obj((oh *)base); word sz = GC_size(base); if (clobbered != 0) { GC_have_errors = TRUE; if (((oh *)base) -> oh_sz == sz) { GC_print_smashed_obj( "GC_debug_free: found previously deallocated (?) object at", p, clobbered); return; /* ignore double free */ } else { GC_print_smashed_obj("GC_debug_free: found smashed location at", p, clobbered); } } /* Invalidate size (mark the object as deallocated) */ ((oh *)base) -> oh_sz = sz; # endif /* SHORT_DBG_HDRS */ } if (GC_find_leak # ifndef SHORT_DBG_HDRS && ((ptr_t)p - (ptr_t)base != sizeof(oh) || !GC_findleak_delay_free) # endif ) { GC_free(base); } else { hdr * hhdr = HDR(p); if (hhdr -> hb_obj_kind == UNCOLLECTABLE # ifdef ATOMIC_UNCOLLECTABLE || hhdr -> hb_obj_kind == AUNCOLLECTABLE # endif ) { GC_free(base); } else { size_t i; size_t obj_sz = BYTES_TO_WORDS(hhdr -> hb_sz - sizeof(oh)); for (i = 0; i < obj_sz; ++i) ((word *)p)[i] = GC_FREED_MEM_MARKER; GC_ASSERT((word *)p + i == (word *)(base + hhdr -> hb_sz)); } } /* !GC_find_leak */ }
/* address. */ STATIC ptr_t GC_check_annotated_obj(oh *ohdr) { ptr_t body = (ptr_t)(ohdr + 1); word gc_sz = GC_size((ptr_t)ohdr); if (ohdr -> oh_sz + DEBUG_BYTES > gc_sz) { return((ptr_t)(&(ohdr -> oh_sz))); } if (ohdr -> oh_sf != (START_FLAG ^ (word)body)) { return((ptr_t)(&(ohdr -> oh_sf))); } if (((word *)ohdr)[BYTES_TO_WORDS(gc_sz)-1] != (END_FLAG ^ (word)body)) { return((ptr_t)((word *)ohdr + BYTES_TO_WORDS(gc_sz)-1)); } if (((word *)body)[SIMPLE_ROUNDED_UP_WORDS(ohdr -> oh_sz)] != (END_FLAG ^ (word)body)) { return((ptr_t)((word *)body + SIMPLE_ROUNDED_UP_WORDS(ohdr->oh_sz))); } return(0); }
void GC_debug_free(void * p) { ptr_t base; ptr_t clobbered; if (0 == p) return; base = GC_base(p); if (base == 0) { GC_err_printf("Attempt to free invalid pointer %p\n", p); ABORT("free(invalid pointer)"); } if ((ptr_t)p - (ptr_t)base != sizeof(oh)) { GC_err_printf( "GC_debug_free called on pointer %p wo debugging info\n", p); } else { # ifndef SHORT_DBG_HDRS clobbered = GC_check_annotated_obj((oh *)base); if (clobbered != 0) { if (((oh *)base) -> oh_sz == GC_size(base)) { GC_err_printf( "GC_debug_free: found previously deallocated (?) object at "); } else { GC_err_printf("GC_debug_free: found smashed location at "); } GC_print_smashed_obj(p, clobbered); } /* Invalidate size */ ((oh *)base) -> oh_sz = GC_size(base); # endif /* SHORT_DBG_HDRS */ } if (GC_find_leak) { GC_free(base); } else { hdr * hhdr = HDR(p); GC_bool uncollectable = FALSE; if (hhdr -> hb_obj_kind == UNCOLLECTABLE) { uncollectable = TRUE; } # ifdef ATOMIC_UNCOLLECTABLE if (hhdr -> hb_obj_kind == AUNCOLLECTABLE) { uncollectable = TRUE; } # endif if (uncollectable) { GC_free(base); } else { size_t i; size_t obj_sz = BYTES_TO_WORDS(hhdr -> hb_sz - sizeof(oh)); for (i = 0; i < obj_sz; ++i) ((word *)p)[i] = 0xdeadbeef; GC_ASSERT((word *)p + i == (word *)(base + hhdr -> hb_sz)); } } /* !GC_find_leak */ }
/* the appropriate free list. */ STATIC GC_bool GC_on_free_list(struct hblk *h) { hdr * hhdr = HDR(h); size_t sz = BYTES_TO_WORDS(hhdr -> hb_sz); ptr_t p; if (sz > MAXOBJWORDS) return(FALSE); for (p = GC_sobjfreelist[sz]; p != 0; p = obj_link(p)) { if (HBLKPTR(p) == h) return(TRUE); } return(FALSE); }
static void per_object_helper(struct hblk *h, word fn) { hdr * hhdr = HDR(h); size_t sz = (size_t)hhdr->hb_sz; word descr = hhdr -> hb_descr; per_object_func f = (per_object_func)fn; size_t i = 0; do { f((ptr_t)(h -> hb_body + i), sz, descr); i += sz; } while (i + sz <= BYTES_TO_WORDS(HBLKSIZE)); }
VectorEncoder::VectorEncoder(usint block_bytes, usint superblock_size, bool _use_small_blocks) : size(0), items(0), blocks(0), block_size(BYTES_TO_WORDS(block_bytes)), superblock_bytes(superblock_size), use_small_blocks(_use_small_blocks), blocks_in_superblock(1), current_blocks(0), samples(0), samples_in_superblock(0), current_samples(0) { this->array = new usint[this->superblock_bytes / sizeof(usint)]; memset(this->array, 0, this->superblock_bytes); if(use_small_blocks) { this->blocks_in_superblock = this->superblock_bytes / (sizeof(usint) * this->block_size); this->buffer = new WriteBuffer(this->array, this->block_size); this->samples = new usint[this->superblock_bytes / sizeof(usint)]; this->samples_in_superblock = this->superblock_bytes / (2 * sizeof(usint)); } else { this->buffer = new WriteBuffer(this->array, BYTES_TO_WORDS(this->superblock_bytes)); this->blocks = this->current_blocks = 1; } }
/*-----------------------------------------------------------------------------* * NAME * readCsBlock * * DESCRIPTION * Read a section of the CS block. * * This function is called when the Host requests the contents of a CS * block, by writing to the OTA_READ_CS_BLOCK handle. This function is * supported only if the application supports the OTA_READ_CS_BLOCK * characteristic. * * PARAMETERS * offset [in] Offset into the CS block to read from, in words. * This is the value written by the Host to the * Characteristic. * length [in] Number of octets to read. * value [out] Buffer to contain block contents * * RETURNS * sys_status_success: The read was successful and "value" contains valid * information. * CSR_OTA_KEY_NOT_READ: The read was unsuccessful and "value" does not * contain valid information. *----------------------------------------------------------------------------*/ static sys_status readCsBlock(uint16 offset, uint8 length, uint8 *value) { /* Check the length is within the packet size and that the read does not * overflow the CS block. */ if ((length > ATTR_LEN_CSR_OTA_DATA_TRANSFER) || (offset + BYTES_TO_WORDS(length) > CSTORE_SIZE)) { return CSR_OTA_KEY_NOT_READ; } MemCopyUnPack(value, (uint16 *)(DATA_CSTORE_START + offset), length); return sys_status_success; }
VectorEncoder::VectorEncoder(usint block_bytes, usint superblock_size) : size(0), items(0), blocks(0), block_size(BYTES_TO_WORDS(block_bytes)), superblock_bytes(superblock_size) { this->array = new usint[this->superblock_bytes / sizeof(usint)]; memset(this->array, 0, this->superblock_bytes); this->blocks_in_superblock = this->superblock_bytes / (sizeof(usint) * this->block_size); this->current_blocks = 0; this->samples = new usint[this->superblock_bytes / sizeof(usint)]; this->samples_in_superblock = this->superblock_bytes / (2 * sizeof(usint)); this->current_samples = 0; this->buffer = new WriteBuffer(this->array, this->block_size); }
STATIC mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr, mse * mark_stack_limit, word env GC_ATTR_UNUSED) { hdr * hhdr = HDR(addr); word sz = hhdr -> hb_sz; word nwords = BYTES_TO_WORDS(sz); complex_descriptor * descr = (complex_descriptor *)(addr[nwords-1]); mse * orig_mark_stack_ptr = mark_stack_ptr; mse * new_mark_stack_ptr; if (descr == 0) { /* Found a reference to a free list entry. Ignore it. */ return(orig_mark_stack_ptr); } /* In use counts were already updated when array descriptor was */ /* pushed. Here we only replace it by subobject descriptors, so */ /* no update is necessary. */ new_mark_stack_ptr = GC_push_complex_descriptor(addr, descr, mark_stack_ptr, mark_stack_limit-1); if (new_mark_stack_ptr == 0) { /* Explicitly instruct Clang Static Analyzer that ptr is non-null. */ if (NULL == mark_stack_ptr) ABORT("Bad mark_stack_ptr"); /* Doesn't fit. Conservatively push the whole array as a unit */ /* and request a mark stack expansion. */ /* This cannot cause a mark stack overflow, since it replaces */ /* the original array entry. */ # ifdef PARALLEL_MARK /* We might be using a local_mark_stack in parallel mode. */ if (GC_mark_stack + GC_mark_stack_size == mark_stack_limit) # endif { GC_mark_stack_too_small = TRUE; } new_mark_stack_ptr = orig_mark_stack_ptr + 1; new_mark_stack_ptr -> mse_start = (ptr_t)addr; new_mark_stack_ptr -> mse_descr.w = sz | GC_DS_LENGTH; } else { /* Push descriptor itself */ new_mark_stack_ptr++; new_mark_stack_ptr -> mse_start = (ptr_t)(addr + nwords - 1); new_mark_stack_ptr -> mse_descr.w = sizeof(word) | GC_DS_LENGTH; } return new_mark_stack_ptr; }
void SuccinctVector::initializeFrom(usint* buffer, usint block_bytes, usint universe_size) { this->size = universe_size; this->block_size = BYTES_TO_WORDS(block_bytes); this->number_of_blocks = (this->size + this->block_size * WORD_BITS - 1) / (this->block_size * WORD_BITS); this->array = buffer; this->integer_bits = length(this->size); this->indexForRank(); if(this->items == 0) { std::cerr << "SuccinctVector: Cannot create a bitvector with no 1-bits!" << std::endl; return; } this->indexForSelect(); }
static Val allocate_heap_ram_for_pickle (Task* task, Vunt bytesize) { // ============================ // // Allocate a bytevector to hold the pickled datastructure. // Heap* heap = task->heap; int size_in_words = BYTES_TO_WORDS( bytesize ); Val tagword = MAKE_TAGWORD( size_in_words, FOUR_BYTE_ALIGNED_NONPOINTER_DATA_BTAG ); // We probably should allocate space in the hugechunk region for these chunks. XXX BUGGO FIXME // if (bytesize >= agegroup0_buffer_size_in_bytes(task)-(8*ONE_K_BINARY)) die ("Pickling %d bytes not supported -- increase agegroup0 buffer size.", bytesize); // XXX BUGGO FIXME set_slot_in_nascent_heapchunk( task, 0, tagword ); return commit_nascent_heapchunk( task, size_in_words ); }
void mmapRegion(uint64_t size) { uint64_t length; bool mmapRegionsCoalesced = false; // Make sure there's enough allocated memory. if (DEFAULT_NUMBER_MMAP_PAGES * sysconf(_SC_PAGE_SIZE) - (sizeof(headerMmapRegion) + sizeof(blockHeader)) < size) { uint64_t numberPages = (uint64_t) (size / sysconf(_SC_PAGE_SIZE)) + 1; length = numberPages * sysconf(_SC_PAGE_SIZE); } else { length = DEFAULT_NUMBER_MMAP_PAGES * sysconf(_SC_PAGE_SIZE); } newMmapRegion = MMAP(length); // TODO: check for errors if (newMmapRegion == MAP_FAILED) { fprintf(stderr, "memoryManagement.mmapRegion - Memory overflow\n"); exit(-1); } // Header Mmap region struct headerMmapRegion *headerMmap = INIT_STRUCT(headerMmapRegion, newMmapRegion); if (!mmapsList) { NEXT_MMAP_ADDRESS(headerMmap) = NULL; } else if (coalesceMmapRegions(mmapsList, newMmapRegion, length)) { mmapRegionsCoalesced = true; } else { NEXT_MMAP_ADDRESS(headerMmap) = mmapsList; // Add the new mmap at front. } if(!mmapRegionsCoalesced) { headerMmap->length = BYTES_TO_WORDS(length); mmapsList = newMmapRegion; // Update the pointer of mmapsList. setMmapFooter(newMmapRegion, length); // Set first free region. void* beginningFreeRegion = ADDRESS_PLUS_OFFSET(newMmapRegion, headerMmapRegion); // header free region and footer mmap to be excluded. uint64_t sizeFreeRegion = length - sizeof(headerMmapRegion) - (2 * sizeof(blockHeader)); initialiseFreeMmapRegion(beginningFreeRegion, sizeFreeRegion); } numberFreeBlocks++; // Add one free block to the counter. }
/* marked as deallocated. */ GC_INNER int GC_has_other_debug_info(ptr_t p) { ptr_t body = (ptr_t)((oh *)p + 1); word sz = GC_size(p); if (HBLKPTR(p) != HBLKPTR((ptr_t)body) || sz < DEBUG_BYTES + EXTRA_BYTES) { return 0; } if (((oh *)p) -> oh_sf != (START_FLAG ^ (word)body) && ((word *)p)[BYTES_TO_WORDS(sz)-1] != (END_FLAG ^ (word)body)) { return 0; } if (((oh *)p)->oh_sz == sz) { /* Object may have had debug info, but has been deallocated */ return -1; } return 1; }
/* its part. */ GC_bool GC_has_other_debug_info(ptr_t p) { register oh * ohdr = (oh *)p; register ptr_t body = (ptr_t)(ohdr + 1); register word sz = GC_size((ptr_t) ohdr); if (HBLKPTR((ptr_t)ohdr) != HBLKPTR((ptr_t)body) || sz < DEBUG_BYTES + EXTRA_BYTES) { return(FALSE); } if (ohdr -> oh_sz == sz) { /* Object may have had debug info, but has been deallocated */ return(FALSE); } if (ohdr -> oh_sf == (START_FLAG ^ (word)body)) return(TRUE); if (((word *)ohdr)[BYTES_TO_WORDS(sz)-1] == (END_FLAG ^ (word)body)) { return(TRUE); } return(FALSE); }
ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, void const * p_data, uint16_t length, pm_store_token_t * p_token) { VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_data); if (ALIGN_NUM(4, length) != length) { return NRF_ERROR_INVALID_PARAM; } pm_peer_data_flash_t peer_data; memset(&peer_data, 0, sizeof(peer_data)); peer_data.length_words = BYTES_TO_WORDS(length); peer_data.data_id = data_id; peer_data.p_all_data = p_data; return pdb_raw_store(peer_id, &peer_data, p_token); }
/* This version assumes we do hold the allocation lock. */ STATIC ptr_t GC_store_debug_info_inner(ptr_t p, word sz, const char *string, int linenum) { word * result = (word *)((oh *)p + 1); GC_ASSERT(GC_size(p) >= sizeof(oh) + sz); GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz))); # ifdef KEEP_BACK_PTRS ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); # endif # ifdef MAKE_BACK_GRAPH ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0); # endif ((oh *)p) -> oh_string = string; ((oh *)p) -> oh_int = (word)linenum; # ifndef SHORT_DBG_HDRS ((oh *)p) -> oh_sz = sz; ((oh *)p) -> oh_sf = START_FLAG ^ (word)result; ((word *)p)[BYTES_TO_WORDS(GC_size(p))-1] = result[SIMPLE_ROUNDED_UP_WORDS(sz)] = END_FLAG ^ (word)result; # endif return((ptr_t)result); }
// Check if the new region is big enough to store a new free block. // if not do not split, but free list now points to next node. void allocateBlock(uint32_t size, uint32_t spaceLeft, uint32_t minFreeRegionSize, uint32_t sizeFreeRegion, void* freeBlock, void* currentFreeBlock, struct freeBlockLinks *currentBlockLinks) { if (spaceLeft > minFreeRegionSize) { if (sufficientSize(size)) { freeList = splitFreeBlock(freeBlock, spaceLeft, size, currentFreeBlock, currentBlockLinks); } else { minFreeRegionSize -= BYTES_TO_WORDS(sizeof(freeBlockFooter)); freeList = splitFreeBlock(freeBlock, spaceLeft, minFreeRegionSize, currentFreeBlock, currentBlockLinks); } numberFreeBlocks++; } else { // No split. // If successor is mmap footer, then set its flag to 0. totalFreeSpace -= WORDS_TO_BYTES(sizeFreeRegion); uint64_t sizeOffset = WORDS_TO_BYTES(sizeFreeRegion); void* next = ADDRESS_PLUS_OFFSET(currentFreeBlock + sizeOffset, blockHeader); struct blockHeader *nextBlockHeader = INIT_STRUCT(blockHeader, next); // check if last one (size = 0.) if (nextBlockHeader->attribute == MSB_TO_ONE) { // Tell next that block is not free anymore. nextBlockHeader->attribute = MSB_TO_ZERO; } else { // If next block is not last one, then just set its flag to zero and keep size. // Flag is automatically set to zero. nextBlockHeader->attribute = GET_SIZE(nextBlockHeader->attribute); } freeList = NEXT_BLOCK(currentBlockLinks); } }
// size free region in bytes void initialiseFreeMmapRegion(void* beginningFreeRegion, uint64_t sizeFreeRegion) { uint32_t sizeFreeRegionInWords = BYTES_TO_WORDS(sizeFreeRegion); // headerMmapsize in words. if(!freeList) { freeList = beginningFreeRegion; // Initialise the free list. initialiseFreeBlock(beginningFreeRegion, sizeFreeRegionInWords, beginningFreeRegion, beginningFreeRegion, false, true); } else { // Add to free list. void *currentBlock = freeList; void* links = ADDRESS_PLUS_OFFSET(currentBlock, blockHeader); struct freeBlockLinks *currentBlockLinks = INIT_STRUCT(freeBlockLinks, links); void* prevBlock = PREV_BLOCK(currentBlockLinks); initialiseFreeBlock(beginningFreeRegion, sizeFreeRegionInWords, prevBlock, currentBlock, false, true); // Tell next block that its previous one is NOW free. uint64_t sizeOffset = WORDS_TO_BYTES(sizeFreeRegionInWords); updateNextBlockOnCoalescing(beginningFreeRegion, sizeFreeRegion); insertFreeBlock(beginningFreeRegion, currentBlockLinks); } }
static int send_recv_packets( struct i2c_bus *i2c_bus, struct i2c_trans_info *trans) { struct i2c_control *control = i2c_bus->control; u32 int_status; u32 words; u8 *dptr; u32 local; uchar last_bytes; int error = 0; int is_write = trans->flags & I2C_IS_WRITE; /* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */ int_status = readl(&control->int_status); writel(int_status, &control->int_status); send_packet_headers(i2c_bus, trans, 1); words = BYTES_TO_WORDS(trans->num_bytes); last_bytes = trans->num_bytes & 3; dptr = trans->buf; while (words) { if (is_write) { /* deal with word alignment */ if ((unsigned)dptr & 3) { memcpy(&local, dptr, sizeof(u32)); writel(local, &control->tx_fifo); debug("pkt data sent (0x%x)\n", local); } else { writel(*(u32 *)dptr, &control->tx_fifo); debug("pkt data sent (0x%x)\n", *(u32 *)dptr); } if (!wait_for_tx_fifo_empty(control)) { error = -1; goto exit; } } else { if (!wait_for_rx_fifo_notempty(control)) { error = -1; goto exit; } /* * for the last word, we read into our local buffer, * in case that caller did not provide enough buffer. */ local = readl(&control->rx_fifo); if ((words == 1) && last_bytes) memcpy(dptr, (char *)&local, last_bytes); else if ((unsigned)dptr & 3) memcpy(dptr, &local, sizeof(u32)); else *(u32 *)dptr = local; debug("pkt data received (0x%x)\n", local); } words--; dptr += sizeof(u32); } if (wait_for_transfer_complete(control)) { error = -1; goto exit; } return 0; exit: /* error, reset the controller. */ i2c_reset_controller(i2c_bus); return error; }
STATIC int GC_make_array_descriptor(size_t nelements, size_t size, GC_descr descriptor, GC_descr *simple_d, complex_descriptor **complex_d, struct LeafDescriptor * leaf) { # define OPT_THRESHOLD 50 /* For larger arrays, we try to combine descriptors of adjacent */ /* descriptors to speed up marking, and to reduce the amount */ /* of space needed on the mark stack. */ if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { if (descriptor == (GC_descr)size) { *simple_d = nelements * descriptor; return(SIMPLE); } else if ((word)descriptor == 0) { *simple_d = (GC_descr)0; return(SIMPLE); } } if (nelements <= OPT_THRESHOLD) { if (nelements <= 1) { if (nelements == 1) { *simple_d = descriptor; return(SIMPLE); } else { *simple_d = (GC_descr)0; return(SIMPLE); } } } else if (size <= BITMAP_BITS/2 && (descriptor & GC_DS_TAGS) != GC_DS_PROC && (size & (sizeof(word)-1)) == 0) { int result = GC_make_array_descriptor(nelements/2, 2*size, GC_double_descr(descriptor, BYTES_TO_WORDS(size)), simple_d, complex_d, leaf); if ((nelements & 1) == 0) { return(result); } else { struct LeafDescriptor * one_element = (struct LeafDescriptor *) GC_malloc_atomic(sizeof(struct LeafDescriptor)); if (result == NO_MEM || one_element == 0) return(NO_MEM); one_element -> ld_tag = LEAF_TAG; one_element -> ld_size = size; one_element -> ld_nelements = 1; one_element -> ld_descriptor = descriptor; switch(result) { case SIMPLE: { struct LeafDescriptor * beginning = (struct LeafDescriptor *) GC_malloc_atomic(sizeof(struct LeafDescriptor)); if (beginning == 0) return(NO_MEM); beginning -> ld_tag = LEAF_TAG; beginning -> ld_size = size; beginning -> ld_nelements = 1; beginning -> ld_descriptor = *simple_d; *complex_d = GC_make_sequence_descriptor( (complex_descriptor *)beginning, (complex_descriptor *)one_element); break; } case LEAF: { struct LeafDescriptor * beginning = (struct LeafDescriptor *) GC_malloc_atomic(sizeof(struct LeafDescriptor)); if (beginning == 0) return(NO_MEM); beginning -> ld_tag = LEAF_TAG; beginning -> ld_size = leaf -> ld_size; beginning -> ld_nelements = leaf -> ld_nelements; beginning -> ld_descriptor = leaf -> ld_descriptor; *complex_d = GC_make_sequence_descriptor( (complex_descriptor *)beginning, (complex_descriptor *)one_element); break; } case COMPLEX: *complex_d = GC_make_sequence_descriptor( *complex_d, (complex_descriptor *)one_element); break; } return(COMPLEX); } } leaf -> ld_size = size; leaf -> ld_nelements = nelements; leaf -> ld_descriptor = descriptor; return(LEAF); }