Example #1
0
static inline void System_Poll( void )
{
    enum EPowerMode pwr_mode = pm_down;

    CheckStack();

    sys_pwr |= core_pwr_getstate();
    sys_pwr |= DispHAL_App_Poll();
    if ( BeepIsRunning() )
        sys_pwr |= PM_SLEEP;

    // decide power management model
    if ( sys_pwr & PM_FULL )
        pwr_mode = pm_full;             // full run mode - no sleeping
    else if ( sys_pwr & PM_SLEEP )
        pwr_mode = pm_sleep;            // sleep and wake up on timer/dma irq
    else
    {
        if ( sys_pwr & PM_HOLD_BTN )
            pwr_mode = pm_hold_btn;     // device with active UI, but with low cpu usage - any button should wake it up
        else if ( sys_pwr & PM_HOLD )
            pwr_mode = pm_hold;         // device is working on background only (monitoring/registering tasks), no active UI, should be woken up by the user by power button only
        else
        {
            core_nvfast_save_struct();
            pwr_mode = pm_down;         // no power requirement is needed - turn it off
        }

        core_pwr_setup_alarm(pwr_mode); // set up the next alarm point in the RTC
        EventBtnClear();                // clear button status
    }

    wake_up = HW_Sleep( pwr_mode );     // enter in the selected power mode
    sys_pwr = 0;                        // when exit - recreate the power scenario
}
Example #2
0
int
yarg_true(int iarg)
{
  Symbol *s = (iarg>=0)? sp - iarg : 0;
  int x = 0;
  if (s) {
    CheckStack(1);
    sp[1].ops = &intScalar;
    if (s->ops==&referenceSym) s = &globTab[s->index];
    if (s->ops != &dataBlockSym) sp[1].value = s->value;
    else sp[1].value.db = Ref(s->value.db);
    sp++;
    sp->ops = s->ops;
    sp->ops->True();
    x = (int)ygets_l(0);
    yarg_drop(1);
  }
  return x;
}
Example #3
0
void CLuaHandleSynced::Init(const string& syncedFile, const string& unsyncedFile, const string& modes)
{
	if (!IsValid())
		return;

	const string syncedCode   = LoadFile(syncedFile, modes);
	const string unsyncedCode = LoadFile(unsyncedFile, modes);
	if (syncedCode.empty() && unsyncedCode.empty()) {
		KillLua();
		return;
	}

	const bool haveSynced   = syncedLuaHandle.Init(syncedCode, syncedFile);
	const bool haveUnsynced = unsyncedLuaHandle.Init(unsyncedCode, unsyncedFile);

	if (!IsValid() || (!haveSynced && !haveUnsynced)) {
		KillLua();
		return;
	}

	CheckStack();
}
Example #4
0
void CTabBarClass::Update(BOOL abPosted/*=FALSE*/)
{
	#ifdef _DEBUG
	if (this != gpConEmu->mp_TabBar)
	{
		_ASSERTE(this == gpConEmu->mp_TabBar);
	}
	#endif

	MCHKHEAP
	/*if (!_active)
	{
	    return;
	}*/ // Теперь - ВСЕГДА! т.к. сами управляем мультиконсолью

	if (mb_DisableRedraw)
	{
		_ASSERTE(FALSE && "mb_DisableRedraw?"); // Надо?
		return;
	}

	if (!isMainThread())
	{
		RequestPostUpdate();
		return;
	}

	gpConEmu->mp_Status->UpdateStatusBar();

	mb_PostUpdateCalled = FALSE;

	#ifdef _DEBUG
	_ASSERTE(mn_InUpdate >= 0);
	if (mn_InUpdate > 0)
	{
		_ASSERTE(mn_InUpdate == 0);
	}
	#endif

	mn_InUpdate ++;

	MCHKHEAP
	int V, I, tabIdx = 0, nCurTab = -1;
	BOOL bShowFarWindows = gpSet->bShowFarWindows;

	// Выполняться должно только в основной нити, так что CriticalSection не нужна

	#ifdef _DEBUG
	if (this != gpConEmu->mp_TabBar)
	{
		_ASSERTE(this == gpConEmu->mp_TabBar);
	}
	#endif

	TODO("Обработка gpSet->bHideInactiveConsoleTabs для новых табов");
	MCHKHEAP


	// Check if we need to AutoSHOW or AutoHIDE tab bar
	if (!IsTabsActive() && gpSet->isTabs)
	{
		int nTabs = CountActiveTabs(2);
		if (nTabs > 1)
		{
			Activate();
		}
	}
	else if (IsTabsActive() && gpSet->isTabs==2)
	{
		int nTabs = CountActiveTabs(2);
		if (nTabs <= 1)
		{
			Deactivate();
		}
	}


	// Validation?
	#ifdef _DEBUG
	if (this != gpConEmu->mp_TabBar)
	{
		_ASSERTE(this == gpConEmu->mp_TabBar);
	}
	#endif



	MCHKHEAP
	HANDLE hUpdate = m_Tabs.UpdateBegin();
	_ASSERTE(hUpdate!=NULL);

	bool bStackChanged = false;

	/* ********************* */
	/*          Go           */
	/* ********************* */
	{
		MMap<CVConGroup*,CVirtualConsole*> Groups; Groups.Init(MAX_CONSOLE_COUNT, true);

		for (V = 0; V < MAX_CONSOLE_COUNT; V++)
		{
			//if (!(pVCon = gpConEmu->GetVCon(V))) continue;
			CVConGuard guard;
			if (!CVConGroup::GetVCon(V, &guard))
				continue;
			CVirtualConsole* pVCon = guard.VCon();

			BOOL lbActive = pVCon->isActive(false);

			if (gpSet->bHideInactiveConsoleTabs && !lbActive)
				continue;

			if (gpSet->isOneTabPerGroup)
			{
				CVConGroup *pGr;
				CVConGuard VGrActive;
				if (CVConGroup::isGroup(pVCon, &pGr, &VGrActive))
				{
					CVirtualConsole* pGrVCon;

					if (Groups.Get(pGr, &pGrVCon))
						continue; // эта группа уже есть

					pGrVCon = VGrActive.VCon();
					Groups.Set(pGr, pGrVCon);

					// И показывать таб нужно от "активной" консоли, а не от первой в группе
					if (pVCon != pGrVCon)
					{
						guard = pGrVCon;
						pVCon = pGrVCon;
					}

					if (!lbActive)
					{
						lbActive = pVCon->isActive(true);
					}

					// Показывать редакторы из всех групп?
					if (gpSet->bShowFarWindows)
					{
						MArray<CVConGuard*> Panes;
						int nPanes = pGr->GetGroupPanes(&Panes);

						// Только если в группе более одного таба - тогда нужно дополниетльная логика населения...
						if (nPanes > 1)
						{
							// Первым табом - показать текущую панель, либо МОДАЛЬНЫЙ редактор/вьювер
							// Редакторы из "far /e ..." здесь НЕ добавлять!
							if (!pVCon->RCon()->isFarPanelAllowed()
								|| !UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged, pVCon, uat_PanelsOrModalsOnly))
							{
								// Если есть - добавить ОДНУ панель, чтобы табы сплита не прыгали туда-сюда
								for (int K = 0; K < nPanes; K++)
								{
									if (Panes[K]->VCon()->RCon()->isFarPanelAllowed())
									{
										if (UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged,
												Panes[K]->VCon(), uat_PanelsOnly) > 0)
											break;
									}
								}
							}

							// Потом - все оставшиеся редакторы/вьюверы (в том числе и "far /e ...")
							for (int K = 0; K < nPanes; K++)
							{
								UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged,
									Panes[K]->VCon(), uat_NonModals|uat_NonPanels);
							}

							// Release
							CVConGroup::FreePanesArray(Panes);

							// Already processed, next VCon
							continue;
						}
					}
				}
			}

			UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged, pVCon, uat_AnyTab);
		}

		Groups.Release();
	}

	MCHKHEAP

	// Must be at least one tab ("ConEmu -Detached" for example)
	if (tabIdx == 0)
	{
		m_Tabs.UpdateAppend(hUpdate, mp_DummyTab, FALSE);

		// Физически (WinAPI) добавляет закладку, или меняет (при необходимости) заголовок существующей
		mp_Rebar->AddTabInt(gpConEmu->GetDefaultTabLabel(), tabIdx, gpConEmu->mb_IsUacAdmin, -1);

		nCurTab = tabIdx;
		tabIdx++;
	}

	m_Tabs.UpdateEnd(hUpdate, 0);

	// Проверим стек последних выбранных
	if (CheckStack())
		bStackChanged = true;

	#ifdef PRINT_RECENT_STACK
	PrintRecentStack();
	#endif

	#ifdef _DEBUG
	static int nPrevVisible, nPrevStacked;
	{
		wchar_t szDbg[100];
		int nNewVisible = m_Tabs.GetCount();
		int nNewStacked = m_TabStack.size();
		_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"*** Tab list updated. Visible:%u, Stacked:%u, StackChanged:%s\n",
			nNewVisible, nNewStacked, bStackChanged ? L"Yes" : L"No");
		DEBUGSTRCOUNT(szDbg);
		nPrevVisible = nNewVisible;
		nPrevStacked = nNewStacked;
	}
	#endif

	// удалить лишние закладки (визуально)
	int nCurCount = GetItemCount();

	#ifdef _DEBUG
	wchar_t szDbg[128];
	_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"CTabBarClass::Update.  ItemCount=%i, PrevItemCount=%i\n", tabIdx, nCurCount);
	DEBUGSTRTABS(szDbg);
	#endif

	if (mp_Rebar->IsTabbarCreated())
	{
		for (I = tabIdx; I < nCurCount; I++)
		{
			#ifdef _DEBUG
			_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"   Deleting tab=%i\n", I+1);
			DEBUGSTRTABS(szDbg);
			#endif

			DeleteItem(tabIdx);
		}
	}

	MCHKHEAP

	if (mb_InKeySwitching)
	{
		if (mn_CurSelTab >= nCurCount)  // Если выбранный таб вылез за границы
			mb_InKeySwitching = false;
	}

	if (!mb_InKeySwitching && nCurTab != -1)
	{
		SelectTab(nCurTab);
	}

	UpdateToolConsoles();

	//if (gpSet->isTabsInCaption)
	//{
	//	SendMessage(ghWnd, WM_NCPAINT, 0, 0);
	//}

	mn_InUpdate --;

	if (mb_PostUpdateRequested)
	{
		mb_PostUpdateCalled = FALSE;
		mb_PostUpdateRequested = FALSE;
		RequestPostUpdate();
	}

	MCHKHEAP
	return; // Just for clearness
}
	void LuaState::CheckStack(int space, const String& error) const
	{
		CheckStack(space, error.GetConstBuffer());
	}
Example #6
0
void EvalFN(Operand *op)
{
  Symbol *stack= op->owner;
  int n= op->references;       /* (sic) # of actual parameters supplied */
  Function *func= op->value;
  Instruction *code= &func->code[1];  /* (code[0] is index to function) */
  int nReq= func->nReq;        /* (see CheckStack call below) */
  int nPos= func->nPos;        /* number of dummy positional parameters */
  int nKey= func->nKey;        /* number of dummy keyword parameters */
  int nLoc= func->nLocal;      /* number of local variables */
  long hasPosList= func->hasPosList;
  long posList;

  int actual, dummy, index, nExtra;
  Symbol *spnow, *extraPos, *key;

  P_SOFTFPE_TEST;

  /* Be sure the stack is long enough for a worst-case invocation of this
     function.  nReq= nPos + (hasPosList&1) + nKey + nLoc + (deepest stack
                      required for expression evaluation) + 10
                      + 1 for return address for this function
     The nPos and nKey terms must be present because they may not be
     actual arguments, and because even if they are supplied they may
     be referenceSyms which must be copied for use during return.
     The extra 10 is so that builtin procedures are always guaranteed
     8(+2 for luck) free stack slots without calling CheckStack.  */
  if (CheckStack(nReq)) stack= sp-n;

  /* Handle all actual parameters.
     This must be done in two passes to avoid accidental collisions
     between dummy parameters and indirect references on the stack
     to external variables of the same name.  All of this could be
     avoided if function parameters were always passed by value,
     never by reference.  But I can't bring myself to disallow the
     FORTRAN-like function which uses its parameters to return values.  */

  /* First pass copies any indirect references.
     The parser has guaranteed that index (dummy) will not be repeated,
     since there may not be 2 dummy parameters with the same name.
     However, nothing prevents the one or more of the actual parameters
     (stack) from being referenceSyms to the same name as a dummy
     parameter.  This possibility requires copying all referenceSym
     actual parameters onto the stack (possibly multiple times).
     Also, note that a globTab entry may NEVER be a referenceSym, so
     if return is to affect external values of parameters, any
     referenceSym parameters must remain on the stack.  */
  posList= hasPosList>>1;
  hasPosList&= 1;
  nExtra= -nPos;
  spnow= stack;
  for (actual=0 ; actual<n ; actual++) {
    spnow++;
    if (spnow->ops) {
      if (spnow->ops==&referenceSym) {
        if (posList) {
          if (nExtra<0 && (posList&1)) {
            /* this is an output parameter */
            extraPos= sp+1;                   /* push copy of referenceSym */
            extraPos->ops= &referenceSym;
            extraPos->index= spnow->index;
            extraPos->value.offset= extraPos-spnow;  /* install ref offset */
            sp= extraPos;
          }
          posList>>= 1;
        }
        ReplaceRef(spnow);       /* replace original reference by object */
      } else if (posList) {
        posList>>= 1;
      }
      nExtra++;
    } else {
Example #7
0
static inline void System_Poll( void )
{
    CheckStack();

}
Example #8
0
pascal	OSErr	IndexedSearch(CSParamPtr pb,
							  long dirID)
{
	static LevelRecHandle	searchStack = NULL;		/* static handle to LevelRec stack */
	static Size				searchStackSize = 0;	/* size of static handle */
	SearchPositionRecPtr	catPosition;
	long					modDate;
	short					index = -1 ;
	ExtendedTMTask			timerTask;
	OSErr					result;
	short					realVRefNum;
	Str63					itemName;
	CInfoPBRec				cPB;
	long					tempLong;
	Boolean					includeFiles;
	Boolean					includeDirs;
	Boolean					includeNames;
	Str63					upperName;
	
	timerTask.stopSearch = false;	/* don't stop yet! */
	
	/* If request has a timeout, install a Time Manager task. */
	if ( pb->ioSearchTime != 0 )
	{
		/* Start timer */
		timerTask.theTask.tmAddr = NewTimerUPP(TimeOutTask);
		InsTime((QElemPtr)&(timerTask.theTask));
		PrimeTime((QElemPtr)&(timerTask.theTask), pb->ioSearchTime);
	}
	
	/* Check the parameter block passed for things that we don't want to assume */
	/* are OK later in the code. For example, make sure pointers to data structures */
	/* and buffers are not NULL.  And while we're in there, see if the request */
	/* specified searching for files, directories, or both, and see if the search */
	/* was by full or partial name. */
	result = VerifyUserPB(pb, &includeFiles, &includeDirs, &includeNames);
	if ( result == noErr )
	{
		pb->ioActMatchCount = 0;	/* no matches yet */
	
		if ( includeNames )
		{
			/* The search includes seach by full or partial name. */
			/* Make an upper case copy of the match string to pass to */
			/* CheckForMatches. */
			BlockMoveData(pb->ioSearchInfo1->hFileInfo.ioNamePtr,
							upperName,
							pb->ioSearchInfo1->hFileInfo.ioNamePtr[0] + 1);
			/* Use the same non-international call the File Manager uses */
			UpperString(upperName, true);
		}
		
		/* Prevent casting to my type throughout code */
		catPosition = (SearchPositionRecPtr)&pb->ioCatPosition;
		
		/* Create searchStack first time called */
		if ( searchStack == NULL )
		{
			searchStack = (LevelRecHandle)NewHandle(kAdditionalLevelRecs * sizeof(LevelRec));
		}
		
		/* Make sure searchStack really exists */
		if ( searchStack != NULL )
		{
			searchStackSize = GetHandleSize((Handle)searchStack);
			
			/* See if the search is a new search or a resumed search. */
			if ( catPosition->initialize == 0 )
			{
				/* New search. */
				
				/* Get the real vRefNum and fill in catPosition->initialize. */ 
				result = CheckVol(pb->ioNamePtr, pb->ioVRefNum, &realVRefNum, &catPosition->initialize);
				if ( result == noErr )
				{
					/* clear searchStack */
					catPosition->stackDepth = 0;
					
					/* use dirID parameter passed and... */
					index = -1;	/* start with the passed directory itself! */
				}
			}
			else
			{
				/* We're resuming a search. */
	
				/* Get the real vRefNum and make sure catPosition->initialize is valid. */ 
				result = CheckVol(pb->ioNamePtr, pb->ioVRefNum, &realVRefNum, &tempLong);
				if ( result == noErr )
				{
					/* Make sure the resumed search is to the same volume! */
					if ( catPosition->initialize == tempLong )
					{
						/* For resume, catPosition->stackDepth > 0 */
						if ( catPosition->stackDepth > 0 )
						{
							/* Position catPosition->stackDepth to access last saved level */
							--(catPosition->stackDepth);
			
							/* Get the dirID and index for the next item */
							dirID = (*searchStack)[catPosition->stackDepth].dirID;
							index = (*searchStack)[catPosition->stackDepth].index;
							
							/* Check the dir's mod date against the saved mode date on our "stack" */
							modDate = GetDirModDate(realVRefNum, dirID);
							if ( modDate != (*searchStack)[catPosition->stackDepth].dirModDate )
							{
								result = catChangedErr;
							}
						}
						else
						{
							/* Invalid catPosition record was passed */
							result = paramErr;
						}
					}
					else
					{
						/* The volume is not the same */
						result = catChangedErr;
					}
				}
			}
			
			if ( result == noErr )
			{
				/* ioNamePtr and ioVRefNum only need to be set up once. */
				cPB.hFileInfo.ioNamePtr = itemName;
				cPB.hFileInfo.ioVRefNum = realVRefNum;
				
				/*
				**	Here's the loop that:
				**		Finds the next item on the volume.
				**		If noErr, calls the code to check for matches and add matches
				**			to the match buffer.
				**		Sets up dirID and index for to find the next item on the volume.
				**
				**	The looping ends when:
				**		(a) an unexpected error is returned by PBGetCatInfo. All that
				**			is expected is noErr and fnfErr (after the last item in a
				**			directory is found).
				**		(b) the caller specified a timeout and our Time Manager task
				**			has fired.
				**		(c) the number of matches requested by the caller has been found.
				**		(d) the last item on the volume was found.
				*/
				do
				{
					/* get the next item */
					cPB.hFileInfo.ioFDirIndex = index;
					cPB.hFileInfo.ioDirID = dirID;
					result = PBGetCatInfoSync(&cPB);
					if ( index != -1 )
					{
						if ( result == noErr )
						{
							/* We found something */
		
							CheckForMatches(&cPB, pb, upperName, includeFiles, includeDirs);
							
							++index;
							if ( (cPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0 )
							{
								/* It's a directory */
								
								result = CheckStack(catPosition->stackDepth, searchStack, &searchStackSize);
								if ( result == noErr )
								{
									/* Save the current state on the searchStack */
									/* when we come back, this is where we'll start */
									(*searchStack)[catPosition->stackDepth].dirID = dirID;
									(*searchStack)[catPosition->stackDepth].index = index;
									(*searchStack)[catPosition->stackDepth].dirModDate = GetDirModDate(realVRefNum, dirID);
									
									/* position catPosition->stackDepth for next saved level */
									++(catPosition->stackDepth);
									
									/* The next item to get is the 1st item in the child directory */
									dirID = cPB.dirInfo.ioDrDirID;
									index = 1;
								}
							}
							/* else do nothing for files */
						}
						else
						{
							/* End of directory found (or we had some error and that */
							/* means we have to drop out of this directory). */
							/* Restore last thing put on stack and */
							/* see if we need to continue or quit. */
							if ( catPosition->stackDepth > 0 )
							{
								/* position catPosition->stackDepth to access last saved level */
								--(catPosition->stackDepth);
								
								dirID = (*searchStack)[catPosition->stackDepth].dirID;
								index = (*searchStack)[catPosition->stackDepth].index;
								
								/* Check the dir's mod date against the saved mode date on our "stack" */
								modDate = GetDirModDate(realVRefNum, dirID);
								if ( modDate != (*searchStack)[catPosition->stackDepth].dirModDate )
								{
									result = catChangedErr;
								}
								else
								{
									/* Going back to ancestor directory. */
									/* Clear error so we can continue. */
									result = noErr;
								}
							}
							else
							{
								/* We hit the bottom of the stack, so we'll let the */
								/* the eofErr drop us out of the loop. */
								result = eofErr;
							}
						}
					}
					else
					{
						/* Special case for index == -1; that means that we're starting */
						/* a new search and so the first item to check is the directory */
						/* passed to us. */
						if ( result == noErr )
						{
							/* We found something */
		
							CheckForMatches(&cPB, pb, upperName, includeFiles, includeDirs);
							
							/* Now, set the index to 1 and then we're ready to look inside */
							/* the passed directory. */
							index = 1;
						}
					}
				} while ( (!timerTask.stopSearch) &&	/* timer hasn't fired */
						  (result == noErr) &&			/* no unexpected errors */
						  (pb->ioReqMatchCount > pb->ioActMatchCount) ); /* we haven't found our limit */
				
				/* Did we drop out of the loop because of timeout or */
				/* ioReqMatchCount was found? */
				if ( result == noErr )
				{
					result = CheckStack(catPosition->stackDepth, searchStack, &searchStackSize);
					if ( result == noErr )
					{
						/* Either there was a timeout or ioReqMatchCount was reached. */
						/* Save the dirID and index for the next time we're called. */
						
						(*searchStack)[catPosition->stackDepth].dirID = dirID;
						(*searchStack)[catPosition->stackDepth].index = index;
						(*searchStack)[catPosition->stackDepth].dirModDate = GetDirModDate(realVRefNum, dirID);
						
						/* position catPosition->stackDepth for next saved level */
						
						++(catPosition->stackDepth);
					}
				}
			}
		}
		else
		{
			/* searchStack Handle could not be allocated */
			result = memFullErr;
		}
	}
	
	if ( pb->ioSearchTime != 0 )
	{
		/* Stop Time Manager task here if it was installed */
		RmvTime((QElemPtr)&(timerTask.theTask));
		DisposeTimerUPP(timerTask.theTask.tmAddr);
	}
	
	return ( result );
}
Example #9
0
void NzLuaInstance::CheckStack(int space, const NzString& error) const
{
	CheckStack(space, error.GetConstBuffer());
}
Example #10
0
// =====================================================================================
//  RecursiveLeafFlow
//      Flood fill through the leafs
//      If src_portal is NULL, this is the originating leaf
// =====================================================================================
inline static void     RecursiveLeafFlow(const int leafnum, const threaddata_t* const thread, const pstack_t* const prevstack)
{
    pstack_t        stack;
    leaf_t*         leaf;

    leaf = &g_leafs[leafnum];
#ifdef USE_CHECK_STACK
    CheckStack(leaf, thread);
#endif

    {
        const unsigned offset = leafnum >> 3;
        const unsigned bit = (1 << (leafnum & 7));
    
        // mark the leaf as visible
        if (!(thread->leafvis[offset] & bit))
        {
            thread->leafvis[offset] |= bit;
            thread->base->numcansee++;
        }
    }

#ifdef USE_CHECK_STACK
    prevstack->next = &stack;
    stack.next = NULL;
#endif
    stack.head = prevstack->head;
    stack.leaf = leaf;
    stack.portal = NULL;
#ifdef RVIS_LEVEL_2
    stack.clipPlaneCount = -1;
    stack.clipPlane = NULL;
#endif

    // check all portals for flowing into other leafs       
    unsigned i;
    portal_t** plist = leaf->portals;

    for (i = 0; i < leaf->numportals; i++, plist++)
    {
        portal_t* p = *plist;

#if ZHLT_ZONES
        portal_t * head_p = stack.head->portal;
        if (g_Zones->check(head_p->zone, p->zone))
        {
            continue;
        }
#endif

        {
            const unsigned offset = p->leaf >> 3;
            const unsigned bit = 1 << (p->leaf & 7);

            if (!(stack.head->mightsee[offset] & bit))
            {
                continue;                                      // can't possibly see it
            }
            if (!(prevstack->mightsee[offset] & bit))
            {
                continue;                                      // can't possibly see it
            }
        }

        // if the portal can't see anything we haven't allready seen, skip it
        {
            long* test;

            if (p->status == stat_done)
            {
                test = (long*)p->visbits;
            }
            else
            {
                test = (long*)p->mightsee;
            }
    
            {
                const int bitlongs = g_bitlongs;

                {
                    long* prevmight = (long*)prevstack->mightsee;
                    long* might = (long*)stack.mightsee;
                
                    unsigned j;
                    for (j = 0; j < bitlongs; j++, test++, might++, prevmight++)
                    {
                        (*might) = (*prevmight) & (*test);
                    }
                }
        
                {
                    long* might = (long*)stack.mightsee;
                    long* vis = (long*)thread->leafvis;
                    unsigned j;
                    for (j = 0; j < bitlongs; j++, might++, vis++)
                    {
                        if ((*might) & ~(*vis))
                        {
                            break;
                        }
                    }
            
                    if (j == g_bitlongs)
                    {                                                  // can't see anything new
                        continue;
                    }
                }
            }
        }

        // get plane of portal, point normal into the neighbor leaf
        stack.portalplane = &p->plane;
        plane_t             backplane;
        VectorSubtract(vec3_origin, p->plane.normal, backplane.normal);
        backplane.dist = -p->plane.dist;

        if (VectorCompare(prevstack->portalplane->normal, backplane.normal))
        {
            continue;                                      // can't go out a coplanar face
        }

        stack.portal = p;
#ifdef USE_CHECK_STACK
        stack.next = NULL;
#endif
        stack.freewindings[0] = 1;
        stack.freewindings[1] = 1;
        stack.freewindings[2] = 1;

        stack.pass = ChopWinding(p->winding, &stack, thread->pstack_head.portalplane);
        if (!stack.pass)
        {
            continue;
        }

        stack.source = ChopWinding(prevstack->source, &stack, &backplane);
        if (!stack.source)
        {
            continue;
        }

        if (!prevstack->pass)
        {                                                  // the second leaf can only be blocked if coplanar
            RecursiveLeafFlow(p->leaf, thread, &stack);
            continue;
        }

        stack.pass = ChopWinding(stack.pass, &stack, prevstack->portalplane);
        if (!stack.pass)
        {
            continue;
        }

#ifdef RVIS_LEVEL_2
        if (stack.clipPlaneCount == -1)
        {
            stack.clipPlaneCount = 0;
            stack.clipPlane = (plane_t*)alloca(sizeof(plane_t) * prevstack->source->numpoints * prevstack->pass->numpoints);

            ClipToSeperators(prevstack->source, prevstack->pass, NULL, false, &stack);
            ClipToSeperators(prevstack->pass, prevstack->source, NULL, true, &stack);
        }

        if (stack.clipPlaneCount > 0)
        {
            unsigned j;
            for (j = 0; j < stack.clipPlaneCount && stack.pass != NULL; j++)
            {
                stack.pass = ChopWinding(stack.pass, &stack, &(stack.clipPlane[j]));
            }

            if (stack.pass == NULL)
            continue;
        }
#else

        stack.pass = ClipToSeperators(stack.source, prevstack->pass, stack.pass, false, &stack);
        if (!stack.pass)
        {
            continue;
        }

        stack.pass = ClipToSeperators(prevstack->pass, stack.source, stack.pass, true, &stack);
        if (!stack.pass)
        {
            continue;
        }
#endif

        if (g_fullvis)
        {
            stack.source = ClipToSeperators(stack.pass, prevstack->pass, stack.source, false, &stack);
            if (!stack.source)
            {
                continue;
            }

            stack.source = ClipToSeperators(prevstack->pass, stack.pass, stack.source, true, &stack);
            if (!stack.source)
            {
                continue;
            }
        }

        // flow through it for real
        RecursiveLeafFlow(p->leaf, thread, &stack);
    }

#ifdef RVIS_LEVEL_2
#if 0
    if (stack.clipPlane != NULL)
    {
        free(stack.clipPlane);
    }
#endif
#endif
}
Example #11
0
uintptr_t WINAPI MemoryManager::CollectMemory(void* arg)
{
  CollectionInfo* info = (CollectionInfo*)arg;

#ifndef _GC_SERIAL
  EnterCriticalSection(&allocated_cs);
#endif
  std::sort(allocated_memory.begin(), allocated_memory.end());
#ifndef _GC_SERIAL
  LeaveCriticalSection(&allocated_cs);
#endif

#ifdef _DEBUG
  long start = allocation_size;
  wcout << dec << endl << L"=========================================" << endl;
  wcout << L"Starting Garbage Collection; thread=" << GetCurrentThread() << endl;
  wcout << L"=========================================" << endl;
  wcout << L"## Marking memory ##" << endl;
#endif

#ifndef GC_SERIAL
  const int num_threads = 4;
  HANDLE thread_ids[num_threads];

  thread_ids[0] = (HANDLE)_beginthreadex(NULL, 0, CheckStatic, info, 0, NULL);
  if(!thread_ids[0]) {
    wcerr << L"Unable to create garbage collection thread!" << endl;
    exit(-1);
  }

  thread_ids[1] = (HANDLE)_beginthreadex(NULL, 0, CheckStack, info, 0, NULL);
  if(!thread_ids[1]) {
    wcerr << L"Unable to create garbage collection thread!" << endl;
    exit(-1);
  }

  thread_ids[2] = (HANDLE)_beginthreadex(NULL, 0, CheckPdaRoots, NULL, 0, NULL);
  if(!thread_ids[2]) {
    wcerr << L"Unable to create garbage collection thread!" << endl;
    exit(-1);
  }

  thread_ids[3] = (HANDLE)_beginthreadex(NULL, 0, CheckJitRoots, NULL, 0, NULL);
  if(!thread_ids[3]) {
    wcerr << L"Unable to create garbage collection thread!" << endl;
    exit(-1);
  }

  // join all of the mark threads
  if(WaitForMultipleObjects(num_threads, thread_ids, TRUE, INFINITE) != WAIT_OBJECT_0) {
    wcerr << L"Unable to join garbage collection threads!" << endl;
    exit(-1);
  }

  for(int i=0; i < num_threads; i++) {
    CloseHandle(thread_ids[i]);
  }
#else
  CheckStatic(NULL);
  CheckStack(info);
  CheckPdaRoots(NULL);
  CheckJitRoots(NULL);
#endif

  // sweep memory
#ifdef _DEBUG
  wcout << L"## Sweeping memory ##" << endl;
#endif

  // sort and search
#ifndef GC_SERIAL
  EnterCriticalSection(&allocated_cs);
  EnterCriticalSection(&marked_cs);
#endif

#ifdef _DEBUG
  wcout << L"-----------------------------------------" << endl;
  wcout << L"Marked " << marked_memory.size() << L" items." << endl;
  wcout << L"-----------------------------------------" << endl;
#endif
  std::sort(marked_memory.begin(), marked_memory.end());
#ifndef GC_SERIAL

#endif
  vector<long*> live_memory;
  live_memory.reserve(allocated_memory.size());
  for(size_t i = 0; i < allocated_memory.size(); ++i) {
    long* mem = allocated_memory[i];

    // check dynamic memory
    bool found = false;
    if(std::binary_search(marked_memory.begin(), marked_memory.end(), mem)) {
      long* tmp = mem;
      tmp[MARKED_FLAG] = 0L;
      found = true;
    }

    // live
    if(found) {
      live_memory.push_back(mem);
    }
    // will be collected
    else {
      // object or array	
      long mem_size;
      if(mem[TYPE] == NIL_TYPE) {
        StackClass* cls = (StackClass*)mem[SIZE_OR_CLS];
#ifdef _DEBUG
        assert(cls);
#endif
        if(cls) {
          mem_size = cls->GetInstanceMemorySize();
        }
        else {
          mem_size = mem[SIZE_OR_CLS];
        }
      } 
      else {
        mem_size = mem[SIZE_OR_CLS];
      }

      // account for deallocated memory
      allocation_size -= mem_size;

      // cache or free memory
      long* tmp = mem - EXTRA_BUF_SIZE;
      switch(mem[CACHE_SIZE]) {
      case 512:	  
        if(cache_pool_512.size() < POOL_SIZE + 1) {
          memset(tmp, 0, 512);
          cache_pool_512.push((char*)tmp);
#ifdef _DEBUG
          wcout << L"# caching memory: addr=" << mem << L"(" << (long)mem
            << L"), size=" << mem_size << L" byte(s) #" << endl;
#endif
        }
        break;

      case 256:
        if(cache_pool_256.size() < POOL_SIZE + 1) {
          memset(tmp, 0, 256);
          cache_pool_256.push((char*)tmp);
#ifdef _DEBUG
          wcout << L"# caching memory: addr=" << mem << L"(" << (long)mem
            << L"), size=" << mem_size << L" byte(s) #" << endl;
#endif
        }
        break;

      case 64:
        if(cache_pool_64.size() < POOL_SIZE + 1) {
          memset(tmp, 0, 64);
          cache_pool_64.push((char*)tmp);
#ifdef _DEBUG
          wcout << L"# caching memory: addr=" << mem << L"(" << (long)mem
            << L"), size=" << mem_size << L" byte(s) #" << endl;
#endif
        }
        break;

      case 32:
        if(cache_pool_32.size() < POOL_SIZE + 1) {
          memset(tmp, 0, 32);
          cache_pool_32.push((char*)tmp);
#ifdef _DEBUG
          wcout << L"# caching memory: addr=" << mem << L"(" << (long)mem
            << L"), size=" << mem_size << L" byte(s) #" << endl;
#endif
        }
        break;

      case 16:
        if(cache_pool_16.size() < POOL_SIZE + 1) {
          memset(tmp, 0, 16);
          cache_pool_16.push((char*)tmp);
#ifdef _DEBUG
          wcout << L"# caching memory: addr=" << mem << L"(" << (long)mem
            << L"), size=" << mem_size << L" byte(s) #" << endl;
#endif
        }
        break;

      default:
        free(tmp);
        tmp = NULL;
#ifdef _DEBUG
        wcout << L"# freeing memory: addr=" << mem << L"(" << (long)mem
          << L"), size=" << mem_size << L" byte(s) #" << endl;
#endif
        break;
      }
    }
  }
  marked_memory.clear();
#ifndef GC_SERIAL
  LeaveCriticalSection(&marked_cs);
#endif  

  // did not collect memory; ajust constraints
  if(live_memory.size() == allocated_memory.size()) {
    if(uncollected_count < UNCOLLECTED_COUNT) {
      uncollected_count++;
    } else {
      mem_max_size <<= 2;
      uncollected_count = 0;
    }
  }
  // collected memory; ajust constraints
  else if(mem_max_size != MEM_MAX) {
    if(collected_count < COLLECTED_COUNT) {
      collected_count++;
    } else {
      mem_max_size >>= 1;
      collected_count = 0;
    }
  }

  // copy live memory to allocated memory
  allocated_memory = live_memory;
#ifndef GC_SERIAL
  LeaveCriticalSection(&allocated_cs);
#endif

#ifdef _DEBUG
  wcout << L"===============================================================" << endl;
  wcout << L"Finished Collection: collected=" << (start - allocation_size)
    << L" of " << start << L" byte(s) - " << showpoint << setprecision(3)
    << (((double)(start - allocation_size) / (double)start) * 100.0)
    << L"%" << endl;
  wcout << L"===============================================================" << endl;
#endif

  return 0;
}