<commit_before>/*
 * NetworkSolver.hpp
 *
 *  Created on: 03.06.2016
 *      Author: hartung
 */

#ifndef NETWORK_INCLUDE_NETWORKSOLVER_HPP_
#define NETWORK_INCLUDE_NETWORKSOLVER_HPP_

#include "../../include/solver/AbstractSolver.hpp"
#include "SimulationServer.hpp"

namespace Solver
{
    template<class DataManagerClass>
    class AbstractSolver<DataManagerClass, FMI::EmptyFmu> : public ISolver
    {
     public:
        AbstractSolver() = delete;

        ~AbstractSolver()
        {

        }

        AbstractSolver(const Initialization::SolverPlan & in, const FMI::EmptyFmu & fmu, std::shared_ptr<DataManagerClass> & dataManager)
                : _id(in.id),
                  _dataManager(dataManager),
                  _currentTime(in.startTime),
                  _endTime(in.endTime),
                  _simServer(in.networkPlan.server),
                  _spec(NetOff::ClientMessageSpecifyer::UNPAUSE),
                  _solvPlan(in),
                  _fmu(fmu),
                  _lastRequestHandled(true),
                  _outputsSent(false)
        {
            if (!_simServer->isActive())
                throw std::runtime_error("SimulationServer isn't active. Abort.");
        }

        size_type solve(const size_type & numSteps) override
        {
            unsigned count = 0, testVar = 1;
            while (count++ < numSteps && testVar == 1)
            {
                if (_lastRequestHandled)
                    _spec = _simServer->getClientRequest();
                switch (_spec)
                {
                    case NetOff::ClientMessageSpecifyer::INPUTS:
                        testVar = confirmInputs();
                        break;
                    case NetOff::ClientMessageSpecifyer::PAUSE:
                        testVar = pauseSim();
                        break;
                    case NetOff::ClientMessageSpecifyer::UNPAUSE:
                        testVar = unpauseSim();
                        break;
                    case NetOff::ClientMessageSpecifyer::RESET:
                        testVar = abortSim();
                        break;
                    case NetOff::ClientMessageSpecifyer::CLIENT_ABORT:
                        testVar = abortSim();
                        break;
                }
            }
            return (testVar == 1) ? count : testVar;
        }

        void initialize() override
        {
            // set up values
            size_type numReals = 0, numInts = 0, numBools = 0, numStrings = 0;

            for (const auto & fmuCon : _solvPlan.networkPlan.fmuNet)
            {
                numReals += fmuCon.inputMap.size<real_type>() + fmuCon.outputMap.size<real_type>();
                numInts += fmuCon.inputMap.size<int_type>() + fmuCon.outputMap.size<int_type>();
                numBools += fmuCon.inputMap.size<bool_type>() + fmuCon.outputMap.size<bool_type>();
                numStrings += fmuCon.inputMap.size<string_type>() + fmuCon.outputMap.size<string_type>();
            }
            _fmu.setNumValues(numReals, numInts, numBools, numStrings);

            _dataManager->addFmu(&_fmu);

            for(auto& con : _fmu.getConnections())
            {
                if(con->isOutgoing(_fmu.getFmuName()))
                    _outConns.push_back(con);
            }
            _simServer->confirmStart();
        }

        ErrorInfo getErrorInfo() const
        {
            return ErrorInfo();
        }

        size_type getSolverOrder() const
        {
            return 1u;
        }

        void setEndTime(const real_type & simTime) override
        {
            _endTime = simTime;
        }

        void setTolerance(const real_type & tolerance) override
        {

        }

        Synchronization::IDataManager* getDataManager() override
        {
            return _dataManager.get();
        }

        real_type getCurrentTime() const
        {
            return _currentTime;
        }

        real_type getEndTime() const
        {
            return _endTime;
        }

        real_type getCurrentStepSize() const
        {
            return 0.01;
        }

        void setStepSize(const real_type & in) override
        {

        }

        real_type getStepSize() const
        {
            return 0.01;
        }

        bool_type isFinished() const
        {
            return _simServer->isActive();
        }

        size_type getId() const
        {
            return _id;
        }

        const FMI::AbstractFmu* getFmu() const
        {
            return &_fmu;
        }

        FMI::AbstractFmu* getFmu() override
        {
            return &_fmu;
        }

        real_type getTolerance() const
        {
            return 1.0e-5;
        }

        real_type getMaxError() const
        {
            return 0.0;
        }

        void setMaxError(const real_type & maxError) override
        {

        }

        size_type getEventCounter() const
        {
            return 0;
        }

     private:
        size_type _id;
        std::shared_ptr<DataManagerClass> _dataManager;
        real_type _currentTime;
        real_type _endTime;

        std::shared_ptr<NetOff::SimulationServer> _simServer;
        std::vector<Synchronization::ConnectionSPtr> _outConns;  // refs simNum to connection
        NetOff::ClientMessageSpecifyer _spec;

        const Initialization::SolverPlan _solvPlan;
        FMI::EmptyFmu _fmu;

        bool _lastRequestHandled;
        bool _outputsSent;

        size_type confirmInputs()
        {
            int fmuId = _simServer->getLastSimId();
            real_type remoteTime = _simServer->getLastReceivedTime(fmuId);
            if (!_outputsSent)
            {
                if (_dataManager->sendSingleOutput(remoteTime, 1, &_fmu, _outConns[fmuId]->getLocalId()))
                    _outputsSent = true;
                else
                {
                    _lastRequestHandled = false;
                    _outputsSent = false;
                    return 1;
                }
            }
            if (std::abs(_currentTime - remoteTime) > 1.0e-10)
            {
                // get values
                if (_dataManager->getDependencyInfo(&_fmu).depStatus != Solver::DependencyStatus::BLOCKED)
                {
                    _dataManager->setFmuInputValuesAtT(remoteTime, &_fmu);
                    _currentTime = remoteTime;
                }
                else
                {
                    _lastRequestHandled = false;
                    return 1;
                }
            }
            NetOff::ValueContainer & vals = _simServer->getOutputValueContainer(fmuId);
            const FMI::ValueCollection & fmuVals = _fmu.getEmptyFmuValues();
            FMI::ValueCollection tmp = _solvPlan.networkPlan.fmuNet[fmuId].outputMap.pack(fmuVals);  // TODO alloc
            vals.setRealValues(tmp.getValues<real_type>().data());
            vals.setIntValues(tmp.getValues<int_type>().data());
            vals.setBoolValues(tmp.getValues<bool_type>().data());

            // _lastRequestHandled = _simServer->sendOutputValues(fmuId, _currentTime, vals);
            _lastRequestHandled = _simServer->sendOutputValues(fmuId, _currentTime);
            return 1;
        }

        size_type pauseSim()
        {
            return 1;
        }

        size_type unpauseSim()
        {
            return 1;
        }

        size_type abortSim()
        {
            _simServer->deinitialize();
            return std::numeric_limits<size_type>::max();
        }

    };
}
#endif
<commit_msg>Send _vals<commit_after>/*
 * NetworkSolver.hpp
 *
 *  Created on: 03.06.2016
 *      Author: hartung
 */

#ifndef NETWORK_INCLUDE_NETWORKSOLVER_HPP_
#define NETWORK_INCLUDE_NETWORKSOLVER_HPP_

#include "../../include/solver/AbstractSolver.hpp"
#include "SimulationServer.hpp"

namespace Solver
{
    template<class DataManagerClass>
    class AbstractSolver<DataManagerClass, FMI::EmptyFmu> : public ISolver
    {
     public:
        AbstractSolver() = delete;

        ~AbstractSolver()
        {

        }

        AbstractSolver(const Initialization::SolverPlan & in, const FMI::EmptyFmu & fmu, std::shared_ptr<DataManagerClass> & dataManager)
                : _id(in.id),
                  _dataManager(dataManager),
                  _currentTime(in.startTime),
                  _endTime(in.endTime),
                  _simServer(in.networkPlan.server),
                  _spec(NetOff::ClientMessageSpecifyer::UNPAUSE),
                  _solvPlan(in),
                  _fmu(fmu),
                  _lastRequestHandled(true),
                  _outputsSent(false)
        {
            if (!_simServer->isActive())
                throw std::runtime_error("SimulationServer isn't active. Abort.");
        }

        size_type solve(const size_type & numSteps) override
        {
            unsigned count = 0, testVar = 1;
            while (count++ < numSteps && testVar == 1)
            {
                if (_lastRequestHandled)
                    _spec = _simServer->getClientRequest();
                switch (_spec)
                {
                    case NetOff::ClientMessageSpecifyer::INPUTS:
                        testVar = confirmInputs();
                        break;
                    case NetOff::ClientMessageSpecifyer::PAUSE:
                        testVar = pauseSim();
                        break;
                    case NetOff::ClientMessageSpecifyer::UNPAUSE:
                        testVar = unpauseSim();
                        break;
                    case NetOff::ClientMessageSpecifyer::RESET:
                        testVar = abortSim();
                        break;
                    case NetOff::ClientMessageSpecifyer::CLIENT_ABORT:
                        testVar = abortSim();
                        break;
                }
            }
            return (testVar == 1) ? count : testVar;
        }

        void initialize() override
        {
            // set up values
            size_type numReals = 0, numInts = 0, numBools = 0, numStrings = 0;

            for (const auto & fmuCon : _solvPlan.networkPlan.fmuNet)
            {
                numReals += fmuCon.inputMap.size<real_type>() + fmuCon.outputMap.size<real_type>();
                numInts += fmuCon.inputMap.size<int_type>() + fmuCon.outputMap.size<int_type>();
                numBools += fmuCon.inputMap.size<bool_type>() + fmuCon.outputMap.size<bool_type>();
                numStrings += fmuCon.inputMap.size<string_type>() + fmuCon.outputMap.size<string_type>();
            }
            _fmu.setNumValues(numReals, numInts, numBools, numStrings);

            _dataManager->addFmu(&_fmu);

            for(auto& con : _fmu.getConnections())
            {
                if(con->isOutgoing(_fmu.getFmuName()))
                    _outConns.push_back(con);
            }
            _simServer->confirmStart();
        }

        ErrorInfo getErrorInfo() const
        {
            return ErrorInfo();
        }

        size_type getSolverOrder() const
        {
            return 1u;
        }

        void setEndTime(const real_type & simTime) override
        {
            _endTime = simTime;
        }

        void setTolerance(const real_type & tolerance) override
        {

        }

        Synchronization::IDataManager* getDataManager() override
        {
            return _dataManager.get();
        }

        real_type getCurrentTime() const
        {
            return _currentTime;
        }

        real_type getEndTime() const
        {
            return _endTime;
        }

        real_type getCurrentStepSize() const
        {
            return 0.01;
        }

        void setStepSize(const real_type & in) override
        {

        }

        real_type getStepSize() const
        {
            return 0.01;
        }

        bool_type isFinished() const
        {
            return _simServer->isActive();
        }

        size_type getId() const
        {
            return _id;
        }

        const FMI::AbstractFmu* getFmu() const
        {
            return &_fmu;
        }

        FMI::AbstractFmu* getFmu() override
        {
            return &_fmu;
        }

        real_type getTolerance() const
        {
            return 1.0e-5;
        }

        real_type getMaxError() const
        {
            return 0.0;
        }

        void setMaxError(const real_type & maxError) override
        {

        }

        size_type getEventCounter() const
        {
            return 0;
        }

     private:
        size_type _id;
        std::shared_ptr<DataManagerClass> _dataManager;
        real_type _currentTime;
        real_type _endTime;

        std::shared_ptr<NetOff::SimulationServer> _simServer;
        std::vector<Synchronization::ConnectionSPtr> _outConns;  // refs simNum to connection
        NetOff::ClientMessageSpecifyer _spec;

        const Initialization::SolverPlan _solvPlan;
        FMI::EmptyFmu _fmu;

        bool _lastRequestHandled;
        bool _outputsSent;

        size_type confirmInputs()
        {
            int fmuId = _simServer->getLastSimId();
            real_type remoteTime = _simServer->getLastReceivedTime(fmuId);
            if (!_outputsSent)
            {
                if (_dataManager->sendSingleOutput(remoteTime, 1, &_fmu, _outConns[fmuId]->getLocalId()))
                    _outputsSent = true;
                else
                {
                    _lastRequestHandled = false;
                    _outputsSent = false;
                    return 1;
                }
            }
            if (std::abs(_currentTime - remoteTime) > 1.0e-10)
            {
                // get values
                if (_dataManager->getDependencyInfo(&_fmu).depStatus != Solver::DependencyStatus::BLOCKED)
                {
                    _dataManager->setFmuInputValuesAtT(remoteTime, &_fmu);
                    _currentTime = remoteTime;
                }
                else
                {
                    _lastRequestHandled = false;
                    return 1;
                }
            }
            NetOff::ValueContainer & vals = _simServer->getOutputValueContainer(fmuId);
            const FMI::ValueCollection & fmuVals = _fmu.getEmptyFmuValues();
            FMI::ValueCollection tmp = _solvPlan.networkPlan.fmuNet[fmuId].outputMap.pack(fmuVals);  // TODO alloc
            vals.setRealValues(tmp.getValues<real_type>().data());
            vals.setIntValues(tmp.getValues<int_type>().data());
            vals.setBoolValues(tmp.getValues<bool_type>().data());

            _lastRequestHandled = _simServer->sendOutputValues(fmuId, _currentTime, vals);
            //_lastRequestHandled = _simServer->sendOutputValues(fmuId, _currentTime);
            return 1;
        }

        size_type pauseSim()
        {
            return 1;
        }

        size_type unpauseSim()
        {
            return 1;
        }

        size_type abortSim()
        {
            _simServer->deinitialize();
            return std::numeric_limits<size_type>::max();
        }

    };
}
#endif
<|endoftext|>


<commit_before>// Ouzel by Elviss Strazdins

#ifndef OUZEL_CORE_WORKERPOOL_HPP
#define OUZEL_CORE_WORKERPOOL_HPP

#include <condition_variable>
#include <functional>
#include <mutex>
#include <queue>
#include <vector>
#include "../thread/Thread.hpp"
#include "../utils/Log.hpp"

namespace ouzel::core
{
    class WorkerPool final
    {
    public:
        WorkerPool()
        {
            const auto count = std::thread::hardware_concurrency();

            for (unsigned int i = 0; i < count; ++i)
                workers.emplace_back(&WorkerPool::work, this);
        }

        ~WorkerPool()
        {
            running = false;
            taskQueueCondition.notify_all();
        }

        void addTask(std::function<void()> task)
        {
            std::unique_lock lock{taskQueueMutex};
            taskQueue.push(std::move(task));
            lock.unlock();

            taskQueueCondition.notify_one();
        }

    private:
        void work()
        {
            log(Log::Level::info) << "Worker started";

            for (;;)
            {
                std::unique_lock lock{taskQueueMutex};
                taskQueueCondition.wait(lock, [this]() noexcept { return !running || !taskQueue.empty(); });
                if (!running) break;
                const auto task = std::move(taskQueue.front());
                taskQueue.pop();
                lock.unlock();

                task();
            }

            log(Log::Level::info) << "Worker finished";
        }

        std::vector<thread::Thread> workers;
        bool running = true;
        std::queue<std::function<void()>> taskQueue;
        std::mutex taskQueueMutex;
        std::condition_variable taskQueueCondition;
    };
}

#endif // OUZEL_CORE_WORKERPOOL_HPP
<commit_msg>Create one less worker than cpu count because one cpu will be reserved for audio renderer<commit_after>// Ouzel by Elviss Strazdins

#ifndef OUZEL_CORE_WORKERPOOL_HPP
#define OUZEL_CORE_WORKERPOOL_HPP

#include <condition_variable>
#include <functional>
#include <mutex>
#include <queue>
#include <vector>
#include "../thread/Thread.hpp"
#include "../utils/Log.hpp"

namespace ouzel::core
{
    class WorkerPool final
    {
    public:
        WorkerPool()
        {
            const std::size_t cpuCount = std::thread::hardware_concurrency();
            const std::size_t count = (cpuCount > 1) ? cpuCount - 1 : 1;

            for (unsigned int i = 0; i < count; ++i)
                workers.emplace_back(&WorkerPool::work, this);
        }

        ~WorkerPool()
        {
            running = false;
            taskQueueCondition.notify_all();
        }

        void addTask(std::function<void()> task)
        {
            std::unique_lock lock{taskQueueMutex};
            taskQueue.push(std::move(task));
            lock.unlock();

            taskQueueCondition.notify_one();
        }

    private:
        void work()
        {
            log(Log::Level::info) << "Worker started";

            for (;;)
            {
                std::unique_lock lock{taskQueueMutex};
                taskQueueCondition.wait(lock, [this]() noexcept { return !running || !taskQueue.empty(); });
                if (!running) break;
                const auto task = std::move(taskQueue.front());
                taskQueue.pop();
                lock.unlock();

                task();
            }

            log(Log::Level::info) << "Worker finished";
        }

        std::vector<thread::Thread> workers;
        bool running = true;
        std::queue<std::function<void()>> taskQueue;
        std::mutex taskQueueMutex;
        std::condition_variable taskQueueCondition;
    };
}

#endif // OUZEL_CORE_WORKERPOOL_HPP
<|endoftext|>


<commit_before>#include <sl.h>
#include <string.h>
#include <push.h>
#include <ring0.h>

#include "GPU\d3dkmt.h"
#include "CPU\intel.h"
#include "disk.h"
#include "hardware.h"
#include "GPU\gpu.h"

UINT64                      g_hNVPMContext;
BOOLEAN                     PushGpuLoadD3DKMT = FALSE;
DWORD                       dwMappedMemAddr;
PUSH_HARDWARE_INFORMATION   hardware;
SYSTEM_BASIC_INFORMATION    HwInfoSystemBasicInformation;
GPU_ADAPTER*                Hwinfo_GpuAdapter;

#define REGISTER_VENDORID   0x00
#define REGISTER_CLASSCODE  0x08
#define REGISTER_BAR0       0x10
#define REGISTER_BAR2       0x18

UINT16 GetEngineClock()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetEngineClock();
}

UINT16 GetMemoryClock()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetMemoryClock();
}

UINT16 GetVoltage()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetVoltage();
}

UINT8 GetGpuTemp()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetTemperature();
}

UINT8 GetGpuLoadHardware()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetLoad();
}

UINT16 GetFanSpeed()
{
    return Hwinfo_GpuAdapter->GetFanSpeed();
}

UINT8
GetGpuLoad()
{
    if (PushGpuLoadD3DKMT)
        return D3DKMT_GetGpuUsage();
    else
        return GetGpuLoadHardware();
}

UINT8
GetCpuTemp()
{
    return GetIntelTemp();
}

UINT64
D3DKMTGetMemoryUsage();

UINT32 GetVramUsed()
{
    UINT64 total, free, used;

    if (!Hwinfo_GpuAdapter)
        return 0;

    total = Hwinfo_GpuAdapter->GetTotalMemory();
    free = Hwinfo_GpuAdapter->GetFreeMemory();
    used = total - free;

    return used / 1048576;
}

UINT8
GetVramUsage()
{
    return 100 * ( (float) hardware.DisplayDevice.FrameBuffer.Used / (float) hardware.DisplayDevice.FrameBuffer.Total );
}

UINT32 GetFrameBufferSize()
{
    return Hwinfo_GpuAdapter->GetTotalMemory();
}

UINT32 GetRamUsed()
{
    SYSTEM_BASIC_PERFORMANCE_INFORMATION performanceInfo;
    UINT64 committedPages; //force allmul() on x86

    NtQuerySystemInformation(SystemBasicPerformanceInformation, &performanceInfo, sizeof(SYSTEM_BASIC_PERFORMANCE_INFORMATION), NULL);

    committedPages = performanceInfo.CommittedPages;

    return (committedPages * HwInfoSystemBasicInformation.PageSize) / 1048576; //byte => megabytes
}

UINT8
GetRamUsage()
{
    return 100 * ( (float) hardware.Memory.Used / (float) hardware.Memory.Total);
}

typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
    LARGE_INTEGER IdleTime;
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER DpcTime;
    LARGE_INTEGER InterruptTime;
    ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

typedef struct _PH_UINT64_DELTA
{
    UINT64 Value;
    UINT64 Delta;
} PH_UINT64_DELTA, *PPH_UINT64_DELTA;

#define PhUpdateDelta(DltMgr, NewValue) \
    ((DltMgr)->Delta = (NewValue) - (DltMgr)->Value, \
    (DltMgr)->Value = (NewValue), (DltMgr)->Delta)

FLOAT PhCpuKernelUsage;
FLOAT PhCpuUserUsage;
FLOAT *PhCpusKernelUsage;
FLOAT* PhCpusUserUsage;

PPH_UINT64_DELTA PhCpusKernelDelta;
PPH_UINT64_DELTA PhCpusUserDelta;
PPH_UINT64_DELTA PhCpusIdleDelta;

PH_UINT64_DELTA PhCpuKernelDelta;
PH_UINT64_DELTA PhCpuUserDelta;
PH_UINT64_DELTA PhCpuIdleDelta;

SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *PhCpuInformation;

FLOAT
GetCpuUsage( UINT8 Cpu );

UINT8
GetCpuLoad()
{
    return (PhCpuUserUsage + PhCpuKernelUsage) * 100;
}

FLOAT
GetCpuUsage( UINT8 Cpu )
{
    return (PhCpusUserUsage[Cpu] + PhCpusKernelUsage[Cpu]) * 100;
}

#define SUCCEEDED(hr) (((long)(hr)) >= 0)

UINT8
GetMaxCoreLoad()
{
    FLOAT usage = 0.0f;
    FLOAT maxUsage = 0.0f;
    UINT8 i = 0;

    for (i = 0; i < hardware.Processor.NumberOfCores; i++)
    {
        usage = GetCpuUsage(i);

        if (usage > maxUsage)
        {
            maxUsage = usage;
        }
    }

    return maxUsage;
}

UINT32
GetDiskReadWriteRate()
{
    return DiskGetBytesDelta();
}

UINT16 GetDiskResponseTime( UINT32 ProcessId )
{
    return DiskGetResponseTime(ProcessId);
}

VOID Hardware_ForceMaxClocks()
{
    Hwinfo_GpuAdapter->ForceMaximumClocks();
}

VOID PhProcessProviderInitialization()
{
    FLOAT *usageBuffer;
    PPH_UINT64_DELTA deltaBuffer;

    PhCpuInformation = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) RtlAllocateHeap(
        PushHeapHandle,
        0,
        sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors
        );

    usageBuffer = (FLOAT*) RtlAllocateHeap(
        PushHeapHandle,
        0,
        sizeof(FLOAT) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors * 2
        );

    deltaBuffer = (PPH_UINT64_DELTA) RtlAllocateHeap(
        PushHeapHandle,
        0,
        sizeof(PH_UINT64_DELTA) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors * 3
        );

    PhCpusKernelUsage = usageBuffer;
    PhCpusUserUsage = PhCpusKernelUsage + (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors;

    PhCpusKernelDelta = deltaBuffer;
    PhCpusUserDelta = PhCpusKernelDelta + (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors;
    PhCpusIdleDelta = PhCpusUserDelta + (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors;

    memset(deltaBuffer, 0, sizeof(PH_UINT64_DELTA) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors);
}

VOID
PhpUpdateCpuInformation()
{
    ULONG i;
    UINT64 totalTime;

    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION PhCpuTotals;
    static BOOLEAN init = FALSE;

    if (!init)
    {
        PhProcessProviderInitialization();

        init = TRUE;
    }

    NtQuerySystemInformation(
        SystemProcessorPerformanceInformation,
        PhCpuInformation,
        sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors,
        NULL
        );

    // Zero the CPU totals.
    memset(&PhCpuTotals, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));

    for (i = 0; i < (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors; i++)
    {
        SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *cpuInfo = &PhCpuInformation[i];

        // KernelTime includes idle time.
        cpuInfo->KernelTime.QuadPart -= cpuInfo->IdleTime.QuadPart;
        cpuInfo->KernelTime.QuadPart += cpuInfo->DpcTime.QuadPart + cpuInfo->InterruptTime.QuadPart;

        PhCpuTotals.DpcTime.QuadPart += cpuInfo->DpcTime.QuadPart;
        PhCpuTotals.IdleTime.QuadPart += cpuInfo->IdleTime.QuadPart;
        PhCpuTotals.InterruptCount += cpuInfo->InterruptCount;
        PhCpuTotals.InterruptTime.QuadPart += cpuInfo->InterruptTime.QuadPart;
        PhCpuTotals.KernelTime.QuadPart += cpuInfo->KernelTime.QuadPart;
        PhCpuTotals.UserTime.QuadPart += cpuInfo->UserTime.QuadPart;

        PhUpdateDelta(&PhCpusKernelDelta[i], cpuInfo->KernelTime.QuadPart);
        PhUpdateDelta(&PhCpusUserDelta[i], cpuInfo->UserTime.QuadPart);
        PhUpdateDelta(&PhCpusIdleDelta[i], cpuInfo->IdleTime.QuadPart);

        totalTime = PhCpusKernelDelta[i].Delta + PhCpusUserDelta[i].Delta + PhCpusIdleDelta[i].Delta;

        if (totalTime != 0)
        {
            PhCpusKernelUsage[i] = (FLOAT)PhCpusKernelDelta[i].Delta / totalTime;
            PhCpusUserUsage[i] = (FLOAT)PhCpusUserDelta[i].Delta / totalTime;
        }
        else
        {
            PhCpusKernelUsage[i] = 0;
            PhCpusUserUsage[i] = 0;
        }
    }

    PhUpdateDelta(&PhCpuKernelDelta, PhCpuTotals.KernelTime.QuadPart);
    PhUpdateDelta(&PhCpuUserDelta, PhCpuTotals.UserTime.QuadPart);
    PhUpdateDelta(&PhCpuIdleDelta, PhCpuTotals.IdleTime.QuadPart);

    totalTime = PhCpuKernelDelta.Delta + PhCpuUserDelta.Delta + PhCpuIdleDelta.Delta;

    if (totalTime != 0)
    {
        PhCpuKernelUsage = (FLOAT)PhCpuKernelDelta.Delta / totalTime;
        PhCpuUserUsage = (FLOAT)PhCpuUserDelta.Delta / totalTime;
    }
    else
    {
        PhCpuKernelUsage = 0;
        PhCpuUserUsage = 0;
    }
}

DWORD FindPciDeviceByClass( BYTE baseClass, BYTE subClass, BYTE programIf, BYTE index )
{
    if(R0DriverHandle == INVALID_HANDLE_VALUE)
    {
        return 0xFFFFFFFF;
    }

    DWORD bus = 0, dev = 0, func = 0;
    DWORD count = 0;
    DWORD pciAddress = 0xFFFFFFFF;
    DWORD conf[3] = {0};
    DWORD error = 0;
    BOOLEAN multiFuncFlag = FALSE;
    BYTE type = 0;
    count = 0;

    for(bus = 0; bus <= 255; bus++)
    {
        for(dev = 0; dev < 31; dev++)
        {
            multiFuncFlag = FALSE;
            for(func = 0; func < 7; func++)
            {
                if(multiFuncFlag == FALSE && func > 0)
                {
                    break;
                }
                pciAddress = PciBusDevFunc(bus, dev, func);
                if (R0ReadPciConfig(pciAddress, 0, (BYTE*)conf, sizeof(conf)))
                {
                    if(func == 0) // Is Multi Function Device
                    {
                        if (R0ReadPciConfig(pciAddress, 0x0E, (BYTE*)&type, sizeof(type)))
                        {
                            if(type & 0x80)
                            {
                                multiFuncFlag = TRUE;
                            }
                        }
                    }
                    if((conf[2] & 0xFFFFFF00) ==
                            (((DWORD)baseClass << 24) |
                            ((DWORD)subClass << 16) |
                            ((DWORD)programIf << 8))
                        )
                    {
                        if (count == index)
                        {
                            return pciAddress;
                        }

                        count++;
                        continue;
                    }
                }
            }
        }
    }
    return 0xFFFFFFFF;
}

VOID* HwMmio;
DWORD
ReadGpuRegister( DWORD Address )
{
    DWORD* val=0;
    DWORD address;
    DWORD ret;

    address = ((DWORD)HwMmio) + Address;

    val = (DWORD*)address;
    ret = *val;
    return ret;
}

DWORD
GetBarAddress( DWORD Bar )
{
    DWORD barAddress;

    R0ReadPciConfig(
        hardware.DisplayDevice.pciAddress,
        Bar,
        (BYTE *)&barAddress,
        sizeof(barAddress)
        );

    // 16-Byte alligned address;
    return (barAddress & 0x0fffffff0);
}

UINT32
GetBarSize(
    DWORD BarAddress
    )
{
   unsigned pos = 0;

   while (!(BarAddress & 1))
   {
      BarAddress >>= 1;
      ++pos;
   }

    return 1 << (pos - 1);
}

VOID InitGpuHardware()
{
    DWORD bar;

    hardware.DisplayDevice.pciAddress = FindPciDeviceByClass(0x03, 0x00, 0x00, 0);

    R0ReadPciConfig(
        hardware.DisplayDevice.pciAddress,
        REGISTER_VENDORID,
        (BYTE *) &hardware.DisplayDevice.VendorId,
        sizeof(hardware.DisplayDevice.VendorId)
        );

    if (hardware.DisplayDevice.VendorId == NVIDIA)
        bar = REGISTER_BAR0;
    else if (hardware.DisplayDevice.VendorId == AMD)
        bar = REGISTER_BAR2;
    else
        return;

    hardware.DisplayDevice.BarAddress = GetBarAddress(bar);

    HwMmio = R0MapPhysicalMemory(
                hardware.DisplayDevice.BarAddress,
                GetBarSize(hardware.DisplayDevice.BarAddress)
                );
}

VOID GetHardwareInfo()
{
    int i = 0;
    CORE_LIST *coreListEntry;

    InitGpuHardware();
    Hwinfo_GpuAdapter = CreateGpuAdapter(hardware.DisplayDevice.VendorId);

    if (Hwinfo_GpuAdapter)
    {
        hardware.DisplayDevice.FrameBuffer.Total = Hwinfo_GpuAdapter->GetTotalMemory();
        hardware.DisplayDevice.EngineClockMax = Hwinfo_GpuAdapter->GetMaximumEngineClock();
        hardware.DisplayDevice.MemoryClockMax = Hwinfo_GpuAdapter->GetMaximumMemoryClock();
    }

    if (SlIniReadBoolean(L"Settings", L"GpuUsageD3DKMT", FALSE, L".\\" PUSH_SETTINGS_FILE))
        PushGpuLoadD3DKMT = TRUE;

    // Get the number of processors in the system
    NtQuerySystemInformation(SystemBasicInformation, &HwInfoSystemBasicInformation, sizeof(SYSTEM_BASIC_INFORMATION), 0);

    hardware.Processor.NumberOfCores = HwInfoSystemBasicInformation.NumberOfProcessors;
    hardware.Memory.Total = (HwInfoSystemBasicInformation.NumberOfPhysicalPages * HwInfoSystemBasicInformation.PageSize) / 1048576; //byte => megabytes

    coreListEntry = &hardware.Processor.coreList;

    for (i = 0; i < hardware.Processor.NumberOfCores; i++)
    {
        coreListEntry->nextEntry = (CORE_LIST*)RtlAllocateHeap(
                                    PushHeapHandle,
                                    0,
                                    sizeof(CORE_LIST)
                                    );

        coreListEntry->number                   = i;
        coreListEntry->idleTime.QuadPart        = 0;
        coreListEntry->perfCounter.QuadPart     = 0;
        coreListEntry->usage                    = 0.0f;

        coreListEntry = coreListEntry->nextEntry;
    }

    // Start disk monitoring;
    DiskStartMonitoring();
}

#include "GPU\adl.h"

VOID RefreshHardwareInfo()
{
    PhpUpdateCpuInformation();

    hardware.Processor.Load                 = GetCpuLoad();
    hardware.Processor.MaxCoreUsage         = GetMaxCoreLoad();
    hardware.Processor.Temperature          = GetCpuTemp();
    hardware.DisplayDevice.Load             = GetGpuLoad();
    hardware.DisplayDevice.EngineClock      = GetEngineClock();
    hardware.DisplayDevice.MemoryClock      = GetMemoryClock();
    hardware.DisplayDevice.Voltage          = GetVoltage();
    hardware.DisplayDevice.Temperature      = GetGpuTemp();
    hardware.DisplayDevice.FrameBuffer.Used = GetVramUsed();
    hardware.DisplayDevice.FrameBuffer.Load = GetVramUsage();
    hardware.DisplayDevice.FanSpeed         = GetFanSpeed();
    hardware.Memory.Used                    = GetRamUsed();
    hardware.Memory.Load                    = GetRamUsage();
    hardware.Disk.ReadWriteRate             = GetDiskReadWriteRate();
    //hardware.Disk.ResponseTime              = GetDiskResponseTime();

    // We actually get some information from other sources
    hardware.Processor.MaxThreadUsage = PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage;
}
<commit_msg>fixes memory usage calculation. issue #36<commit_after>#include <sl.h>
#include <string.h>
#include <push.h>
#include <ring0.h>

#include "GPU\d3dkmt.h"
#include "CPU\intel.h"
#include "disk.h"
#include "hardware.h"
#include "GPU\gpu.h"

UINT64                      g_hNVPMContext;
BOOLEAN                     PushGpuLoadD3DKMT = FALSE;
DWORD                       dwMappedMemAddr;
PUSH_HARDWARE_INFORMATION   hardware;
SYSTEM_BASIC_INFORMATION    HwInfoSystemBasicInformation;
GPU_ADAPTER*                Hwinfo_GpuAdapter;

#define REGISTER_VENDORID   0x00
#define REGISTER_CLASSCODE  0x08
#define REGISTER_BAR0       0x10
#define REGISTER_BAR2       0x18

UINT16 GetEngineClock()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetEngineClock();
}

UINT16 GetMemoryClock()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetMemoryClock();
}

UINT16 GetVoltage()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetVoltage();
}

UINT8 GetGpuTemp()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetTemperature();
}

UINT8 GetGpuLoadHardware()
{
    if (!Hwinfo_GpuAdapter)
        return 0;

    return Hwinfo_GpuAdapter->GetLoad();
}

UINT16 GetFanSpeed()
{
    return Hwinfo_GpuAdapter->GetFanSpeed();
}

UINT8
GetGpuLoad()
{
    if (PushGpuLoadD3DKMT)
        return D3DKMT_GetGpuUsage();
    else
        return GetGpuLoadHardware();
}

UINT8
GetCpuTemp()
{
    return GetIntelTemp();
}

UINT64
D3DKMTGetMemoryUsage();

UINT32 GetVramUsed()
{
    UINT64 total, free, used;

    if (!Hwinfo_GpuAdapter)
        return 0;

    total = Hwinfo_GpuAdapter->GetTotalMemory();
    free = Hwinfo_GpuAdapter->GetFreeMemory();
    used = total - free;

    return used / 1048576;
}

UINT8
GetVramUsage()
{
    return 100 * ( (float) hardware.DisplayDevice.FrameBuffer.Used / (float) hardware.DisplayDevice.FrameBuffer.Total );
}

UINT32 GetFrameBufferSize()
{
    return Hwinfo_GpuAdapter->GetTotalMemory();
}

//in megabytes
UINT32 GetRamUsed()
{
    SYSTEM_BASIC_PERFORMANCE_INFORMATION performanceInfo;
    UINT64 committedPages; //force allmul() on x86

    NtQuerySystemInformation(SystemBasicPerformanceInformation, &performanceInfo, sizeof(SYSTEM_BASIC_PERFORMANCE_INFORMATION), NULL);

    committedPages = performanceInfo.CommittedPages;

    return (committedPages * HwInfoSystemBasicInformation.PageSize) / 1048576; //byte => megabytes
}

//percentage (non-float)
UINT8 GetRamUsage()
{
    return 100 * ( (float) hardware.Memory.Used / (float) hardware.Memory.Total);
}

typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
    LARGE_INTEGER IdleTime;
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER DpcTime;
    LARGE_INTEGER InterruptTime;
    ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

typedef struct _PH_UINT64_DELTA
{
    UINT64 Value;
    UINT64 Delta;
} PH_UINT64_DELTA, *PPH_UINT64_DELTA;

#define PhUpdateDelta(DltMgr, NewValue) \
    ((DltMgr)->Delta = (NewValue) - (DltMgr)->Value, \
    (DltMgr)->Value = (NewValue), (DltMgr)->Delta)

FLOAT PhCpuKernelUsage;
FLOAT PhCpuUserUsage;
FLOAT *PhCpusKernelUsage;
FLOAT* PhCpusUserUsage;

PPH_UINT64_DELTA PhCpusKernelDelta;
PPH_UINT64_DELTA PhCpusUserDelta;
PPH_UINT64_DELTA PhCpusIdleDelta;

PH_UINT64_DELTA PhCpuKernelDelta;
PH_UINT64_DELTA PhCpuUserDelta;
PH_UINT64_DELTA PhCpuIdleDelta;

SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *PhCpuInformation;

FLOAT
GetCpuUsage( UINT8 Cpu );

UINT8
GetCpuLoad()
{
    return (PhCpuUserUsage + PhCpuKernelUsage) * 100;
}

FLOAT
GetCpuUsage( UINT8 Cpu )
{
    return (PhCpusUserUsage[Cpu] + PhCpusKernelUsage[Cpu]) * 100;
}

#define SUCCEEDED(hr) (((long)(hr)) >= 0)

UINT8
GetMaxCoreLoad()
{
    FLOAT usage = 0.0f;
    FLOAT maxUsage = 0.0f;
    UINT8 i = 0;

    for (i = 0; i < hardware.Processor.NumberOfCores; i++)
    {
        usage = GetCpuUsage(i);

        if (usage > maxUsage)
        {
            maxUsage = usage;
        }
    }

    return maxUsage;
}

UINT32
GetDiskReadWriteRate()
{
    return DiskGetBytesDelta();
}

UINT16 GetDiskResponseTime( UINT32 ProcessId )
{
    return DiskGetResponseTime(ProcessId);
}

VOID Hardware_ForceMaxClocks()
{
    Hwinfo_GpuAdapter->ForceMaximumClocks();
}

VOID PhProcessProviderInitialization()
{
    FLOAT *usageBuffer;
    PPH_UINT64_DELTA deltaBuffer;

    PhCpuInformation = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) RtlAllocateHeap(
        PushHeapHandle,
        0,
        sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors
        );

    usageBuffer = (FLOAT*) RtlAllocateHeap(
        PushHeapHandle,
        0,
        sizeof(FLOAT) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors * 2
        );

    deltaBuffer = (PPH_UINT64_DELTA) RtlAllocateHeap(
        PushHeapHandle,
        0,
        sizeof(PH_UINT64_DELTA) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors * 3
        );

    PhCpusKernelUsage = usageBuffer;
    PhCpusUserUsage = PhCpusKernelUsage + (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors;

    PhCpusKernelDelta = deltaBuffer;
    PhCpusUserDelta = PhCpusKernelDelta + (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors;
    PhCpusIdleDelta = PhCpusUserDelta + (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors;

    memset(deltaBuffer, 0, sizeof(PH_UINT64_DELTA) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors);
}

VOID
PhpUpdateCpuInformation()
{
    ULONG i;
    UINT64 totalTime;

    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION PhCpuTotals;
    static BOOLEAN init = FALSE;

    if (!init)
    {
        PhProcessProviderInitialization();

        init = TRUE;
    }

    NtQuerySystemInformation(
        SystemProcessorPerformanceInformation,
        PhCpuInformation,
        sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors,
        NULL
        );

    // Zero the CPU totals.
    memset(&PhCpuTotals, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));

    for (i = 0; i < (ULONG)HwInfoSystemBasicInformation.NumberOfProcessors; i++)
    {
        SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *cpuInfo = &PhCpuInformation[i];

        // KernelTime includes idle time.
        cpuInfo->KernelTime.QuadPart -= cpuInfo->IdleTime.QuadPart;
        cpuInfo->KernelTime.QuadPart += cpuInfo->DpcTime.QuadPart + cpuInfo->InterruptTime.QuadPart;

        PhCpuTotals.DpcTime.QuadPart += cpuInfo->DpcTime.QuadPart;
        PhCpuTotals.IdleTime.QuadPart += cpuInfo->IdleTime.QuadPart;
        PhCpuTotals.InterruptCount += cpuInfo->InterruptCount;
        PhCpuTotals.InterruptTime.QuadPart += cpuInfo->InterruptTime.QuadPart;
        PhCpuTotals.KernelTime.QuadPart += cpuInfo->KernelTime.QuadPart;
        PhCpuTotals.UserTime.QuadPart += cpuInfo->UserTime.QuadPart;

        PhUpdateDelta(&PhCpusKernelDelta[i], cpuInfo->KernelTime.QuadPart);
        PhUpdateDelta(&PhCpusUserDelta[i], cpuInfo->UserTime.QuadPart);
        PhUpdateDelta(&PhCpusIdleDelta[i], cpuInfo->IdleTime.QuadPart);

        totalTime = PhCpusKernelDelta[i].Delta + PhCpusUserDelta[i].Delta + PhCpusIdleDelta[i].Delta;

        if (totalTime != 0)
        {
            PhCpusKernelUsage[i] = (FLOAT)PhCpusKernelDelta[i].Delta / totalTime;
            PhCpusUserUsage[i] = (FLOAT)PhCpusUserDelta[i].Delta / totalTime;
        }
        else
        {
            PhCpusKernelUsage[i] = 0;
            PhCpusUserUsage[i] = 0;
        }
    }

    PhUpdateDelta(&PhCpuKernelDelta, PhCpuTotals.KernelTime.QuadPart);
    PhUpdateDelta(&PhCpuUserDelta, PhCpuTotals.UserTime.QuadPart);
    PhUpdateDelta(&PhCpuIdleDelta, PhCpuTotals.IdleTime.QuadPart);

    totalTime = PhCpuKernelDelta.Delta + PhCpuUserDelta.Delta + PhCpuIdleDelta.Delta;

    if (totalTime != 0)
    {
        PhCpuKernelUsage = (FLOAT)PhCpuKernelDelta.Delta / totalTime;
        PhCpuUserUsage = (FLOAT)PhCpuUserDelta.Delta / totalTime;
    }
    else
    {
        PhCpuKernelUsage = 0;
        PhCpuUserUsage = 0;
    }
}

DWORD FindPciDeviceByClass( BYTE baseClass, BYTE subClass, BYTE programIf, BYTE index )
{
    if(R0DriverHandle == INVALID_HANDLE_VALUE)
    {
        return 0xFFFFFFFF;
    }

    DWORD bus = 0, dev = 0, func = 0;
    DWORD count = 0;
    DWORD pciAddress = 0xFFFFFFFF;
    DWORD conf[3] = {0};
    DWORD error = 0;
    BOOLEAN multiFuncFlag = FALSE;
    BYTE type = 0;
    count = 0;

    for(bus = 0; bus <= 255; bus++)
    {
        for(dev = 0; dev < 31; dev++)
        {
            multiFuncFlag = FALSE;
            for(func = 0; func < 7; func++)
            {
                if(multiFuncFlag == FALSE && func > 0)
                {
                    break;
                }
                pciAddress = PciBusDevFunc(bus, dev, func);
                if (R0ReadPciConfig(pciAddress, 0, (BYTE*)conf, sizeof(conf)))
                {
                    if(func == 0) // Is Multi Function Device
                    {
                        if (R0ReadPciConfig(pciAddress, 0x0E, (BYTE*)&type, sizeof(type)))
                        {
                            if(type & 0x80)
                            {
                                multiFuncFlag = TRUE;
                            }
                        }
                    }
                    if((conf[2] & 0xFFFFFF00) ==
                            (((DWORD)baseClass << 24) |
                            ((DWORD)subClass << 16) |
                            ((DWORD)programIf << 8))
                        )
                    {
                        if (count == index)
                        {
                            return pciAddress;
                        }

                        count++;
                        continue;
                    }
                }
            }
        }
    }
    return 0xFFFFFFFF;
}

VOID* HwMmio;
DWORD
ReadGpuRegister( DWORD Address )
{
    DWORD* val=0;
    DWORD address;
    DWORD ret;

    address = ((DWORD)HwMmio) + Address;

    val = (DWORD*)address;
    ret = *val;
    return ret;
}

DWORD
GetBarAddress( DWORD Bar )
{
    DWORD barAddress;

    R0ReadPciConfig(
        hardware.DisplayDevice.pciAddress,
        Bar,
        (BYTE *)&barAddress,
        sizeof(barAddress)
        );

    // 16-Byte alligned address;
    return (barAddress & 0x0fffffff0);
}

UINT32
GetBarSize(
    DWORD BarAddress
    )
{
   unsigned pos = 0;

   while (!(BarAddress & 1))
   {
      BarAddress >>= 1;
      ++pos;
   }

    return 1 << (pos - 1);
}

VOID InitGpuHardware()
{
    DWORD bar;

    hardware.DisplayDevice.pciAddress = FindPciDeviceByClass(0x03, 0x00, 0x00, 0);

    R0ReadPciConfig(
        hardware.DisplayDevice.pciAddress,
        REGISTER_VENDORID,
        (BYTE *) &hardware.DisplayDevice.VendorId,
        sizeof(hardware.DisplayDevice.VendorId)
        );

    if (hardware.DisplayDevice.VendorId == NVIDIA)
        bar = REGISTER_BAR0;
    else if (hardware.DisplayDevice.VendorId == AMD)
        bar = REGISTER_BAR2;
    else
        return;

    hardware.DisplayDevice.BarAddress = GetBarAddress(bar);

    HwMmio = R0MapPhysicalMemory(
                hardware.DisplayDevice.BarAddress,
                GetBarSize(hardware.DisplayDevice.BarAddress)
                );
}

VOID GetHardwareInfo()
{
    int i = 0;
    CORE_LIST *coreListEntry;

    //use 64 bits to force allmul() on 32 bit builds
    UINT64 physicalPages;
    UINT64 pageSize;

    InitGpuHardware();
    Hwinfo_GpuAdapter = CreateGpuAdapter(hardware.DisplayDevice.VendorId);

    if (Hwinfo_GpuAdapter)
    {
        hardware.DisplayDevice.FrameBuffer.Total = Hwinfo_GpuAdapter->GetTotalMemory();
        hardware.DisplayDevice.EngineClockMax = Hwinfo_GpuAdapter->GetMaximumEngineClock();
        hardware.DisplayDevice.MemoryClockMax = Hwinfo_GpuAdapter->GetMaximumMemoryClock();
    }

    if (SlIniReadBoolean(L"Settings", L"GpuUsageD3DKMT", FALSE, L".\\" PUSH_SETTINGS_FILE))
        PushGpuLoadD3DKMT = TRUE;

    // Get the number of processors in the system
    NtQuerySystemInformation(SystemBasicInformation, &HwInfoSystemBasicInformation, sizeof(SYSTEM_BASIC_INFORMATION), 0);

    hardware.Processor.NumberOfCores = HwInfoSystemBasicInformation.NumberOfProcessors;

    physicalPages = HwInfoSystemBasicInformation.NumberOfPhysicalPages;
    pageSize = HwInfoSystemBasicInformation.PageSize;

    //byte => megabytes
    hardware.Memory.Total = (physicalPages * pageSize) / 1048576;

    coreListEntry = &hardware.Processor.coreList;

    for (i = 0; i < hardware.Processor.NumberOfCores; i++)
    {
        coreListEntry->nextEntry = (CORE_LIST*)RtlAllocateHeap(
                                    PushHeapHandle,
                                    0,
                                    sizeof(CORE_LIST)
                                    );

        coreListEntry->number                   = i;
        coreListEntry->idleTime.QuadPart        = 0;
        coreListEntry->perfCounter.QuadPart     = 0;
        coreListEntry->usage                    = 0.0f;

        coreListEntry = coreListEntry->nextEntry;
    }

    // Start disk monitoring;
    DiskStartMonitoring();
}

#include "GPU\adl.h"

VOID RefreshHardwareInfo()
{
    PhpUpdateCpuInformation();

    hardware.Processor.Load                 = GetCpuLoad();
    hardware.Processor.MaxCoreUsage         = GetMaxCoreLoad();
    hardware.Processor.Temperature          = GetCpuTemp();
    hardware.DisplayDevice.Load             = GetGpuLoad();
    hardware.DisplayDevice.EngineClock      = GetEngineClock();
    hardware.DisplayDevice.MemoryClock      = GetMemoryClock();
    hardware.DisplayDevice.Voltage          = GetVoltage();
    hardware.DisplayDevice.Temperature      = GetGpuTemp();
    hardware.DisplayDevice.FrameBuffer.Used = GetVramUsed();
    hardware.DisplayDevice.FrameBuffer.Load = GetVramUsage();
    hardware.DisplayDevice.FanSpeed         = GetFanSpeed();
    hardware.Memory.Used                    = GetRamUsed();
    hardware.Memory.Load                    = GetRamUsage();
    hardware.Disk.ReadWriteRate             = GetDiskReadWriteRate();
    //hardware.Disk.ResponseTime              = GetDiskResponseTime();

    // We actually get some information from other sources
    hardware.Processor.MaxThreadUsage = PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage;
}
<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * settings.h
 *
 *  Created on: Oct 2018
 *      Author: Norbert Podhorszki
 */

#include "settings.h"

#include <cmath>
#include <cstring>
#include <getopt.h>
#include <iostream>
#include <stdexcept>
#include <string>

struct option options[] = {{"help", no_argument, NULL, 'h'},
                           {"verbose", no_argument, NULL, 'v'},
                           {"appid", required_argument, NULL, 'a'},
                           {"config", required_argument, NULL, 'c'},
                           {"decomp", required_argument, NULL, 'd'},
                           {"xml", required_argument, NULL, 'x'},
                           {"strong-scaling", no_argument, NULL, 's'},
                           {"weak-scaling", no_argument, NULL, 'w'},
                           {"timer", no_argument, NULL, 't'},
                           {"fixed", no_argument, NULL, 'F'},
#ifdef ADIOS2_HAVE_HDF5_PARALLEL
                           {"hdf5", no_argument, NULL, 'H'},
#endif
                           {NULL, 0, NULL, 0}};

static const char *optstring = "-hvswtFHa:c:d:x:";

size_t Settings::ndigits(size_t n) const
{
    /* Determine how many characters are needed to print n */
    static char digitstr[32];
    return static_cast<size_t>(snprintf(digitstr, 32, "%zu", n));
}

void Settings::displayHelp()
{
    std::cout
        << "Usage: adios_iotest -a appid -c config {-s | -w} -d {d1 [d2 .. dN] "
           "| r1,[r2,..,rN]}"
           "[-x "
           "file]\n"
        << "  -a appID:  unique number for each application in the workflow\n"
        << "  -c config: data specification config file\n"
        << "  -d ...     define process decomposition:\n"
        << "      d1:        number of processes in 1st (slowest) dimension\n"
        << "      dN:        number of processes in Nth dimension\n"
        << "                 d1*d2*..*dN must equal the number of processes\n"
        << "      r1:        ratio of process decomposition in the 1st "
           "(slowest) dimension\n"
        << "      rN:        ratio of process decomposition in the Nth "
           "dimension\n"
        << "                 r1xr2x..xrN must scale up to process count"
           "count without remainder\n"
        << "  -s OR -w:  strong or weak scaling. \n"
        << "             Dimensions in config are treated accordingly\n"
        << "  -x file    ADIOS configuration XML file\n"
#ifdef ADIOS2_HAVE_HDF5_PARALLEL
        << "  --hdf5     Use native Parallel HDF5 instead of ADIOS for I/O\n"
#endif
        << "  -v         increase verbosity\n"
        << "  -h         display this help\n"
        << "  -F         turn on fixed I/O pattern explicitly\n"
        << "  -t         print and dump the timing measured by the I/O "
           "timer\n\n";
}

size_t Settings::stringToNumber(const std::string &varName,
                                const char *arg) const
{
    char *end;
    size_t retval = static_cast<size_t>(std::strtoull(arg, &end, 10));
    if (end[0] || errno == ERANGE)
    {
        throw std::invalid_argument("Invalid value given for " + varName +
                                    ": " + std::string(arg));
    }
    return retval;
}

int Settings::parseRatios(const char *arg)
{
    char *argCopy = strdup(arg);
    char *ratio;

    ratio = strtok(argCopy, ",");
    while (ratio)
    {
        processDecomp[nDecomp++] = stringToNumber("decomposition ratio", ratio);
        ratio = strtok(NULL, ",");
    }

    free(argCopy);

    isRatioDecomp = true;

    return (0);
}

int Settings::rescaleDecomp()
{
    size_t ratioProd = 1;
    size_t scaleFactor;

    for (size_t i = 0; i < nDecomp; i++)
    {
        ratioProd *= processDecomp[i];
    }

    for (scaleFactor = 1; ratioProd * pow(scaleFactor, nDecomp) <= nProc;
         scaleFactor++)
    {
        if (ratioProd * pow(scaleFactor, nDecomp) == nProc)
        {
            for (size_t i = 0; i < nDecomp; i++)
            {
                processDecomp[i] *= scaleFactor;
            }
            return (0);
        }
    }

    throw std::invalid_argument(
        "decomposition ratios must scale up to process count");

    return (0);
}

int Settings::processArgs(int argc, char *argv[])
{
    bool appIdDefined = false;
    bool scalingDefined = false;
    int c;
    int last_c = '_';

    /* Process the arguments */
    while ((c = getopt_long(argc, argv, optstring, options, NULL)) != -1)
    {
        switch (c)
        {
        case 'a':
            appId = stringToNumber("appID", optarg);
            appIdDefined = true;
            break;
        case 'c':
            configFileName = optarg;
            break;
        case 'd':
            if (strchr(optarg, ','))
            {
                parseRatios(optarg);
            }
            else
            {
                processDecomp[nDecomp] =
                    stringToNumber("decomposition in dimension 1", optarg);
                ++nDecomp;
            }
            break;
        case 'F':
            fixedPattern = true;
            break;
        case 'h':
            if (!myRank)
            {
                displayHelp();
            }
            return 1;
#ifdef ADIOS2_HAVE_HDF5_PARALLEL
        case 'H':
            iolib = IOLib::HDF5;
            break;
#endif
        case 's':
            if (scalingDefined && !isStrongScaling)
            {
                throw std::invalid_argument(
                    "Cannot have -w and -s used at the same time ");
            }
            isStrongScaling = true;
            scalingDefined = true;
            break;
        case 'v':
            ++verbose;
            break;
        case 'w':
            if (scalingDefined && isStrongScaling)
            {
                throw std::invalid_argument(
                    "Cannot have -s and -w used at the same time ");
            }
            isStrongScaling = false;
            scalingDefined = true;
            break;
        case 't':
            ioTimer = true;
            break;
        case 'x':
            adiosConfigFileName = optarg;
            break;
        case 1:
            /* This means a field is unknown, or could be multiple arg or bad
             * arg*/

            if (last_c == 'd')
            { // --decomp extra arg (or not if not a number)
                processDecomp[nDecomp] = stringToNumber(
                    "decomposition in dimension " + std::to_string(nDecomp + 1),
                    optarg);
                ++nDecomp;
            }
            else
            {
                throw std::invalid_argument("Invalid argument " +
                                            std::string(optarg));
            }
            break;

        default:
            throw std::invalid_argument("Invalid argument option " +
                                        std::string(optarg));
        } /* end switch */
        if (c != 1)
        {
            last_c = c;
        }
    } /* end while */

    /* Check if we have extra unprocessed arguments */
    if (optind < argc)
    {
        std::string s;
        while (optind < argc)
        {
            s += std::string(argv[optind]) + " ";
            ++optind;
        }
        throw std::invalid_argument("There are unknown arguments: " + s);
    }

    /* Check if we have a everything defined */
    if (!appIdDefined)
    {
        throw std::invalid_argument("Missing argument for application ID, "
                                    "which must be unique for each application "
                                    "(see -a option)");
    }
    if (configFileName.empty())
    {
        throw std::invalid_argument(
            "Missing argument for config file (see -c option)");
    }
    if (!scalingDefined)
    {
        throw std::invalid_argument("Missing argument for scaling, "
                                    "which must be set to Strong or Weak "
                                    "(see -s, -w options)");
    }

    return 0;
}

int Settings::processArguments(int argc, char *argv[], MPI_Comm worldComm)
{
    int retval = 0;
    try
    {
        retval = processArgs(argc, argv);

        int wrank;
        MPI_Comm_rank(worldComm, &wrank);
        MPI_Comm_split(worldComm, static_cast<int>(appId), wrank, &appComm);

        int rank, nproc;
        MPI_Comm_rank(appComm, &rank);
        MPI_Comm_size(appComm, &nproc);
        myRank = static_cast<size_t>(rank);
        nProc = static_cast<size_t>(nproc);

        if (isRatioDecomp)
        {
            rescaleDecomp();
        }
    }
    catch (std::exception &e) // command-line argument errors
    {
        std::cout << "ERROR : " << e.what() << std::endl;
        displayHelp();
        retval = 1;
    }
    return retval;
}

int Settings::extraArgumentChecks()
{
    if (!nDecomp && nProc > 1)
    {
        std::cout << "ERROR : Missing decomposition for parallel program (see "
                     "-d option)"
                  << std::endl;
        return 1;
    }

    size_t N = 1;
    for (size_t i = 0; i < nDecomp; ++i)
    {
        N *= processDecomp[i];
    }

    if (N != nProc)
    {
        std::cout << "ERROR : Product of decomposition values = " << N
                  << " must equal the number of processes = " << nProc
                  << std::endl;
        return 1;
    }
    return 0;
}
<commit_msg>Removed unreachable return statement<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * settings.h
 *
 *  Created on: Oct 2018
 *      Author: Norbert Podhorszki
 */

#include "settings.h"

#include <cmath>
#include <cstring>
#include <getopt.h>
#include <iostream>
#include <stdexcept>
#include <string>

struct option options[] = {{"help", no_argument, NULL, 'h'},
                           {"verbose", no_argument, NULL, 'v'},
                           {"appid", required_argument, NULL, 'a'},
                           {"config", required_argument, NULL, 'c'},
                           {"decomp", required_argument, NULL, 'd'},
                           {"xml", required_argument, NULL, 'x'},
                           {"strong-scaling", no_argument, NULL, 's'},
                           {"weak-scaling", no_argument, NULL, 'w'},
                           {"timer", no_argument, NULL, 't'},
                           {"fixed", no_argument, NULL, 'F'},
#ifdef ADIOS2_HAVE_HDF5_PARALLEL
                           {"hdf5", no_argument, NULL, 'H'},
#endif
                           {NULL, 0, NULL, 0}};

static const char *optstring = "-hvswtFHa:c:d:x:";

size_t Settings::ndigits(size_t n) const
{
    /* Determine how many characters are needed to print n */
    static char digitstr[32];
    return static_cast<size_t>(snprintf(digitstr, 32, "%zu", n));
}

void Settings::displayHelp()
{
    std::cout
        << "Usage: adios_iotest -a appid -c config {-s | -w} -d {d1 [d2 .. dN] "
           "| r1,[r2,..,rN]}"
           "[-x "
           "file]\n"
        << "  -a appID:  unique number for each application in the workflow\n"
        << "  -c config: data specification config file\n"
        << "  -d ...     define process decomposition:\n"
        << "      d1:        number of processes in 1st (slowest) dimension\n"
        << "      dN:        number of processes in Nth dimension\n"
        << "                 d1*d2*..*dN must equal the number of processes\n"
        << "      r1:        ratio of process decomposition in the 1st "
           "(slowest) dimension\n"
        << "      rN:        ratio of process decomposition in the Nth "
           "dimension\n"
        << "                 r1xr2x..xrN must scale up to process count"
           "count without remainder\n"
        << "  -s OR -w:  strong or weak scaling. \n"
        << "             Dimensions in config are treated accordingly\n"
        << "  -x file    ADIOS configuration XML file\n"
#ifdef ADIOS2_HAVE_HDF5_PARALLEL
        << "  --hdf5     Use native Parallel HDF5 instead of ADIOS for I/O\n"
#endif
        << "  -v         increase verbosity\n"
        << "  -h         display this help\n"
        << "  -F         turn on fixed I/O pattern explicitly\n"
        << "  -t         print and dump the timing measured by the I/O "
           "timer\n\n";
}

size_t Settings::stringToNumber(const std::string &varName,
                                const char *arg) const
{
    char *end;
    size_t retval = static_cast<size_t>(std::strtoull(arg, &end, 10));
    if (end[0] || errno == ERANGE)
    {
        throw std::invalid_argument("Invalid value given for " + varName +
                                    ": " + std::string(arg));
    }
    return retval;
}

int Settings::parseRatios(const char *arg)
{
    char *argCopy = strdup(arg);
    char *ratio;

    ratio = strtok(argCopy, ",");
    while (ratio)
    {
        processDecomp[nDecomp++] = stringToNumber("decomposition ratio", ratio);
        ratio = strtok(NULL, ",");
    }

    free(argCopy);

    isRatioDecomp = true;

    return (0);
}

int Settings::rescaleDecomp()
{
    size_t ratioProd = 1;
    size_t scaleFactor;

    for (size_t i = 0; i < nDecomp; i++)
    {
        ratioProd *= processDecomp[i];
    }

    for (scaleFactor = 1; ratioProd * pow(scaleFactor, nDecomp) <= nProc;
         scaleFactor++)
    {
        if (ratioProd * pow(scaleFactor, nDecomp) == nProc)
        {
            for (size_t i = 0; i < nDecomp; i++)
            {
                processDecomp[i] *= scaleFactor;
            }
            return (0);
        }
    }

    throw std::invalid_argument(
        "decomposition ratios must scale up to process count");
}

int Settings::processArgs(int argc, char *argv[])
{
    bool appIdDefined = false;
    bool scalingDefined = false;
    int c;
    int last_c = '_';

    /* Process the arguments */
    while ((c = getopt_long(argc, argv, optstring, options, NULL)) != -1)
    {
        switch (c)
        {
        case 'a':
            appId = stringToNumber("appID", optarg);
            appIdDefined = true;
            break;
        case 'c':
            configFileName = optarg;
            break;
        case 'd':
            if (strchr(optarg, ','))
            {
                parseRatios(optarg);
            }
            else
            {
                processDecomp[nDecomp] =
                    stringToNumber("decomposition in dimension 1", optarg);
                ++nDecomp;
            }
            break;
        case 'F':
            fixedPattern = true;
            break;
        case 'h':
            if (!myRank)
            {
                displayHelp();
            }
            return 1;
#ifdef ADIOS2_HAVE_HDF5_PARALLEL
        case 'H':
            iolib = IOLib::HDF5;
            break;
#endif
        case 's':
            if (scalingDefined && !isStrongScaling)
            {
                throw std::invalid_argument(
                    "Cannot have -w and -s used at the same time ");
            }
            isStrongScaling = true;
            scalingDefined = true;
            break;
        case 'v':
            ++verbose;
            break;
        case 'w':
            if (scalingDefined && isStrongScaling)
            {
                throw std::invalid_argument(
                    "Cannot have -s and -w used at the same time ");
            }
            isStrongScaling = false;
            scalingDefined = true;
            break;
        case 't':
            ioTimer = true;
            break;
        case 'x':
            adiosConfigFileName = optarg;
            break;
        case 1:
            /* This means a field is unknown, or could be multiple arg or bad
             * arg*/

            if (last_c == 'd')
            { // --decomp extra arg (or not if not a number)
                processDecomp[nDecomp] = stringToNumber(
                    "decomposition in dimension " + std::to_string(nDecomp + 1),
                    optarg);
                ++nDecomp;
            }
            else
            {
                throw std::invalid_argument("Invalid argument " +
                                            std::string(optarg));
            }
            break;

        default:
            throw std::invalid_argument("Invalid argument option " +
                                        std::string(optarg));
        } /* end switch */
        if (c != 1)
        {
            last_c = c;
        }
    } /* end while */

    /* Check if we have extra unprocessed arguments */
    if (optind < argc)
    {
        std::string s;
        while (optind < argc)
        {
            s += std::string(argv[optind]) + " ";
            ++optind;
        }
        throw std::invalid_argument("There are unknown arguments: " + s);
    }

    /* Check if we have a everything defined */
    if (!appIdDefined)
    {
        throw std::invalid_argument("Missing argument for application ID, "
                                    "which must be unique for each application "
                                    "(see -a option)");
    }
    if (configFileName.empty())
    {
        throw std::invalid_argument(
            "Missing argument for config file (see -c option)");
    }
    if (!scalingDefined)
    {
        throw std::invalid_argument("Missing argument for scaling, "
                                    "which must be set to Strong or Weak "
                                    "(see -s, -w options)");
    }

    return 0;
}

int Settings::processArguments(int argc, char *argv[], MPI_Comm worldComm)
{
    int retval = 0;
    try
    {
        retval = processArgs(argc, argv);

        int wrank;
        MPI_Comm_rank(worldComm, &wrank);
        MPI_Comm_split(worldComm, static_cast<int>(appId), wrank, &appComm);

        int rank, nproc;
        MPI_Comm_rank(appComm, &rank);
        MPI_Comm_size(appComm, &nproc);
        myRank = static_cast<size_t>(rank);
        nProc = static_cast<size_t>(nproc);

        if (isRatioDecomp)
        {
            rescaleDecomp();
        }
    }
    catch (std::exception &e) // command-line argument errors
    {
        std::cout << "ERROR : " << e.what() << std::endl;
        displayHelp();
        retval = 1;
    }
    return retval;
}

int Settings::extraArgumentChecks()
{
    if (!nDecomp && nProc > 1)
    {
        std::cout << "ERROR : Missing decomposition for parallel program (see "
                     "-d option)"
                  << std::endl;
        return 1;
    }

    size_t N = 1;
    for (size_t i = 0; i < nDecomp; ++i)
    {
        N *= processDecomp[i];
    }

    if (N != nProc)
    {
        std::cout << "ERROR : Product of decomposition values = " << N
                  << " must equal the number of processes = " << nProc
                  << std::endl;
        return 1;
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
 * opencog/cogserver/server/Agent.cc
 *
 * Copyright (C) 2008 by OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "Agent.h"

#include <opencog/cogserver/server/CogServer.h>
#include <opencog/util/Config.h>

#define DEBUG

using namespace opencog;

Agent::Agent(CogServer& cs, const unsigned int f) : _cogserver(cs), _frequency(f)
{
    STIAtomWage = config().get_int("ECAN_STARTING_ATOM_STI_WAGE");
    LTIAtomWage = config().get_int("ECAN_STARTING_ATOM_LTI_WAGE");

    targetSTI = config().get_int("TARGET_STI_FUNDS");
    stiFundsBuffer = config().get_int("STI_FUNDS_BUFFER");
    targetLTI = config().get_int("TARGET_LTI_FUNDS");
    ltiFundsBuffer = config().get_int("LTI_FUNDS_BUFFER");

    _attentionValue = AttentionValue::DEFAULT_AV();

    // an empty set of parameters and defaults (so that various
    // methods will still work even if none are set in this or a derived
    // class)
    static const std::string defaultConfig[] = {
        "", ""
    };
    setParameters(defaultConfig);

    stimulatedAtoms = new AtomStimHashMap();
    totalStimulus = 0;

    conn = _cogserver.getAtomSpace().removeAtomSignal(
            boost::bind(&Agent::atomRemoved, this, _1));

    _as = &cs.getAtomSpace();
}

Agent::~Agent()
{
    // give back funds
    _as->update_STI_funds(_attentionValue->getSTI());
    _as->update_LTI_funds(_attentionValue->getLTI());

    resetUtilizedHandleSets();
    conn.disconnect();
    delete stimulatedAtoms;

    if (log)
        delete log;
}

void Agent::setLogger(Logger* _log)
{
    if (log)
        delete log;
    log = _log;
}

Logger* Agent::getLogger()
{
    return log;
}

void Agent::setParameters(const std::string* params)
{
    PARAMETERS = params;

    for (unsigned int i = 0; params[i] != ""; i += 2) {
        if (!config().has(params[i])) {
           config().set(params[i], params[i + 1]);
        }
    }
}

std::string Agent::to_string() const
{
    std::ostringstream oss;
    oss << classinfo().id;
    oss << " {\"";
    for (unsigned int i = 0; PARAMETERS[i] != ""; i += 2) {
        if (i != 0) oss << "\", \"";
        oss << PARAMETERS[i] << "\" => \"" << config()[PARAMETERS[i]];
    }
    oss << "\"}";
    return oss.str();
}

void Agent::atomRemoved(AtomPtr atom)
{
    Handle h = atom->getHandle();
    {
        std::lock_guard<std::mutex> lock(_handleSetMutex);
        for (size_t i = 0; i < _utilizedHandleSets.size(); i++)
            _utilizedHandleSets[i].erase(h);
    }
    removeAtomStimulus(h);
}

void Agent::resetUtilizedHandleSets()
{
    std::lock_guard<std::mutex> lock(_handleSetMutex);
    for (size_t i = 0; i < _utilizedHandleSets.size(); i++)
        _utilizedHandleSets[i].clear();
    _utilizedHandleSets.clear();
}

stim_t Agent::stimulateAtom(Handle h, stim_t amount)
{
    {
        std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);

        // Add atom to the map of atoms with stimulus
        // and add stimulus to it
        (*stimulatedAtoms)[h] += amount;
    }

    // update record of total stimulus given out
    totalStimulus += amount;

    logger().fine("Atom %d received stimulus of %d, total now %d",
                  h.value(),
                  amount,
                  totalStimulus.load(std::memory_order_relaxed));

#ifdef DEBUG
    std::cout << "Atom " << h.value() << " received stimulus of " << amount <<
                 ", total now " << totalStimulus.load(std::memory_order_relaxed)
                 << "\n";
#endif

    return totalStimulus.load(std::memory_order_relaxed);
}

void Agent::removeAtomStimulus(Handle h)
{
    stim_t amount;
    {
        std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);
        // if handle not in map then return
        if (stimulatedAtoms->find(h) == stimulatedAtoms->end())
            return;

        amount = (*stimulatedAtoms)[h];
        stimulatedAtoms->erase(h);
    }

    // update record of total stimulus given out
    totalStimulus -= amount;
}

stim_t Agent::stimulateAtom(HandleSeq hs, stim_t amount)
{
    stim_t split;

    // how much to give each atom
    split = amount / hs.size();

    for (Handle handle : hs) {
        stimulateAtom(handle, split);
    }
    // return unused stimulus
    return amount - (split * hs.size());
}

stim_t Agent::resetStimulus()
{
    {
        std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);
        stimulatedAtoms->clear();
    }
    // reset stimulus counter
    totalStimulus = 0;
    return totalStimulus.load(std::memory_order_relaxed);
}

stim_t Agent::getTotalStimulus() const
{
    return totalStimulus;
}

stim_t Agent::getAtomStimulus(Handle h) const
{
    std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);
    if (stimulatedAtoms->find(h) == stimulatedAtoms->end()) {
        return 0;
    } else {
        return (*stimulatedAtoms)[h];
    }
}

void Agent::experimentalStimulateAtom(Handle h,float stimulus)
{
    int sti = h->getAttentionValue()->getSTI();
    int lti = h->getAttentionValue()->getLTI();
    int stiWage = calculate_STI_Wage() * stimulus;
    int ltiWage = calculate_LTI_Wage() * stimulus;

    h->setSTI(sti + stiWage);
    h->setLTI(lti + ltiWage);
}

AttentionValue::sti_t Agent::calculate_STI_Wage()
{
    int funds = _as->get_STI_funds();
    float diff  = funds - targetSTI;
    float ndiff = diff / stiFundsBuffer;
    ndiff = std::min(ndiff,1.0f);
    ndiff = std::max(ndiff,-1.0f);

    return STIAtomWage + (STIAtomWage * ndiff);
}

AttentionValue::lti_t Agent::calculate_LTI_Wage()
{
    int funds = _as->get_LTI_funds();
    float diff  = funds - targetLTI;
    float ndiff = diff / ltiFundsBuffer;
    ndiff = std::min(ndiff,1.0f);
    ndiff = std::max(ndiff,-1.0f);

    return LTIAtomWage + (LTIAtomWage * ndiff);
}
<commit_msg>Fix cogserver crash<commit_after>/*
 * opencog/cogserver/server/Agent.cc
 *
 * Copyright (C) 2008 by OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "Agent.h"

#include <opencog/cogserver/server/CogServer.h>
#include <opencog/util/Config.h>

#define DEBUG

using namespace opencog;

Agent::Agent(CogServer& cs, const unsigned int f) : _cogserver(cs), _frequency(f)
{
#if 0
This causes the cogserver to crash!
See https://github.com/opencog/opencog/issues/2329

    STIAtomWage = config().get_int("ECAN_STARTING_ATOM_STI_WAGE");
    LTIAtomWage = config().get_int("ECAN_STARTING_ATOM_LTI_WAGE");

    targetSTI = config().get_int("TARGET_STI_FUNDS");
    stiFundsBuffer = config().get_int("STI_FUNDS_BUFFER");
    targetLTI = config().get_int("TARGET_LTI_FUNDS");
    ltiFundsBuffer = config().get_int("LTI_FUNDS_BUFFER");
#endif

    _attentionValue = AttentionValue::DEFAULT_AV();

    // an empty set of parameters and defaults (so that various
    // methods will still work even if none are set in this or a derived
    // class)
    static const std::string defaultConfig[] = {
        "", ""
    };
    setParameters(defaultConfig);

    stimulatedAtoms = new AtomStimHashMap();
    totalStimulus = 0;

    conn = _cogserver.getAtomSpace().removeAtomSignal(
            boost::bind(&Agent::atomRemoved, this, _1));

    _as = &cs.getAtomSpace();
}

Agent::~Agent()
{
    // give back funds
    _as->update_STI_funds(_attentionValue->getSTI());
    _as->update_LTI_funds(_attentionValue->getLTI());

    resetUtilizedHandleSets();
    conn.disconnect();
    delete stimulatedAtoms;

    if (log)
        delete log;
}

void Agent::setLogger(Logger* _log)
{
    if (log)
        delete log;
    log = _log;
}

Logger* Agent::getLogger()
{
    return log;
}

void Agent::setParameters(const std::string* params)
{
    PARAMETERS = params;

    for (unsigned int i = 0; params[i] != ""; i += 2) {
        if (!config().has(params[i])) {
           config().set(params[i], params[i + 1]);
        }
    }
}

std::string Agent::to_string() const
{
    std::ostringstream oss;
    oss << classinfo().id;
    oss << " {\"";
    for (unsigned int i = 0; PARAMETERS[i] != ""; i += 2) {
        if (i != 0) oss << "\", \"";
        oss << PARAMETERS[i] << "\" => \"" << config()[PARAMETERS[i]];
    }
    oss << "\"}";
    return oss.str();
}

void Agent::atomRemoved(AtomPtr atom)
{
    Handle h = atom->getHandle();
    {
        std::lock_guard<std::mutex> lock(_handleSetMutex);
        for (size_t i = 0; i < _utilizedHandleSets.size(); i++)
            _utilizedHandleSets[i].erase(h);
    }
    removeAtomStimulus(h);
}

void Agent::resetUtilizedHandleSets()
{
    std::lock_guard<std::mutex> lock(_handleSetMutex);
    for (size_t i = 0; i < _utilizedHandleSets.size(); i++)
        _utilizedHandleSets[i].clear();
    _utilizedHandleSets.clear();
}

stim_t Agent::stimulateAtom(Handle h, stim_t amount)
{
    {
        std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);

        // Add atom to the map of atoms with stimulus
        // and add stimulus to it
        (*stimulatedAtoms)[h] += amount;
    }

    // update record of total stimulus given out
    totalStimulus += amount;

    logger().fine("Atom %d received stimulus of %d, total now %d",
                  h.value(),
                  amount,
                  totalStimulus.load(std::memory_order_relaxed));

#ifdef DEBUG
    std::cout << "Atom " << h.value() << " received stimulus of " << amount <<
                 ", total now " << totalStimulus.load(std::memory_order_relaxed)
                 << "\n";
#endif

    return totalStimulus.load(std::memory_order_relaxed);
}

void Agent::removeAtomStimulus(Handle h)
{
    stim_t amount;
    {
        std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);
        // if handle not in map then return
        if (stimulatedAtoms->find(h) == stimulatedAtoms->end())
            return;

        amount = (*stimulatedAtoms)[h];
        stimulatedAtoms->erase(h);
    }

    // update record of total stimulus given out
    totalStimulus -= amount;
}

stim_t Agent::stimulateAtom(HandleSeq hs, stim_t amount)
{
    stim_t split;

    // how much to give each atom
    split = amount / hs.size();

    for (Handle handle : hs) {
        stimulateAtom(handle, split);
    }
    // return unused stimulus
    return amount - (split * hs.size());
}

stim_t Agent::resetStimulus()
{
    {
        std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);
        stimulatedAtoms->clear();
    }
    // reset stimulus counter
    totalStimulus = 0;
    return totalStimulus.load(std::memory_order_relaxed);
}

stim_t Agent::getTotalStimulus() const
{
    return totalStimulus;
}

stim_t Agent::getAtomStimulus(Handle h) const
{
    std::lock_guard<std::mutex> lock(stimulatedAtomsMutex);
    if (stimulatedAtoms->find(h) == stimulatedAtoms->end()) {
        return 0;
    } else {
        return (*stimulatedAtoms)[h];
    }
}

void Agent::experimentalStimulateAtom(Handle h,float stimulus)
{
    int sti = h->getAttentionValue()->getSTI();
    int lti = h->getAttentionValue()->getLTI();
    int stiWage = calculate_STI_Wage() * stimulus;
    int ltiWage = calculate_LTI_Wage() * stimulus;

    h->setSTI(sti + stiWage);
    h->setLTI(lti + ltiWage);
}

AttentionValue::sti_t Agent::calculate_STI_Wage()
{
    int funds = _as->get_STI_funds();
    float diff  = funds - targetSTI;
    float ndiff = diff / stiFundsBuffer;
    ndiff = std::min(ndiff,1.0f);
    ndiff = std::max(ndiff,-1.0f);

    return STIAtomWage + (STIAtomWage * ndiff);
}

AttentionValue::lti_t Agent::calculate_LTI_Wage()
{
    int funds = _as->get_LTI_funds();
    float diff  = funds - targetLTI;
    float ndiff = diff / ltiFundsBuffer;
    ndiff = std::min(ndiff,1.0f);
    ndiff = std::max(ndiff,-1.0f);

    return LTIAtomWage + (LTIAtomWage * ndiff);
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace NP_DATETIME;

namespace CSS133Assignment1Tests
{
	TEST_CLASS(CTimeTests)
	{
	public:

		// Constructor tests

		TEST_METHOD(EmptyConstructorTest)
		{
			validateTime(CTime());
		}

		TEST_METHOD(MaxHourConstructorTest)
		{
			CTime time = CTime(23);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)23);
		}

		TEST_METHOD(OverflowMaxHourConstructorTest)
		{
			CTime time = CTime(24);
			validateTime(time);
			Assert::AreNotEqual(time.getHour(), (short)24);
		}

		TEST_METHOD(MaxMinuteConstructorTest)
		{
			CTime time = CTime(1, 59);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreEqual(time.getMinute(), (short)59);
		}

		TEST_METHOD(OverflowMaxMinuteConstructorTest)
		{
			CTime time = CTime(1, 60);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreNotEqual(time.getMinute(), (short)60);
		}

		TEST_METHOD(MaxSecondConstructorTest)
		{
			CTime time = CTime(1, 1, 59);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreEqual(time.getMinute(), (short)1);
			Assert::AreEqual(time.getSecond(), (short)59);
		}

		TEST_METHOD(OverflowMaxSecondConstructorTest)
		{
			CTime time = CTime(1, 1, 60);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreEqual(time.getMinute(), (short)1);
			Assert::AreNotEqual(time.getSecond(), (short)60);
		}

		// Hour Mutator/Accessor Tests

		TEST_METHOD(SetHourValidValues)
		{
			CTime time = CTime(0,0,0);
			for (short hour = 0; hour < 24; hour++) {
				time.setHour(hour);
				validateTime(time);
				Assert::AreEqual(time.getHour(), hour);
			}
		}

		TEST_METHOD(SetHourInValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short hour = 24; hour < 100; hour++) {
				time.setHour(hour);
				validateTime(time);
				Assert::AreEqual(time.getHour(), (short)0);
			}
		}

		// Minute Mutator/Accessor Tests

		TEST_METHOD(SetMinuteValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short minute = 0; minute < 60; minute++) {
				time.setMinute(minute);
				validateTime(time);
				Assert::AreEqual(time.getMinute(), minute);
			}
		}

		TEST_METHOD(SetMinuteInValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short minute = 60; minute < 100; minute++) {
				time.setMinute(minute);
				validateTime(time);
				Assert::AreEqual(time.getMinute(), (short)0);
			}
		}

		// Second Mutator/Accessor Tests

		TEST_METHOD(SetSecondValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short second = 0; second < 60; second++) {
				time.setSecond(second);
				validateTime(time);
				Assert::AreEqual(time.getSecond(), second);
			}
		}

		TEST_METHOD(SetSecondInValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short second = 60; second < 100; second++) {
				time.setSecond(second);
				validateTime(time);
				Assert::AreEqual(time.getSecond(), (short)0);
			}
		}

		// Comparison Tests

		TEST_METHOD(HourlyComparisonTests)
		{
			CTime early;
			CTime late;

			for (short earlyHour = 0; earlyHour < 24; earlyHour++) {
				early.setHour(earlyHour);
				late.setHour(earlyHour);
				Assert::IsTrue(early == late);
				Assert::IsTrue(early <= late);
				Assert::IsTrue(late >= early);
				for (short lateHour = earlyHour + 1; lateHour < 24; lateHour++) {
					late.setHour(lateHour);
					Assert::IsTrue(early < late);
					Assert::IsTrue(late > early);
					Assert::IsTrue(early <= late);
					Assert::IsTrue(late >= early);
				}
			}
		}

		TEST_METHOD(MinutelyComparisonTests)
		{
			CTime early(0, 0, 0);
			CTime late(0, 0, 0);

			for (short earlyMinute = 0; earlyMinute < 60; earlyMinute++) {
				early.setMinute(earlyMinute);
				late.setMinute(earlyMinute);
				Assert::IsTrue(early == late);
				Assert::IsTrue(early <= late);
				Assert::IsTrue(late >= early);
				for (short lateMinute = earlyMinute + 1; lateMinute < 60; lateMinute++) {
					late.setMinute(lateMinute);
					Assert::IsTrue(early < late);
					Assert::IsTrue(late > early);
					Assert::IsTrue(early <= late);
					Assert::IsTrue(late >= early);
				}
			}
		}

		TEST_METHOD(HourlyAndMinutelyComparisonTests)
		{
			CTime time1(0, 0, 0);
			CTime time2(0, 0, 0);

			short defaultHour = 12;

			for (short hourVariation = -1; hourVariation <= 1; hourVariation++) {

				time1.setHour(defaultHour);
				time2.setHour(hourVariation + defaultHour);

				for (short earlyMinute = 0; earlyMinute < 60; earlyMinute++) {
					time1.setMinute(earlyMinute);
					time2.setMinute(earlyMinute);
					if (hourVariation == -1) {
						Assert::IsTrue(time1 > time2);
						Assert::IsTrue(time1 >= time2);
						Assert::IsTrue(time2 < time1);
						Assert::IsTrue(time2 <= time1);
					}
					else if (hourVariation == 0) {
						Assert::IsTrue(time1 == time2);
						Assert::IsTrue(time1 <= time2);
						Assert::IsTrue(time2 >= time1);
					}
					else {
						Assert::IsTrue(time2 > time1);
						Assert::IsTrue(time2 >= time1);
						Assert::IsTrue(time1 < time2);
						Assert::IsTrue(time1 <= time2);
					}

					for (short lateMinute = earlyMinute + 1; lateMinute < 60; lateMinute++) {
						time2.setMinute(lateMinute);

						if (hourVariation == -1) {
							Assert::IsTrue(time1 > time2);
							Assert::IsTrue(time1 >= time2);
							Assert::IsTrue(time2 < time1);
							Assert::IsTrue(time2 <= time1);
						}
						else if (hourVariation == 0) {
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time1 <= time2);
							Assert::IsTrue(time2 >= time1);
						}
						else {
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time2 >= time1);
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time1 <= time2);
						}
					}
				}

			}
		}

		TEST_METHOD(HourlyAndSecondlyComparisonTests)
		{
			CTime time1(0, 0, 0);
			CTime time2(0, 0, 0);

			short defaultMinute = 30;

			for (short minuteVariation = -1; minuteVariation <= 1; minuteVariation++) {

				time1.setMinute(defaultMinute);
				time2.setMinute(minuteVariation + defaultMinute);

				for (short earlySecond = 0; earlySecond < 60; earlySecond++) {
					time1.setSecond(earlySecond);
					time2.setSecond(earlySecond);
					if (minuteVariation == -1) {
						Assert::IsTrue(time1 > time2);
						Assert::IsTrue(time1 >= time2);
						Assert::IsTrue(time2 < time1);
						Assert::IsTrue(time2 <= time1);
					}
					else if (minuteVariation == 0) {
						Assert::IsTrue(time1 == time2);
						Assert::IsTrue(time1 <= time2);
						Assert::IsTrue(time2 >= time1);
					}
					else {
						Assert::IsTrue(time2 > time1);
						Assert::IsTrue(time2 >= time1);
						Assert::IsTrue(time1 < time2);
						Assert::IsTrue(time1 <= time2);
					}

					for (short lateSecond = earlySecond + 1; lateSecond < 60; lateSecond++) {
						time2.setSecond(lateSecond);

						if (minuteVariation == -1) {
							Assert::IsTrue(time1 > time2);
							Assert::IsTrue(time1 >= time2);
							Assert::IsTrue(time2 < time1);
							Assert::IsTrue(time2 <= time1);
						}
						else if (minuteVariation == 0) {
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time1 <= time2);
							Assert::IsTrue(time2 >= time1);
						}
						else {
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time2 >= time1);
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time1 <= time2);
						}
					}
				}
			}
		}

	private:
		void validateTime(CTime time) {
			Assert::IsTrue(time.getHour() >= 0 && time.getHour() < 24);
			Assert::IsTrue(time.getMinute() >= 0 && time.getMinute() < 60);
			Assert::IsTrue(time.getSecond() >= 0 && time.getSecond() < 60);
		}

	};
}<commit_msg>add test for time comparison<commit_after>#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace NP_DATETIME;

namespace CSS133Assignment1Tests
{
	TEST_CLASS(CTimeTests)
	{
	public:

		// Constructor tests

		TEST_METHOD(EmptyConstructorTest)
		{
			validateTime(CTime());
		}

		TEST_METHOD(MaxHourConstructorTest)
		{
			CTime time = CTime(23);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)23);
		}

		TEST_METHOD(OverflowMaxHourConstructorTest)
		{
			CTime time = CTime(24);
			validateTime(time);
			Assert::AreNotEqual(time.getHour(), (short)24);
		}

		TEST_METHOD(MaxMinuteConstructorTest)
		{
			CTime time = CTime(1, 59);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreEqual(time.getMinute(), (short)59);
		}

		TEST_METHOD(OverflowMaxMinuteConstructorTest)
		{
			CTime time = CTime(1, 60);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreNotEqual(time.getMinute(), (short)60);
		}

		TEST_METHOD(MaxSecondConstructorTest)
		{
			CTime time = CTime(1, 1, 59);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreEqual(time.getMinute(), (short)1);
			Assert::AreEqual(time.getSecond(), (short)59);
		}

		TEST_METHOD(OverflowMaxSecondConstructorTest)
		{
			CTime time = CTime(1, 1, 60);
			validateTime(time);
			Assert::AreEqual(time.getHour(), (short)1);
			Assert::AreEqual(time.getMinute(), (short)1);
			Assert::AreNotEqual(time.getSecond(), (short)60);
		}

		// Hour Mutator/Accessor Tests

		TEST_METHOD(SetHourValidValues)
		{
			CTime time = CTime(0,0,0);
			for (short hour = 0; hour < 24; hour++) {
				time.setHour(hour);
				validateTime(time);
				Assert::AreEqual(time.getHour(), hour);
			}
		}

		TEST_METHOD(SetHourInValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short hour = 24; hour < 100; hour++) {
				time.setHour(hour);
				validateTime(time);
				Assert::AreEqual(time.getHour(), (short)0);
			}
		}

		// Minute Mutator/Accessor Tests

		TEST_METHOD(SetMinuteValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short minute = 0; minute < 60; minute++) {
				time.setMinute(minute);
				validateTime(time);
				Assert::AreEqual(time.getMinute(), minute);
			}
		}

		TEST_METHOD(SetMinuteInValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short minute = 60; minute < 100; minute++) {
				time.setMinute(minute);
				validateTime(time);
				Assert::AreEqual(time.getMinute(), (short)0);
			}
		}

		// Second Mutator/Accessor Tests

		TEST_METHOD(SetSecondValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short second = 0; second < 60; second++) {
				time.setSecond(second);
				validateTime(time);
				Assert::AreEqual(time.getSecond(), second);
			}
		}

		TEST_METHOD(SetSecondInValidValues)
		{
			CTime time = CTime(0, 0, 0);
			for (short second = 60; second < 100; second++) {
				time.setSecond(second);
				validateTime(time);
				Assert::AreEqual(time.getSecond(), (short)0);
			}
		}

		// Comparison Tests

		TEST_METHOD(HourlyComparisonTests)
		{
			CTime early;
			CTime late;

			for (short earlyHour = 0; earlyHour < 24; earlyHour++) {
				early.setHour(earlyHour);
				late.setHour(earlyHour);
				Assert::IsTrue(early == late);
				Assert::IsTrue(early <= late);
				Assert::IsTrue(late >= early);
				for (short lateHour = earlyHour + 1; lateHour < 24; lateHour++) {
					late.setHour(lateHour);
					Assert::IsTrue(early < late);
					Assert::IsTrue(late > early);
					Assert::IsTrue(early <= late);
					Assert::IsTrue(late >= early);
				}
			}
		}

		TEST_METHOD(MinutelyComparisonTests)
		{
			CTime early(0, 0, 0);
			CTime late(0, 0, 0);

			for (short earlyMinute = 0; earlyMinute < 60; earlyMinute++) {
				early.setMinute(earlyMinute);
				late.setMinute(earlyMinute);
				Assert::IsTrue(early == late);
				Assert::IsTrue(early <= late);
				Assert::IsTrue(late >= early);
				for (short lateMinute = earlyMinute + 1; lateMinute < 60; lateMinute++) {
					late.setMinute(lateMinute);
					Assert::IsTrue(early < late);
					Assert::IsTrue(late > early);
					Assert::IsTrue(early <= late);
					Assert::IsTrue(late >= early);
				}
			}
		}

		TEST_METHOD(HourlyAndMinutelyComparisonTests)
		{
			CTime time1(0, 0, 0);
			CTime time2(0, 0, 0);

			short defaultHour = 12;

			for (short hourVariation = -1; hourVariation <= 1; hourVariation++) {

				time1.setHour(defaultHour);
				time2.setHour(hourVariation + defaultHour);

				for (short earlyMinute = 0; earlyMinute < 60; earlyMinute++) {
					time1.setMinute(earlyMinute);
					time2.setMinute(earlyMinute);
					if (hourVariation == -1) {
						Assert::IsTrue(time1 > time2);
						Assert::IsTrue(time1 >= time2);
						Assert::IsTrue(time2 < time1);
						Assert::IsTrue(time2 <= time1);
					}
					else if (hourVariation == 0) {
						Assert::IsTrue(time1 == time2);
						Assert::IsTrue(time1 <= time2);
						Assert::IsTrue(time2 >= time1);
					}
					else {
						Assert::IsTrue(time2 > time1);
						Assert::IsTrue(time2 >= time1);
						Assert::IsTrue(time1 < time2);
						Assert::IsTrue(time1 <= time2);
					}

					for (short lateMinute = earlyMinute + 1; lateMinute < 60; lateMinute++) {
						time2.setMinute(lateMinute);

						if (hourVariation == -1) {
							Assert::IsTrue(time1 > time2);
							Assert::IsTrue(time1 >= time2);
							Assert::IsTrue(time2 < time1);
							Assert::IsTrue(time2 <= time1);
						}
						else if (hourVariation == 0) {
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time1 <= time2);
							Assert::IsTrue(time2 >= time1);
						}
						else {
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time2 >= time1);
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time1 <= time2);
						}
					}
				}

			}
		}

		TEST_METHOD(RandomSortTests) {
			auto time0 = CTime(13, 45, 23);
			auto time1 = CTime(10, 18, 53);
			auto time2 = CTime(17, 30, 38);
			auto time3 = CTime(5, 20, 15);
			auto time4 = CTime(10, 30, 50);
			auto time5 = CTime(15, 0, 18);
			auto time6 = CTime(13, 45, 23);

			Assert::IsTrue(time0 > time1);
			Assert::IsTrue(time1 < time2);
			Assert::IsTrue(time2 > time3);
			Assert::IsTrue(time3 < time4);
			Assert::IsTrue(time4 < time5);
			Assert::IsTrue(time5 > time6);
			Assert::IsTrue(time0 == time6);

		}

		TEST_METHOD(HourlyAndSecondlyComparisonTests)
		{
			CTime time1(0, 0, 0);
			CTime time2(0, 0, 0);

			short defaultMinute = 30;

			for (short minuteVariation = -1; minuteVariation <= 1; minuteVariation++) {

				time1.setMinute(defaultMinute);
				time2.setMinute(minuteVariation + defaultMinute);

				for (short earlySecond = 0; earlySecond < 60; earlySecond++) {
					time1.setSecond(earlySecond);
					time2.setSecond(earlySecond);
					if (minuteVariation == -1) {
						Assert::IsTrue(time1 > time2);
						Assert::IsTrue(time1 >= time2);
						Assert::IsTrue(time2 < time1);
						Assert::IsTrue(time2 <= time1);
					}
					else if (minuteVariation == 0) {
						Assert::IsTrue(time1 == time2);
						Assert::IsTrue(time1 <= time2);
						Assert::IsTrue(time2 >= time1);
					}
					else {
						Assert::IsTrue(time2 > time1);
						Assert::IsTrue(time2 >= time1);
						Assert::IsTrue(time1 < time2);
						Assert::IsTrue(time1 <= time2);
					}

					for (short lateSecond = earlySecond + 1; lateSecond < 60; lateSecond++) {
						time2.setSecond(lateSecond);

						if (minuteVariation == -1) {
							Assert::IsTrue(time1 > time2);
							Assert::IsTrue(time1 >= time2);
							Assert::IsTrue(time2 < time1);
							Assert::IsTrue(time2 <= time1);
						}
						else if (minuteVariation == 0) {
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time1 <= time2);
							Assert::IsTrue(time2 >= time1);
						}
						else {
							Assert::IsTrue(time2 > time1);
							Assert::IsTrue(time2 >= time1);
							Assert::IsTrue(time1 < time2);
							Assert::IsTrue(time1 <= time2);
						}
					}
				}
			}
		}

	private:
		void validateTime(CTime time) {
			Assert::IsTrue(time.getHour() >= 0 && time.getHour() < 24);
			Assert::IsTrue(time.getMinute() >= 0 && time.getMinute() < 60);
			Assert::IsTrue(time.getSecond() >= 0 && time.getSecond() < 60);
		}

	};
}<|endoftext|>


<commit_before><commit_msg>10098 - Generating Fast<commit_after><|endoftext|>


<commit_before>/**
 * @file length_filter.cpp
 * @author Chase Geigle
 */

#include "analyzers/filters/length_filter.h"

namespace meta
{
namespace analyzers
{

length_filter::length_filter(std::unique_ptr<token_stream> source, uint64_t min,
                             uint64_t max)
    : source_{std::move(source)}, min_length_{min}, max_length_{max}
{
    next_token();
}

length_filter::length_filter(const length_filter& other)
    : source_{other.source_->clone()},
      token_{other.token_},
      min_length_{other.min_length_},
      max_length_{other.max_length_}
{
    // nothing
}

void length_filter::set_content(const std::string& content)
{
    token_ = util::nullopt;
    source_->set_content(content);
    next_token();
}

std::string length_filter::next()
{
    auto tok = *token_;
    next_token();
    return tok;
}

length_filter::operator bool() const
{
    return token_ || *source_;
}

void length_filter::next_token()
{
    if (!*source_)
    {
        token_ = util::nullopt;
        return;
    }

    while (*source_)
    {
        auto tok = source_->next();
        if (tok.length() >= min_length_ && tok.length() <= max_length_)
        {
            token_ = tok;
            break;
        }
    }
}

}
}
<commit_msg>Update length_filter to be unicode aware.<commit_after>/**
 * @file length_filter.cpp
 * @author Chase Geigle
 */

#include "analyzers/filters/length_filter.h"
#include "util/utf.h"

namespace meta
{
namespace analyzers
{

length_filter::length_filter(std::unique_ptr<token_stream> source, uint64_t min,
                             uint64_t max)
    : source_{std::move(source)}, min_length_{min}, max_length_{max}
{
    next_token();
}

length_filter::length_filter(const length_filter& other)
    : source_{other.source_->clone()},
      token_{other.token_},
      min_length_{other.min_length_},
      max_length_{other.max_length_}
{
    // nothing
}

void length_filter::set_content(const std::string& content)
{
    token_ = util::nullopt;
    source_->set_content(content);
    next_token();
}

std::string length_filter::next()
{
    auto tok = *token_;
    next_token();
    return tok;
}

length_filter::operator bool() const
{
    return token_ || *source_;
}

void length_filter::next_token()
{
    if (!*source_)
    {
        token_ = util::nullopt;
        return;
    }

    while (*source_)
    {
        auto tok = source_->next();
        auto len = utf::length(tok);
        if (len >= min_length_ && len <= max_length_)
        {
            token_ = tok;
            break;
        }
    }
}

}
}
<|endoftext|>


<commit_before>#include "qjsonwebtoken.h"

QJsonWebToken::QJsonWebToken()
{

}
<commit_msg>removing qjsonwebtoken<commit_after><|endoftext|>