Taro3

View on GitHub

Mac OS実装を追加する

SysInfoクラスのMac実装を見てみましょう。まず、SysInfoクラスを継承するSysInfoMacImplという名前の新しいC++クラスを作成します。SysInfo仮想関数をオーバーライドすると次のようなSysInfoMacImpl.hファイルが作成されます。

#include "sysinfo.h"

#include <QtGlobal>
#include <QVector>

class SysInfoMacImpl : public SysInfo
{
public:
    SysInfoMacImpl();

    // SysInfo interface
public:
    void init() override;
    double cpuLoadAverage() override;
    double memoryUsed() override;
};

最初に行う実装は、SysInfoMacImpl.cppファイル内のmemoryUsed()関数です。

#include <mach/vm_statistics.h>
#include <mach/mach_types.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/vm_map.h>

SysInfoMacImpl::SysInfoMacImpl() :
    SysInfo()
{

}

double SysInfoMacImpl::memoryUsed()
{
    vm_size_t pageSize;
    vm_statistics64_data_t vmStats;

    mach_port_t machPort = mach_host_self();

    mach_msg_type_number_t count = sizeof(vmStats)
            / sizeof(natural_t);
    host_page_size(machPort, &pageSize);

    host_statistics64(machPort,
                      HOST_VM_INFO,
                      (host_info64_t)&vmStats,
                      &count);

    qulonglong freeMemory = (int64_t)vmStats.free_count
            * (int64_t)pageSize;

    qulonglong totalMemoryUsed = ((int64_t)vmStats.active_count +
                                  (int64_t)vmStats.inactive_count +
                                  (int64_t)vmStats.wire_count)
            * (int64_t)pageSize;

    qulonglong totalMemory = freeMemory + totalMemoryUsed;

    double percent = (double)totalMemoryUsed
            / (double)totalMemory * 100.0;
    return qBound(0.0, percent, 100.0);
}

まず、Mac OSカーネルのさまざまなヘッダを含めます。次に、mach_host_self()関数を呼び出してmachPortを初期化します。machPortは、システムへの情報を要求できるようにする、カーネルへの一種の特別な接続のようなものです。次に、host_statistics64()で仮想メモリ統計を取得できるように、他の変数の準備に進みます。

vmStatsクラスに必要な情報が入力されると、関連するデータであるfreeMemoryとtotalMemoryUsedが抽出されます。

Mac OSには、メモリを管理する独特の方法があることに注意してください。これは、大量のメモリをキャッシュに保持し、必要なときにフラッシュできるようにします。これは、私たちの統計が誤解される可能性があることを意味します。メモリが使用されたように見えますが、単に「念のため」に保管されているだけなのです。

割合の計算は簡単ですが、今後のグラフでおかしな値が出ないようにするために、クランプされた最小/最大値を返します。

次はcpuLoadAverage()の実装です、パターンは同じで、定期的な感覚でサンプルを取得し、この感覚での増加を計算します。したがって、次のサンプルとの差を計算できるように、中間値を保存する必要があります。

#include "sysinfo.h"

#include <QtGlobal>
#include <QVector>

...

private:
    QVector<qulonglong> cpuRawData();

private:
    QVector<qulonglong> mCpuLoadLastValues;
};

void SysInfoMacImpl::init()
{
    mCpuLoadLastValues = cpuRawData();
}

QVector<qulonglong> SysInfoMacImpl::cpuRawData()
{
    host_cpu_load_info_data_t cpuInfo;
    mach_msg_type_number_t cpuCount = HOST_CPU_LOAD_INFO_COUNT;
    QVector<qulonglong> rawData;
    qulonglong totalUser = 0, totalUserNice = 0, totalSystem = 0,
            totalIdle = 0;
    host_statistics(mach_host_self(),
                    HOST_CPU_LOAD_INFO,
                    (host_info_t)&cpuInfo,
                    &cpuCount);

    for(unsigned int i = 0; i < cpuCount; i++) {
        unsigned int maxTicks = CPU_STATE_MAX * i;
        totalUser += cpuInfo.cpu_ticks[maxTicks + CPU_STATE_USER];
        totalUserNice += cpuInfo.cpu_ticks[maxTicks
                + CPU_STATE_SYSTEM];
        totalSystem += cpuInfo.cpu_ticks[maxTicks
                + CPU_STATE_NICE];
        totalIdle += cpuInfo.cpu_ticks[maxTicks + CPU_STATE_IDLE];
    }

    rawData.append(totalUser);
    rawData.append(totalUserNice);
    rawData.append(totalSystem);
    rawData.append(totalIdle);
    return rawData;
}

見たとおり、使用されるパターンはLinuxの実装と厳密に同等です。SysInfoLinuxImpl.cppファイルからcpuLoadAverage()関数の本体をコピーして貼り付けることも出来ます。それらは全く同じことを行います。

ここでは、cpuRawData()関数の実装は異なります。host_statistics()を使用してcpuInfoとcpuCountをロードし、各CPUをループして、totalUser、totalUserNice、totalSystem、totalIdleをを設定しています。最後に、この全てのデータをrawDataオブジェクトに追加してから返します。

最後の部分は、Mac OSでのみSysInfoMacImplクラスをコンパイルすることです。次の内容になるように.proファイルを変更します。

...

linux {
    SOURCES += sysinfolinuximpl.cpp
    HEADERS += sysinfolinuximpl.h
}

macx {
    SOURCES += sysinfomacimpl.cpp
    HEADERS += sysinfomacimpl.h
}

FORMS += \
    mainwindow.ui

戻る