Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/compiler/target-cpu/fragments/seq-sarr-dual-indirect.in
ViewVC logotype

View of /branches/vis15/src/compiler/target-cpu/fragments/seq-sarr-dual-indirect.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4489 - (download) (annotate)
Sat Sep 3 00:32:03 2016 UTC (3 years, 1 month ago) by jhr
File size: 5936 byte(s)
working on merge: changing initially to start
// strand_array for BSP/DUAL STATE/INDIRECT ACCESS
//
struct strand_array {
    typedef uint32_t index_t;
    typedef char *block_t;		// points to array of @STRANDTY@ structs

    uint8_t		*_status;	// the array of status information for the strands
    uint32_t		*_idx;		// array of strand indices for indirect state rep.
    std::vector<block_t> _blocks;	// vector of pointers to strand-storage blocks
    uint32_t		_inIdx;		// index of shared input state (either 0 or 1)
    uint32_t		_nItems;	// number of items in the _blocks and _status arrays
    uint32_t		_nStable;	// stable strands (in locations 0.._nStable-1)
    uint32_t		_nActive;	// active strands (in locations _nStable.._nStable+_nActive-1)

    static const uint32_t LOG_BLKSZ= 12			// 2^12 items per block
    static const uint32_t BLKSZ = (1 << LOG_BLKSZ);
    static const uint32_t BLKMASK = (BLKSZ-1);		// mask for block index

    strand_array () : _status(nullptr), _idx(nullptr), _nItems(0) { }

  // return a pointer to the given strand
    @STRANDTY@ *strand (index_t ix) const
    {
	uint32_t jx = this->_idx[ix];
	uint32_t blkId = jx >> LOG_BLKSZ;
	uint32_t offset = ix & BLKMASK;
	return reinterpret_cast<@STRANDTY@ *>(this->_blocks[blkId] + offset * sizeof(S_strand));
    }
  // return a pointer to the local state of strand ix
    @STRAND@_local *local_state (index_t ix) const
    {
	return &(this->strand()->_local);
    }
  // return a pointer to the in-state of strand ix
    const @STRAND@_shared *in_state (index_t ix) const
    {
	return &(this->strand()->_shared[this->_inIdx]);
    }
  // return a pointer to the out-state of strand ix
    @STRAND@_shared *out_state (index_t ix) const
    {
	return &(this->strand()->_shared[this->_inIdx ^ 1]);
    }

  // swap in and out states
    void swap ()
    {
	tihs->_inIdx ^= 1;
    }

  // deallocate space reserved for strands
    void dealloc ()
    {
	if (this->_status != nullptr) {
	    std::free (this->_status);
	    this->_status = nullptr;
	}
	if (this->_idx != nullptr) {
	    std::free (this->_idx);
	    this->_idx = nullptr;
	}
	for (uint32_t i = 0;  i < this->_blocks.size();  i++) {
	    if (this->_blocks[i] != nullptr) {
		std::free (this->_blocks[i]);
		this->_blocks[i] = nullptr;
	    }
	    else {
		break;
	    }
	}
    }

  // allocate space for at least nItems
    bool alloc (uint32_t nItems)
    {
	nItems = (nItems + BLKSZ - 1) & ~BLKMASK;
	uint32_t nBlks = nItems >> LOG_BLKSZ;
      // allocate block vector
	this->_blocks.resize(nBlks, nullptr);
      // allocate blocks
	for (int i = 0;  i < nBlks;  i++) {
	    this->_blocks[i] = static_cast<char *>(std::malloc (BLKSZ * sizeof(@STRANDTY@)));
	    if (this->_blocks[i]  == nullptr) {
	      // unable to allocate memory
		this->dealloc();
		return true;
	    }
	}
      // allocate _status array
	this->_status = static_cast<uint8_t *>(std::malloc (nItems * sizeof(uint8_t)));
	if (this->_status == nullptr) {
	    std::free (this->_storage);
	    return true;
	}
      // allocate _idx array
	this->_idx = static_cast<uint32_t *>(std::malloc (nItems * sizeof(uint32_t)));
	if (this->_idx == nullptr) {
	    std::free (this->_storage);
	    std::free (this->_status);
	    return true;
	}
	this->_nItems = nItems;
	this->_nActive = 0;
	this->_nStable = 0;
	return false;
    }

  // initialize the first nStrands locations as new active strands
    void create_strands (uint32_t nStrands)
    {
	assert (this->_nActive == 0);
	assert (this->_nItems >= nStrands);

	uint32_t ix = 0;
	for (uint32_t i = 0;  i < this->_blocks.size();  i++) {
	    @STRANDTY@ *p = reinterpret_cast<@STRANDTY@ *>(this->_blocks[i]);
	    for (uint32_t j = 0;  j < BLKSZ;  j++, ix++) {
		this->_idx[ix] = ix;
		this->_status[ix] = (ix < nStrands) ? diderot::kActive : diderot::kDead;
		new (p++) @STRANDTY@;
	    }
	}

	this->_nActive = nStrands;
    }

  // kill the specified strand
    void kill (index_t ix)
    {
	assert (this->_nStable <= ix);
	assert (ix < this->_nStable + this->_nActive);
	this->_nActive--;
	uint32_t jx = this->_nStable + this->_nActive;
	uint32_t id = this->_idx[ix];
	this->_statux[jx] = diderot::kDead;
	std::swap (this->_idx[ix], this->_idx[jx]);
      // invoke the dead strand's destructors
	reinterpret_cast<@STRANDTY@ *>(&this->_storage[id])->~@STRANDTY@();
    }

  // create a new strand
    index_t new_strand ()
    {
	index_t ix = this->_nStable + this->_nActive;
	if (this->_nItems <= ix) {
	    if (this->_grow ()) {
		std::cerr << "Fatal error: unable to allocate space for new strands"; << std::endl;
		exit (1);
	    }
	}
	this->_status[ix] = diderot::kNew;
	this->_nActive++;
	return ix;
    }

  // allocate more space for strand state
    bool grow ()
    {
	size_t nItems = static_cast<size_t>(this->_nItems) + BLKSZ;
	if (nItems >= UINT32_MAX) {
	  // cannot have more than UINT32_MAX elements
	    return true;
	}

      // allocate a new block at the end of the _blocks array
	char *blk = static_cast<char *>(std::malloc (BLKSZ * sizeof(@STRANDTY@)));
	if (blk == nullptr) {
	    return true;
	}
	this->_blocks.push_back (blk);

      // grow the _status and _idx arrays
	uint8_t *status = static_cast<uint8_t *>(std::malloc (nItems * sizeof(uint8_t)));
	uint32_t *idx = static_cast<uint32_t *>(std::malloc (nItems * sizeof(uint32_t)));
	if ((status == nullptr) || (idx == nullptr)) {
	    return true;
	}
	std::memcpy (status, this->_status, this->_nItems * sizeof(uint8_t));
	std::memcpy (idx, this->_idx, this->_nItems * sizeof(uint32_t));

      // initialize the new storage
	@STRANDTY@ *p = reinterpret_cast<@STRANDTY@ *>(blk);
	for (uint32_t ix = this->_nItems;  ix < nItems;  ix++) {
	    status[ix] = diderot::kDead;
	    idx[ix] = ix;
	    new (p++) @STRANDTY@;
	}

      // free the old storage
	std::free (this->_status);
	std::free (this->_idx);

      // update pointers
	this->_status = status;
	this->_idx = idx;
	this->_nItems = nItems;

    }

}; // struct strand_array

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0