Exemple #1
0
// Report heap sizes and occupancy before and after GC
void MemMgr::ReportHeapSizes(const char *phase)
{
    POLYUNSIGNED alloc = 0, nonAlloc = 0, inAlloc = 0, inNonAlloc = 0;
    for (unsigned i = 0; i < nlSpaces; i++)
    {
        LocalMemSpace *sp = lSpaces[i];
        if (sp->allocationSpace)
        {
            alloc += sp->spaceSize();
            inAlloc += sp->allocatedSpace();
        }
        else
        {
            nonAlloc += sp->spaceSize();
            inNonAlloc += sp->allocatedSpace();
        }
    }
    Log("Heap: %s Major heap used ", phase);
    LogSize(inNonAlloc); Log(" of ");
    LogSize(nonAlloc);
    Log(" (%1.0f%%). Alloc space used ", (float)inNonAlloc / (float)nonAlloc * 100.0F);
    LogSize(inAlloc); Log(" of ");
    LogSize(alloc);
    Log(" (%1.0f%%). Total space ", (float)inAlloc / (float)alloc * 100.0F);
    LogSize(spaceForHeap);
    Log(" %1.0f%% full.\n", (float)(inAlloc + inNonAlloc) / (float)spaceForHeap * 100.0F);
}
Exemple #2
0
// Set the initial size based on any parameters specified on the command line
void HeapSizeParameters::SetHeapParameters(unsigned minsize, unsigned maxsize, unsigned percent)
{
    minHeapSize = K_to_words(minsize); // If these overflow assume the result will be zero
    maxHeapSize = K_to_words(maxsize);

    POLYUNSIGNED memsize = 0;
    if (minHeapSize == 0 || maxHeapSize == 0)
        memsize = GetPhysicalMemorySize() / sizeof(PolyWord);

    // If no maximum is given default it to 80% of the physical memory.
    // This allows some space for the OS and other things.
    if (maxHeapSize == 0 || maxHeapSize > MAXIMUMADDRESS)
    {
        if (memsize == 0) maxHeapSize = MAXIMUMADDRESS;
        else maxHeapSize = memsize - memsize / 5;
    }

    // Set the initial size to the minimum if that has been provided.
    POLYUNSIGNED initialSize = minHeapSize;

    if (initialSize == 0) {
        // If no -H option was given set the default initial size to a quarter of the memory.
        if (memsize == 0) // Unable to determine memory size so default to 64M.
            initialSize = 64 * 1024 * 1024;
        else initialSize =  memsize / 4;
    }

    // Initially we divide the space equally between the major and
    // minor heaps.  That means that there will definitely be space
    // for the first minor GC to copy its data.  This division can be
    // changed later on.
    gMem.SetSpaceForHeap(initialSize);
    gMem.SetSpaceBeforeMinorGC(initialSize/2);
    lastFreeSpace = initialSize;
    highWaterMark = initialSize;

    if (percent == 0)
        userGCRatio = 1.0 / 9.0; // Default to 10% GC to 90% application
    else
        userGCRatio = (float)percent / (float)(100 - percent);

    predictedRatio = lastMajorGCRatio = userGCRatio;

    if (debugOptions & DEBUG_HEAPSIZE)
    {
        Log("Heap: Initial settings: Initial heap ");
        LogSize(initialSize);
        Log(" minimum ");
        LogSize(minHeapSize);
        Log(" maximum ");
        LogSize(maxHeapSize);
        Log(" target ratio %f\n", userGCRatio);
    }
}
Exemple #3
0
// Estimate the GC cost for a given heap size.  The result is the ratio of
// GC time to application time.
// This is really guesswork.
double HeapSizeParameters::costFunction(POLYUNSIGNED heapSize, bool withSharing, bool withSharingCost)
{
    POLYUNSIGNED heapSpace = gMem.SpaceForHeap() < highWaterMark ? gMem.SpaceForHeap() : highWaterMark;
    POLYUNSIGNED currentFreeSpace = heapSpace - currentSpaceUsed;
    POLYUNSIGNED averageFree = (lastFreeSpace + currentFreeSpace) / 2;
    POLYUNSIGNED spaceUsed = currentSpaceUsed;
    if (heapSize <= currentSpaceUsed)
        return 1.0E6;
    // If we run the sharing pass the live space will be smaller.
    if (withSharing)
        spaceUsed -= (POLYUNSIGNED)((double)currentSpaceUsed * sharingRecoveryRate);
    POLYUNSIGNED estimatedFree = heapSize - spaceUsed;
    // The cost scales as the inverse of the amount of free space.
    double result = lastMajorGCRatio * (double)averageFree / (double)estimatedFree;
    // If we run the sharing pass the GC cost will increase.
    if (withSharing && withSharingCost)
        result += result*sharingCostFactor;

    // The paging contribution depends on the page limit
    double pagingCost = 0.0;
    if (pagingLimitSize != 0)
    {
        double factor = ((double)heapSize - (double)pagingLimitSize) / (double)pagingLimitSize * PAGINGCOSTSTEEPNESS;
        pagingCost = PAGINGCOSTFACTOR * exp(factor);
        result += pagingCost;
    }

    if (debugOptions & DEBUG_HEAPSIZE)
    {
        Log("Heap: Cost for heap of size ");
        LogSize(heapSize);
        Log(" is %2.2f with paging contributing %2.2f with%s sharing pass.\n", result, pagingCost, withSharing ? "" : "out");
    }
    return result;
}
Exemple #4
0
// Called in the minor GC if a GC thread needs to grow the heap.
// Returns zero if the heap cannot be grown. "space" is the space required for the
// object (and length field) in case this is larger than the default size.
LocalMemSpace *HeapSizeParameters::AddSpaceInMinorGC(POLYUNSIGNED space, bool isMutable)
{
    // See how much space is allocated to the major heap.
    POLYUNSIGNED spaceAllocated = gMem.CurrentHeapSize() - gMem.CurrentAllocSpace();

    // The new segment is either the default size or as large as
    // necessary for the object.
    POLYUNSIGNED spaceSize = gMem.DefaultSpaceSize();
    if (space > spaceSize) spaceSize = space;

    // We allow for extension if the total heap size after extending it
    // plus one allocation area of the default size would not be more
    // than the allowed heap size.
    if (spaceAllocated + spaceSize + gMem.DefaultSpaceSize() <= gMem.SpaceForHeap())
    {
        LocalMemSpace *sp = gMem.NewLocalSpace(spaceSize, isMutable); // Return the space or zero if it failed
        // If this is the first time the allocation failed report it.
        if (sp == 0 && (debugOptions & DEBUG_HEAPSIZE) && lastAllocationSucceeded)
        {
            Log("Heap: Allocation of new heap segment size ");
            LogSize(spaceSize);
            Log(" failed.  Limit reached?\n");
        }
        lastAllocationSucceeded = sp != 0;
        return sp;
    }
    return 0; // Insufficient space
}
void SymbianLog::printMessage(const char* level, const char* msg, PLATFORM_VA_LIST argList) 
{
    iSemaphore.Wait();
    
    StringBuffer currentTime = createCurrentTime(true);
    
    TInt err = file.Open(fsSession, iLogName, EFileWrite|EFileShareAny);
    TInt pos = 0;
    
    if (err == KErrNotFound) 
    {
        // First time: file does not exist. Create it.
        err = file.Create(fsSession, iLogName, EFileWrite|EFileShareAny);
        if (err != KErrNone) {
            setErrorF(err, "SymbianLog: could not open log file (code %d)", err);
            goto finally;
        }
        StringBuffer header = createHeader();
        RBuf8 data;
        data.Assign(stringBufferToNewBuf8(header));
        file.Write(data);
        data.Close();
    }
    else 
    {
        err = file.Seek(ESeekEnd, pos);
        if (err != KErrNone) {
            setErrorF(err, "SymbianLog: seek error on log file (code %d)", err);
            goto finally;
        }
    }

    {
        // Write the data
        StringBuffer line, data;
        line.sprintf("%s -%s- %s", currentTime.c_str(), level, msg);
        data.vsprintf(line.c_str(), argList);
        data.append("\n");
        
        RBuf8 buf;
        buf.Assign(stringBufferToNewBuf8(data));
        file.Write(buf);
        buf.Close();
    }
    
finally:
    file.Close();
    // we need closed file to operate on it
    if ( LogSize() > SYMBIAN_LOG_SIZE ){
        // roll log file
        RollLogFile();
    }
    iSemaphore.Signal();
}
Exemple #6
0
// Called after a minor GC.  Currently does nothing.
// See also adjustHeapSize for adjustments after a major GC.
bool HeapSizeParameters::AdjustSizeAfterMinorGC(POLYUNSIGNED spaceAfterGC, POLYUNSIGNED spaceBeforeGC)
{
    POLYUNSIGNED spaceCopiedOut = spaceAfterGC-spaceBeforeGC;
    TIMEDATA gc, total;
    minorGCsSinceMajor++;
    // The major costs are cumulative so we use those
    gc.add(majorGCSystemCPU);
    gc.add(majorGCUserCPU);
    total.add(gc);
    total.add(majorNonGCSystemCPU);
    total.add(majorNonGCUserCPU);
    float g = gc.toSeconds() / total.toSeconds();

    if (debugOptions & DEBUG_HEAPSIZE)
    {
        Log("Heap: Space before ");
        LogSize(spaceBeforeGC);
        Log(", space after ");
        LogSize(spaceAfterGC);
        Log("\n");
        Log("Heap: Minor resizing factors g = %f, recent pf = %ld, cumulative pf = %ld\n",
            g, minorGCPageFaults, majorGCPageFaults);
    }

    if (highWaterMark < gMem.CurrentHeapSize()) highWaterMark = gMem.CurrentHeapSize();

    POLYUNSIGNED nextLimit = highWaterMark + highWaterMark / 32;
    if (nextLimit > gMem.SpaceForHeap()) nextLimit = gMem.SpaceForHeap();

    // Set the space available for the allocation area to be the difference between the
    // total heap size and the allowed heap size together with as much space as we copied
    // on this GC.  That allows for the next minor GC to copy the same amount without
    // extending the heap.  If the next minor GC adds more than this the heap will be
    // extended and a corresponding amount deducted so that the heap shrinks again.
    POLYUNSIGNED nonAlloc = gMem.CurrentHeapSize() - gMem.CurrentAllocSpace() + spaceCopiedOut;
    // TODO: If we have limited the space to the high water mark + 1/32 but that is less
    // than we really need we should increase it further.
    POLYUNSIGNED allowedAlloc = nonAlloc >= nextLimit ? 0 : nextLimit - nonAlloc;
    // If we hit the limit at the last major GC we have to be much more careful.
    // If the minor GC cannot allocate a major GC space when it needs it the minor
    // GC will fail immediately and a major GC will be started.  It's better to
    // risk doing more minor GCs than we need by making the allocation area smaller
    // rather than run out of space.
    if (allocationFailedBeforeLastMajorGC)
        allowedAlloc = allowedAlloc / 2;
    if (gMem.CurrentAllocSpace() != allowedAlloc)
    {
        if (debugOptions & DEBUG_HEAPSIZE)
        {
            Log("Heap: Adjusting space for allocation area from ");
            LogSize(gMem.SpaceBeforeMinorGC());
            Log(" to ");
            LogSize(allowedAlloc);
            Log("\n");
        }
        gMem.SetSpaceBeforeMinorGC(allowedAlloc);
        if (allowedAlloc < gMem.DefaultSpaceSize() * 2 || minorGCPageFaults > 100)
            return false; // Trigger full GC immediately.
     }

    // Trigger a full GC if the live data is very large or if we have exceeeded
    // the target ratio over several GCs (this smooths out small variations).
    if ((minorGCsSinceMajor > 4 && g > predictedRatio*0.8) || majorGCPageFaults > 100)
        fullGCNextTime = true;
    return true;
}
Exemple #7
0
// Called at the end of collection.  This is where we should do the
// fine adjustment of the heap size to minimise the GC time.
// Growing the heap is just a matter of adjusting the limits.  We
// don't actually need to allocate the space here.
// See also adjustHeapSizeAfterMinorGC for adjustments after a minor GC.
void HeapSizeParameters::AdjustSizeAfterMajorGC(POLYUNSIGNED wordsRequired)
{
    // Cumulative times since the last major GC
    TIMEDATA gc, nonGc;
    gc.add(majorGCSystemCPU);
    gc.add(majorGCUserCPU);
    nonGc.add(majorNonGCSystemCPU);
    nonGc.add(majorNonGCUserCPU);

    if (highWaterMark < heapSizeAtStart) highWaterMark = heapSizeAtStart;

    POLYUNSIGNED heapSpace = gMem.SpaceForHeap() < highWaterMark ? gMem.SpaceForHeap() : highWaterMark;
    currentSpaceUsed = 0;
    for (unsigned i = 0; i < gMem.nlSpaces; i++)
    {
        currentSpaceUsed += gMem.lSpaces[i]->allocatedSpace();
    }
    POLYUNSIGNED currentFreeSpace = heapSpace - currentSpaceUsed;
    if (currentFreeSpace < wordsRequired) currentFreeSpace = 0; else currentFreeSpace -= wordsRequired;

    // The times for all the minor GCs up to this.  The cost of this (major) GC
    // is actually in minorGCUserCPU/minorGCSystemCPU.
    TIMEDATA minorGC;
    minorGC.add(gc);
    minorGC.sub(minorGCUserCPU);
    minorGC.sub(minorGCSystemCPU);

    if (performSharingPass)
    {
        // We ran the sharing pass last time: calculate the actual recovery rate.
        POLYUNSIGNED originalSpaceUsed = currentSpaceUsed + sharingWordsRecovered;
        sharingRecoveryRate = (double)sharingWordsRecovered / (double)originalSpaceUsed;
        if (debugOptions & DEBUG_HEAPSIZE)
            Log("Heap: Sharing recovery rate was %0.3f and cost %0.3f seconds (%0.3f%% of total).\n",
                sharingRecoveryRate, sharingCPU.toSeconds(), sharingCPU.toSeconds() / gc.toSeconds());
        // The cost factor is the ratio of the cost of sharing to the cost without.
        sharingCostFactor = sharingCPU.toSeconds() / (gc.toSeconds() - sharingCPU.toSeconds());
        // Subtract the sharing cost from the GC cost because the initial estimate is
        // the cost without running the sharing pass.
        gc.sub(sharingCPU);
    }

    if (gc.toSeconds() != 0.0 && nonGc.toSeconds() != 0.0)
        lastMajorGCRatio = gc.toSeconds() / nonGc.toSeconds();

    if (debugOptions & DEBUG_HEAPSIZE)
    {
        Log("Heap: GC cpu time %2.3f non-gc time %2.3f ratio %0.3f for free space ",
            gc.toSeconds(), nonGc.toSeconds(), lastMajorGCRatio);
        LogSize((lastFreeSpace + currentFreeSpace)/2);
        Log("\n");
        Log("Heap: GC real time %2.3f non-gc time %2.3f ratio %0.3f\n",
            majorGCReal.toSeconds(), majorNonGCReal.toSeconds(), majorGCReal.toSeconds()/majorNonGCReal.toSeconds());
        Log("Heap: Total of minor GCs %2.3f, %2.3f of total\n", minorGC.toSeconds(), minorGC.toSeconds() / gc.toSeconds());
    }

    // Calculate the paging threshold.
    if (pagingLimitSize != 0 || majorGCPageFaults != 0)
    {
        if (majorGCPageFaults == 0) majorGCPageFaults = 1; // Less than one
        // Some paging detected.  The expression here is the inverse of the one used to
        // compute the paging contribution in the cost function.
        double scaleFactor = 1.0 + log((double)majorGCPageFaults / PAGINGCOUNTFACTOR) / PAGINGCOSTSTEEPNESS;
        ASSERT(scaleFactor > 0.0);
        POLYUNSIGNED newLimit = (POLYUNSIGNED)((double)heapSpace / scaleFactor);
        if (pagingLimitSize == 0)
            pagingLimitSize = newLimit;
        else 
            pagingLimitSize = (newLimit + pagingLimitSize) / 2;
    }
    if (allocationFailedBeforeLastMajorGC)
    {
        // If the last allocation failed then we may well have reached the
        // maximum available memory.  Set the paging limit to be the current
        // heap size.  We want to avoid hitting the limit because typically
        // that happens when we try to extend the major heap in a minor GC
        // resulting in the minor GC failing and a major GC starting.
        if (pagingLimitSize == 0 || heapSizeAtStart < pagingLimitSize)
            pagingLimitSize = heapSizeAtStart;
    }
    if (pagingLimitSize != 0 && (debugOptions & DEBUG_HEAPSIZE))
    {
        Log("Heap: Paging threshold adjusted to ");
        LogSize(pagingLimitSize);
        Log(" with %ld page faults\n", majorGCPageFaults);
    }

    // Calculate the new heap size and the predicted cost.
    POLYUNSIGNED newHeapSize;
    double cost;
    bool atTarget = getCostAndSize(newHeapSize, cost, false);
    // If we have been unable to allocate any more memory we may already
    // be at the limit.
    if (allocationFailedBeforeLastMajorGC && newHeapSize > heapSizeAtStart)
    {
        cost = costFunction(heapSizeAtStart, false, true);
        atTarget = false;
    }

    if (atTarget)
    {
        // We are at the target level.  We don't want to attempt sharing.
        performSharingPass = false;
        cumulativeSharingSaving = 0;
    }
    else
    {
        POLYUNSIGNED newHeapSizeWithSharing;
        double costWithSharing;
        // Get the cost and heap size if sharing was enabled.  If we are at the
        // limit, though, we need to work using the size we can achieve.
        if (! allocationFailedBeforeLastMajorGC)
            (void)getCostAndSize(newHeapSizeWithSharing, costWithSharing, true);
        else
        {
            newHeapSizeWithSharing = heapSizeAtStart;
            costWithSharing = costFunction(heapSizeAtStart, true, true);
        }
        // Run the sharing pass if that would give a lower cost.
        // Subtract the cumulative saving that would have been made if the
        // sharing had been run before.  This is an estimate and depends on the
        // extent to which a reduction in the heap earlier would be carried through
        // to later GCs.
        cumulativeSharingSaving =
            cumulativeSharingSaving * ((double)currentSpaceUsed / (double)heapSpace);
        if (debugOptions & DEBUG_HEAPSIZE)
            Log("Heap: Cumulative sharing saving %0.2f\n", cumulativeSharingSaving);
        if (costWithSharing - cumulativeSharingSaving < cost)
        {
            // Run the sharing pass next time.
            performSharingPass = true;
            cumulativeSharingSaving = 0;
        }
        else
        {
            // Don't run the sharing pass next time
            performSharingPass = false;
            // Running a sharing pass reduces the heap for subsequent
            // runs.  Add this into the cost.
            double freeSharingCost = costFunction(newHeapSizeWithSharing, true, false);
            if (freeSharingCost < cost && freeSharingCost > userGCRatio)
            {
                if (debugOptions & DEBUG_HEAPSIZE)
                    Log("Heap: Previous sharing would have saved %0.2f\n", cost - freeSharingCost);
                cumulativeSharingSaving += cost - freeSharingCost;
            }
        }
    }

    if (debugOptions & DEBUG_HEAPSIZE)
    {
        if (performSharingPass)
            Log("Heap: Next full GC will enable the sharing pass\n");
        Log("Heap: Resizing from ");
        LogSize(gMem.SpaceForHeap());
        Log(" to ");
        LogSize(newHeapSize);
        Log(".  Estimated ratio %2.2f\n", cost);
    }
    // Set the sizes.
    gMem.SetSpaceForHeap(newHeapSize);
    // Set the minor space size.  It can potentially use the whole of the
    // rest of the available heap but there could be a problem if that exceeds
    // the available memory and causes paging.  We need to raise the limit carefully.
    // Also, if we use the whole of the heap we may not then be able to allocate
    // new areas in the major heap without going over the limit.  Restrict it to
    // half of the available heap.
    POLYUNSIGNED nextLimit = highWaterMark + highWaterMark / 32;
    if (nextLimit > newHeapSize) nextLimit = newHeapSize;
    // gMem.CurrentHeapSize() is the live space size.
    if (gMem.CurrentHeapSize() > nextLimit)
        gMem.SetSpaceBeforeMinorGC(0); // Run out of space
    else gMem.SetSpaceBeforeMinorGC((nextLimit-gMem.CurrentHeapSize())/2);

    lastFreeSpace = newHeapSize - currentSpaceUsed;
    predictedRatio = cost;
}
Exemple #8
0
void ComspecDone(int aiRc)
{
#ifdef _DEBUG
    xf_dump_chk();
    xf_validate(NULL);
#endif
    //WARNING("Послать в GUI CONEMUCMDSTOPPED");
    LogSize(NULL, 0, "ComspecDone");

    // Это необходимо делать, т.к. при смене буфера (SetConsoleActiveScreenBuffer) приложением,
    // дескриптор нужно закрыть, иначе conhost может не вернуть предыдущий буфер
    //ConOutCloseHandle()

    // Поддержка алиасов
    if (gpSrv->szComSpecName[0] && gpSrv->szSelfName[0])
    {
        // Скопировать алиасы из cmd.exe в conemuc.exe
        wchar_t *pszPostAliases = NULL;
        DWORD nPostAliasSize;
        BOOL lbChanged = (gpSrv->pszPreAliases == NULL);

        if (!GetAliases(gpSrv->szComSpecName, &pszPostAliases, &nPostAliasSize))
        {
            if (pszPostAliases)
                _wprintf(pszPostAliases);
        }
        else
        {
            if (!lbChanged)
            {
                lbChanged = (gpSrv->nPreAliasSize!=nPostAliasSize);
            }

            if (!lbChanged && gpSrv->nPreAliasSize && gpSrv->pszPreAliases && pszPostAliases)
            {
                lbChanged = memcmp(gpSrv->pszPreAliases,pszPostAliases,gpSrv->nPreAliasSize)!=0;
            }

            if (lbChanged)
            {
                xf_dump_chk();

                if (gnMainServerPID)
                {
                    MCHKHEAP;
                    CESERVER_REQ* pIn = ExecuteNewCmd(CECMD_SAVEALIASES,sizeof(CESERVER_REQ_HDR)+nPostAliasSize);

                    if (pIn)
                    {
                        MCHKHEAP;
                        memmove(pIn->Data, pszPostAliases, nPostAliasSize);
                        MCHKHEAP;
                        CESERVER_REQ* pOut = ExecuteSrvCmd(gnMainServerPID, pIn, GetConEmuHWND(2), FALSE, 0, TRUE);
                        MCHKHEAP;

                        if (pOut) ExecuteFreeResult(pOut);

                        ExecuteFreeResult(pIn);
                        MCHKHEAP;
                    }
                }

                xf_dump_chk();
                wchar_t *pszNewName = pszPostAliases, *pszNewTarget, *pszNewLine;

                while (pszNewName && *pszNewName)
                {
                    pszNewLine = pszNewName + lstrlen(pszNewName);
                    pszNewTarget = wcschr(pszNewName, L'=');

                    if (pszNewTarget)
                    {
                        *pszNewTarget = 0;
                        pszNewTarget++;
                    }

                    if (*pszNewTarget == 0) pszNewTarget = NULL;

                    AddConsoleAlias(pszNewName, pszNewTarget, gpSrv->szSelfName);
                    pszNewName = pszNewLine+1;
                }

                xf_dump_chk();
            }
        }

        if (pszPostAliases)
        {
            free(pszPostAliases);
            pszPostAliases = NULL;
        }
    }

    xf_dump_chk();
    //TODO("Уведомить плагин через пайп (если родитель - FAR) что процесс завершен. Плагин должен считать и запомнить содержимое консоли и только потом вернуть управление в ConEmuC!");
    DWORD dwErr1 = 0; //, dwErr2 = 0;
    HANDLE hOut1 = NULL, hOut2 = NULL;
    BOOL lbRc1 = FALSE, lbRc2 = FALSE;
    CONSOLE_SCREEN_BUFFER_INFO sbi1 = {{0,0}}, sbi2 = {{0,0}};

#ifdef _DEBUG
    HWND hWndCon = GetConEmuHWND(2);
#endif

    // Тут нужна реальная, а не скорректированная информация!
    if (!gbNonGuiMode)
    {
        // Если GUI не сможет через сервер вернуть высоту буфера - это нужно сделать нам!
        lbRc1 = GetConsoleScreenBufferInfo(hOut1 = GetStdHandle(STD_OUTPUT_HANDLE), &sbi1);

        if (!lbRc1)
            dwErr1 = GetLastError();

        xf_dump_chk();
    }

    //PRAGMA_ERROR("Размер должен возвращать сам GUI, через серверный ConEmuC!");
#ifdef SHOW_STARTED_MSGBOX
    MessageBox(GetConEmuHWND(2), L"ConEmuC (comspec mode) is about to TERMINATE", L"ConEmuC.ComSpec", 0);
#endif

#ifdef _DEBUG
    xf_dump_chk();
    xf_validate(NULL);
#endif

    if (!gbNonGuiMode && (gpSrv->dwParentFarPID != 0))
    {
        //// Вернуть размер буфера (высота И ширина)
        //if (gpSrv->sbi.dwSize.X && gpSrv->sbi.dwSize.Y) {
        //	SMALL_RECT rc = {0};
        //	SetConsoleSize(0, gpSrv->sbi.dwSize, rc, "ComspecDone");
        //}
        //ConOutCloseHandle()
        CONSOLE_SCREEN_BUFFER_INFO l_csbi = {{0}};
        lbRc2 = GetConsoleScreenBufferInfo(hOut2 = GetStdHandle(STD_OUTPUT_HANDLE), &l_csbi);

        CESERVER_REQ *pOut = SendStopped(&l_csbi);

        if (pOut)
        {
            if (!pOut->StartStopRet.bWasBufferHeight)
            {
                //gpSrv->sbi.dwSize = pIn->StartStop.sbi.dwSize;
                lbRc1 = FALSE; // Консольное приложение самостоятельно сбросило буферный режим. Не дергаться...
            }
            else
            {
                lbRc1 = TRUE;
            }

            ExecuteFreeResult(pOut);
            pOut = NULL;
        }

        if (!gbWasBufferHeight)
        {
            lbRc2 = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbi2);

#ifdef _DEBUG
            if (sbi2.dwSize.Y > 200)
            {
                wchar_t szTitle[128];
                _wsprintf(szTitle, SKIPLEN(countof(szTitle)) L"ConEmuC (PID=%i)", GetCurrentProcessId());
                MessageBox(NULL, L"BufferHeight was not turned OFF", szTitle, MB_SETFOREGROUND|MB_SYSTEMMODAL);
            }
#endif

            if (lbRc1 && lbRc2 && sbi2.dwSize.Y == sbi1.dwSize.Y)
            {
                // GUI не смог вернуть высоту буфера...
                // Это плохо, т.к. фар высоту буфера не меняет и будет сильно глючить на N сотнях строк...
                int nNeedHeight = gpSrv->sbi.dwSize.Y;

                if (nNeedHeight < 10)
                {
                    nNeedHeight = (sbi2.srWindow.Bottom-sbi2.srWindow.Top+1);
                }

                if (sbi2.dwSize.Y != nNeedHeight)
                {
                    _ASSERTE(sbi2.dwSize.Y == nNeedHeight);
                    PRINT_COMSPEC(L"Error: BufferHeight was not changed from %i\n", sbi2.dwSize.Y);
                    SMALL_RECT rc = {0};
                    sbi2.dwSize.Y = nNeedHeight;

                    if (gpLogSize) LogSize(&sbi2.dwSize, 0, ":ComspecDone.RetSize.before");

                    SetConsoleSize(0, sbi2.dwSize, rc, "ComspecDone.Force");

                    if (gpLogSize) LogSize(NULL, 0, ":ComspecDone.RetSize.after");
                }
            }
        }
    }

    if (gpSrv->pszPreAliases) {
        free(gpSrv->pszPreAliases);
        gpSrv->pszPreAliases = NULL;
    }

    //SafeCloseHandle(ghCtrlCEvent);
    //SafeCloseHandle(ghCtrlBreakEvent);
}
Exemple #9
0
// Set the initial size based on any parameters specified on the command line.
// Any of these can be zero indicating they should default.
void HeapSizeParameters::SetHeapParameters(POLYUNSIGNED minsize, POLYUNSIGNED maxsize, POLYUNSIGNED initialsize, unsigned percent)
{
    minHeapSize = K_to_words(minsize); // If these overflow assume the result will be zero
    maxHeapSize = K_to_words(maxsize);
    POLYUNSIGNED initialSize = K_to_words(initialsize);

    POLYUNSIGNED memsize = GetPhysicalMemorySize() / sizeof(PolyWord);

    // If no maximum is given default it to 80% of the physical memory.
    // This allows some space for the OS and other things.
    if (maxHeapSize == 0 || maxHeapSize > MAXIMUMADDRESS)
    {
        if (memsize != 0)
            maxHeapSize = memsize - memsize / 5;
        else maxHeapSize = MAXIMUMADDRESS;
        // But if this must not be smaller than the minimum size.
        if (maxHeapSize < minHeapSize) maxHeapSize = minHeapSize;
        if (maxHeapSize < initialSize) maxHeapSize = initialSize;
    }

    // The default minimum is zero; in practice the live data size.

    // The default initial size is the minimum if that has been provided,
    // otherwise 8M words.  There are applications that only require a small
    // heap and if we set the heap large to begin with we'll never do a
    // full GC and reduce it.
    if (initialSize == 0)
    {
        if (minHeapSize != 0)
            initialSize = minHeapSize;
        else initialSize = 8 * gMem.DefaultSpaceSize();
        // But not more than the maximum
        if (initialSize > maxHeapSize) initialSize = maxHeapSize;
    }
    // Together with the constraints on user settings that ensures this holds.
    ASSERT(initialSize >= minHeapSize && initialSize <= maxHeapSize);

    // Initially we divide the space equally between the major and
    // minor heaps.  That means that there will definitely be space
    // for the first minor GC to copy its data.  This division can be
    // changed later on.
    gMem.SetSpaceForHeap(initialSize);
    gMem.SetSpaceBeforeMinorGC(initialSize/2);
    lastFreeSpace = initialSize;
    highWaterMark = initialSize;

    if (percent == 0)
        userGCRatio = 1.0 / 9.0; // Default to 10% GC to 90% application
    else
        userGCRatio = (float)percent / (float)(100 - percent);

    predictedRatio = lastMajorGCRatio = userGCRatio;

    if (debugOptions & DEBUG_HEAPSIZE)
    {
        Log("Heap: Initial settings: Initial heap ");
        LogSize(initialSize);
        Log(" minimum ");
        LogSize(minHeapSize);
        Log(" maximum ");
        LogSize(maxHeapSize);
        Log(" target ratio %f\n", userGCRatio);
    }
}
Exemple #10
0
size_t SymbianLog::getLogSize() 
{
    return (size_t)LogSize();
}