예제 #1
0
//Get the memory location referenced by block
//Return NULL for invalid block descriptor
static void* getBlockPtr(Block b)
{
    void* ptr = (void*) megMap;
    if(!validBlock(b))
        return NULL;
    int level = getBlockLevel(b);
    for(int i = 0; i <= level; i++)
    {
        //For each level, add the offset for table as well as the memory for
        //blocks before this one
        ptr += subblockStart[i];
        ptr += b.levels[i] * blockSize[i];
    }
    return ptr;
}
예제 #2
0
//Return a BlockStatus value or -1 on error
static int getBlockStatus(Block b)
{
    if(!validBlock(b))
        return -1;
    int level = getBlockLevel(b);
    byte* table; //start of table for parent blocks, or top-level block.
    byte mask = 0b11;
    int shift;
    //set table to address of block status bitmap of parent
    if(level == 0)
        table = (byte*) megMap;
    else
        table = (byte*) getBlockPtr(getParentBlock(b));
    int baseIndex = b.levels[level];
    byte entry = *(table + (baseIndex / 4)); //2 bits per entry
    shift = 6 - (2 * (baseIndex % 4));  //trust me it works
    return (entry & (mask << shift)) >> shift;
}
예제 #3
0
static bool allocBlocks(int level, int numBlocks, Block* result)
{
    //printf("Allocating %d blocks at level %d\n", numBlocks, level);
    if(level == 0)
    {
        //printf("  Will attempt to find top-level group of %d blocks.\n", numBlocks);
        return findTopLevelGroup(numBlocks, result);
    }
    //Need to find subblock(s)
    //Best to worst options:
    //-Use same parent block from last allocation
    //-Allocate new parent block somewhere else
    //-Depth-first search subdivided blocks looking for free blocks
    //-Return false
    //First try lastParents
    int bestOvershootParent = -1;
    int bestOvershoot = 0xFFFF;
    int overshoot = 0;
    for(int i = 0; i < PARENT_SAVES; i++)
    {
        if(validBlock(lastParents[level][i]))
        {
            if(findGroupInBlock(lastParents[level][i], numBlocks, result, &overshoot))
            {
                if(overshoot < bestOvershoot)
                {
                    bestOvershoot = overshoot;
                    bestOvershootParent = i;
                }
            }
        }
    }
    if(bestOvershootParent != -1)
    {
        Block use = lastParents[level][bestOvershootParent];
        if(!findGroupInBlock(use, numBlocks, result, NULL))
        {
            //This should never ever happen
            //puts("VERY FATAL ERROR: CHECK FOUND LAST_PARENT CASE");
            return false;
        }
        //puts("Allocation successful via lastParents");
        //printf("Resulting block group: ");
        //printBlock(*result);
        //puts("");
        allocGroup(*result, numBlocks);
        return true;
    }
    //lastParents must be updated
    //If one is not yet valid, set it to a newly allocated block
    //Immediately use subblocks of that new block to fulfill current request
    //puts("Did not find good cached parent block.");
    bool allValid = true;
    Block* toReplace;
    for(int i = 0; i < PARENT_SAVES; i++)
    {
        if(!validBlock(lastParents[level][i]))
        {
            allValid = false;
            toReplace = &lastParents[level][i];
            break;
        }
    }
    if(!allValid)
    {
        bool success = replaceParentSave(toReplace, level - 1);
        if(success)
        {
            //use *toReplace (now a fresh subdivded block) as parent
            *result = getFirstSubblock(*toReplace);
            allocGroup(*result, numBlocks);
            //puts("Allocation successful via newParent");
            return true;
        }
    }
    else
    {
        int worstGroup = 100;
        int worstBlock = -1;
        for(int i = 0; i < PARENT_SAVES; i++)
        {
            int thisGroup = getMaxGroup(lastParents[level][i]);
            if(thisGroup < worstGroup)
            {
                worstGroup = thisGroup;
                worstBlock = i;
            }
        }
        toReplace = &lastParents[level][worstBlock];
        //replace worstBlock
        bool success = replaceParentSave(toReplace, level - 1);
        if(success)
        {
            *result = getFirstSubblock(*toReplace);
            allocGroup(*result, numBlocks);
            return true;
            //puts("Allocation sucessful via new parent.");
        }
    }
    //If here, then depth-first search for an appropriate parent block
    //that isn't necesarily listed in lastParent.
    Block first;
    for(int i = 0; i < numSubblocks[0]; i++)
    {
        Block topLevel = {{i, -1, -1, -1}};
        if(getBlockStatus(topLevel) == SUBDIV)
        {
            if(groupSearch(level, numBlocks, topLevel, &first))
            {
                *result = first;
                allocGroup(*result, numBlocks);
                return true;
                //puts("Allocation successful via worst-case dfs for parent");
            }
        }
    }
    //puts("Block group allocation failed!");
    return false;
}
// partly copied from https://github.com/zcash/zcash/blob/master/src/miner.cpp#L581
bool equihash_(std::string solver, CBlock *pblock, int n, int k)
{
    arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);

    // Hash state
    crypto_generichash_blake2b_state state;
    EhInitialiseState(n, k, state);

    // I = the block header minus nonce and solution.
    CEquihashInput I{*pblock};
    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
    ss << I;

    // H(I||...
    crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());

    // H(I||V||...
    crypto_generichash_blake2b_state curr_state;
    curr_state = state;
    crypto_generichash_blake2b_update(&curr_state,
        pblock->nNonce.begin(),
        pblock->nNonce.size());

    // (x_1, x_2, ...) = A(I, V, n, k)
    LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",
             solver, pblock->nNonce.ToString());

    std::function<bool(std::vector<unsigned char>)> validBlock =
    [&pblock, &hashTarget](std::vector<unsigned char> soln) {
        // Write the solution to the hash and compute the result.
        pblock->nSolution = soln;

        if (UintToArith256(pblock->GetHash()) > hashTarget) {
           return false;
        }

        // Found a solution
        LogPrintf("CMMMiner:\n");
        LogPrintf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
        return true;
    };

    if (solver == "tromp") {
        // Create solver and initialize it.
        equi eq(1);
        eq.setstate(&curr_state);

        // Intialization done, start algo driver.
        eq.digit0(0);
        eq.xfull = eq.bfull = eq.hfull = 0;
        eq.showbsizes(0);
        for (u32 r = 1; r < WK; r++) {
            (r&1) ? eq.digitodd(r, 0) : eq.digiteven(r, 0);
            eq.xfull = eq.bfull = eq.hfull = 0;
            eq.showbsizes(r);
        }
        eq.digitK(0);

        // Convert solution indices to byte array (decompress) and pass it to validBlock method.
        for (size_t s = 0; s < eq.nsols; s++) {
            std::vector<eh_index> index_vector(PROOFSIZE);
            for (size_t i = 0; i < PROOFSIZE; i++) {
                index_vector[i] = eq.sols[s][i];
            }
            std::vector<unsigned char> sol_char = GetMinimalFromIndices(index_vector, DIGITBITS);
            if (validBlock(sol_char)) 
                return true;
        }
    } else {
        try {
            if (EhOptimisedSolve(n, k, curr_state, validBlock)) 
                return true;
        } catch (std::exception&) {
            LogPrintf("pow/nano.cpp: ", "execption catched...");
        }
    }
    return false;
}
예제 #5
0
CMotionVector CVideoObject::findShapeMVP (
	const CMotionVector* pmv, const CMotionVector* pmvBY, 
	const CMBMode* pmbmd,
	Int iMBX, Int iMBY
) const
{
	CMotionVector mvRet;
	// try shape vector first

	Bool bLeftBndry, bRightBndry, bTopBndry;
	Int iMBnum = VPMBnum(iMBX, iMBY);
	bLeftBndry = bVPNoLeft(iMBnum, iMBX);
	bTopBndry = bVPNoTop(iMBnum);
	bRightBndry = bVPNoRightTop(iMBnum, iMBX);

//OBSS_SAIT_991015
	if (iMBX==0 && iMBY==0) {
		mvRet.iMVX = mvRet.iMVY = mvRet.iHalfX  =mvRet.iHalfY = 0;	
	}
	else mvRet = *(pmvBY - 1);	
/* !!!
	mvRet = *(pmvBY - 1);	
*/
//~OBSS_SAIT_991015

//	Modified for error resilient mode by Toshiba(1997-11-14)
//	if ((iMBX > 0) && ((pmbmd - 1)->m_shpmd == INTER_CAE_MVDZ ||
	if (!bLeftBndry && ((pmbmd - 1)->m_shpmd == INTER_CAE_MVDZ ||
		(pmbmd - 1)->m_shpmd == INTER_CAE_MVDNZ ||
		(pmbmd - 1)->m_shpmd == MVDZ_NOUPDT ||
		(pmbmd - 1)->m_shpmd == MVDNZ_NOUPDT))
		return mvRet;
	if (iMBY > 0)   {
		mvRet = *(pmvBY - m_iNumMBX);
//	Modified for error resilient mode by Toshiba(1997-11-14)
//		if ((pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDZ ||
		if (!bTopBndry && ((pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDZ ||
			(pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDNZ ||
			(pmbmd - m_iNumMBX)->m_shpmd == MVDZ_NOUPDT ||
			(pmbmd - m_iNumMBX)->m_shpmd == MVDNZ_NOUPDT
//	Modified for error resilient mode by Toshiba(1997-11-14)
//		)
		))
			return mvRet;			
		mvRet = *(pmvBY - m_iNumMBX + 1);
//	Modified for error resilient mode by Toshiba(1997-11-14)
//		if ((iMBX < m_iNumMBX - 1) && ((pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDZ ||
		if (!bRightBndry && ((pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDZ ||
			(pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDNZ ||
			(pmbmd - m_iNumMBX + 1)->m_shpmd == MVDZ_NOUPDT ||
			(pmbmd - m_iNumMBX + 1)->m_shpmd == MVDNZ_NOUPDT)
		)
			return mvRet;
	}

	// try texture vector then; truncate half pel
	if(m_volmd.bShapeOnly==FALSE && (m_vopmd.vopPredType==PVOP || (m_uiSprite == 2 && m_vopmd.vopPredType==SPRITE))) // GMC
	{
	  Int iSubDim;
	  if (m_volmd.bQuarterSample) // Quarter sample
	    iSubDim = 4;
	  else
	    iSubDim = 2;

//	Modified for error resilient mode by Toshiba(1997-11-14)
//		if (iMBX != 0 && validBlock (pmbmd - 1, gIndexOfCandBlk [1] [0]))
		if (!bLeftBndry && validBlock (pmbmd, pmbmd - 1, gIndexOfCandBlk [1] [0]))
// GMC
			if(!((pmbmd-1)->m_bMCSEL)){
// ~GMC
				return CMotionVector ((pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0])->m_vctTrueHalfPel.x / iSubDim,
								  (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0])->m_vctTrueHalfPel.y / iSubDim);
// GMC
			}else{
				return CMotionVector ();
			}
// ~GMC
		if (iMBY != 0)   {
//	Modified for error resilient mode by Toshiba(1997-11-14)
//			if (validBlock (pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1]))
			if (!bTopBndry && validBlock (pmbmd, pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1]))
// GMC
				if(!((pmbmd-m_iNumMBX)->m_bMCSEL)){
// ~GMC
					return CMotionVector ((pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1])->m_vctTrueHalfPel.x / iSubDim,
									  (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1])->m_vctTrueHalfPel.y / iSubDim);
// GMC
				}else{
					return CMotionVector ();
				}
// ~GMC
//	Modified for error resilient mode by Toshiba(1997-11-14)
//			if (iMBX < m_iNumMBX - 1 && validBlock (pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2]))
			if (!bRightBndry && validBlock (pmbmd, pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2]))
// GMC
				if(!((pmbmd-m_iNumMBX + 1)->m_bMCSEL)){
// ~GMC
					return CMotionVector ((pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2])->m_vctTrueHalfPel.x / iSubDim,
									  (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2])->m_vctTrueHalfPel.y / iSubDim);
// GMC
				}else{
					return CMotionVector ();
				}
// ~GMC
		}
	}
	return CMotionVector ();																		
}