示例#1
0
/* _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 {
示例#2
0
文件: read.c 项目: rev22/mythryl-1
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;
}
示例#3
0
/* 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);
}
示例#4
0
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;
}
示例#5
0
// 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;
}
示例#6
0
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 */
}
示例#7
0
文件: recv.c 项目: jes5199/mythryl
/* _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;
}
示例#8
0
// 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.
}
示例#9
0
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;
}
示例#10
0
/* 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);
}
示例#11
0
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 */
}
示例#12
0
 /* 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);
 }
示例#13
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 */
}
示例#14
0
  /* 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);
  }
示例#15
0
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;
}
示例#18
0
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);
}
示例#19
0
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();
}
示例#21
0
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 );
}
示例#22
0
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.
}
示例#23
0
  /* 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;
  }
示例#24
0
/* 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);
}
示例#25
0
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);
}
示例#26
0
/* 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);
}
示例#27
0
// 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);
	}
}
示例#28
0
// 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);
	}
}
示例#29
0
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;
}
示例#30
0
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);
}