New caching mechanism for CPU

This commit is contained in:
Linus Dierheimer
2022-09-21 17:26:10 +02:00
parent 07231ffbbc
commit d31d157b00
8 changed files with 202 additions and 78 deletions
+101 -11
View File
@@ -4,6 +4,7 @@
#include "common/printing.h"
#include <stdlib.h>
#include <string.h>
#define FF_CACHE_VERSION_NAME "cacheversion"
#define FF_CACHE_VERSION_EXTENSION "ffv"
@@ -11,7 +12,7 @@
#define FF_CACHE_VALUE_EXTENSION "ffcv"
#define FF_CACHE_SPLIT_EXTENSION "ffcs"
#define FF_CACHE_EXTENSION_DATA "ffcd"
#define FF_CACHE_EXTENSION_V1 "ffc1"
static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
{
@@ -211,24 +212,113 @@ void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const
ffCacheClose(&cache);
}
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data)
typedef struct FFCacheRead
{
FFstrbuf path;
ffStrbufInitA(&path, 128);
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
ffWriteFileData(path.chars, dataSize, data);
ffStrbufDestroy(&path);
FFstrbuf data;
uint32_t position;
} FFCacheRead;
static bool cacheReadStrbuf(FFCacheRead* cacheRead, FFstrbuf* strbuf)
{
if(cacheRead->position >= cacheRead->data.length)
return false;
ffStrbufAppendS(strbuf, cacheRead->data.chars + cacheRead->position);
cacheRead->position += strbuf->length + 1; // skip the null byte too
return true;
}
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data)
static bool cacheReadData(FFCacheRead* cacheRead, size_t dataSize, void* data)
{
if(cacheRead->position + dataSize > cacheRead->data.length)
return false;
memcpy(data, cacheRead->data.chars + cacheRead->position, dataSize);
cacheRead->position += (uint32_t) dataSize;
return true;
}
static bool cacheResetStrbuf(FFCache* cache, FFstrbuf* strbuf)
{
FF_UNUSED(cache);
ffStrbufClear(strbuf);
return true;
}
static bool cacheResetData(FFCache* cacheRead, size_t dataSize, void* data)
{
FF_UNUSED(cacheRead, dataSize, data);
return true;
}
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
{
if(instance->config.recache)
return false;
FFCacheRead cache;
bool result;
FFstrbuf path;
ffStrbufInitA(&path, 128);
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
ssize_t result = ffReadFileData(path.chars, dataSize, data);
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
cache.position = 0;
ffStrbufInitA(&cache.data, 256);
result = ffAppendFileBuffer(path.chars, &cache.data);
if(result)
result = callback(obj, &cache, (FFCacheMethodStrbuf) cacheReadStrbuf, (FFCacheMethodData) cacheReadData);
if(result)
result = cache.position == cache.data.length;
if(!result)
callback(obj, NULL, (FFCacheMethodStrbuf) cacheResetStrbuf, (FFCacheMethodData) cacheResetData);
ffStrbufDestroy(&cache.data);
ffStrbufDestroy(&path);
return result;
}
typedef struct FFCacheWrite
{
FFstrbuf data;
} FFCacheWrite;
static bool cacheWriteStrbuf(FFCacheWrite* cacheWrite, FFstrbuf* strbuf)
{
ffStrbufEnsureFree(&cacheWrite->data, strbuf->length);
memcpy(cacheWrite->data.chars + cacheWrite->data.length, strbuf->chars, strbuf->length +1); //Copy the nullbyte too
cacheWrite->data.length += strbuf->length + 1;
return true;
}
static bool cacheWriteData(FFCacheWrite* cacheWrite, size_t dataSize, const void* data)
{
ffStrbufEnsureFree(&cacheWrite->data, (uint32_t) dataSize);
memcpy(cacheWrite->data.chars + cacheWrite->data.length, data, dataSize);
cacheWrite->data.length += (uint32_t) dataSize;
return true;
}
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
{
if(!instance->config.cacheSave)
return;
FFCacheWrite cache;
FFstrbuf path;
ffStrbufInitA(&path, 128);
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
ffStrbufInitA(&cache.data, 256);
callback(obj, &cache, (FFCacheMethodStrbuf) cacheWriteStrbuf, (FFCacheMethodData) cacheWriteData);
ffWriteFileBuffer(path.chars, &cache.data);
ffStrbufDestroy(&cache.data);
ffStrbufDestroy(&path);
return result > 0 && (size_t) result == dataSize;
}
+8 -2
View File
@@ -21,7 +21,13 @@ bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModu
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data);
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data);
typedef void FFCache;
typedef bool(*FFCacheMethodStrbuf)(FFCache* cache, FFstrbuf* strbuf);
typedef bool(*FFCacheMethodData)(FFCache* cache, size_t dataSize, void* data);
typedef bool(*FFCacheMethodCallback)(void* data, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod);
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
#endif
+44 -14
View File
@@ -1,22 +1,52 @@
#include "cpu.h"
#include "common/caching.h"
#include "detection/internal.h"
void ffDetectCPUImpl(FFCPUResult* cpu);
#define FF_CPU_CACHE_NAME "cpu"
const FFCPUResult* ffDetectCPU()
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached);
static bool cacheCallback(FFCPUResult* cpu, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod)
{
return
strbufMethod(cache, &cpu->vendor) &&
strbufMethod(cache, &cpu->name) &&
dataMethod(cache, sizeof(cpu->coresPhysical), &cpu->coresPhysical) &&
dataMethod(cache, sizeof(cpu->coresLogical), &cpu->coresLogical) &&
dataMethod(cache, sizeof(cpu->coresOnline), &cpu->coresOnline) &&
dataMethod(cache, sizeof(cpu->frequencyMin), &cpu->frequencyMin) &&
dataMethod(cache, sizeof(cpu->frequencyMax), &cpu->frequencyMax);
}
static void detectCPU(const FFinstance* instance, FFCPUResult* cpu)
{
ffStrbufInit(&cpu->name);
ffStrbufInit(&cpu->vendor);
bool cached = ffCacheRead(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
ffDetectCPUImpl(cpu, cached);
if(cached)
return;
const char* removeStrings[] = {
"(R)", "(r)", "(TM)", "(tm)",
" CPU", " FPU", " APU", " Processor",
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
" with Radeon Graphics"
};
ffStrbufRemoveStringsA(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
ffCacheWrite(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
}
const FFCPUResult* ffDetectCPU(const FFinstance* instance)
{
FF_DETECTION_INTERNAL_GUARD(FFCPUResult,
ffDetectCPUImpl(&result);
const char* removeStrings[] = {
"(R)", "(r)", "(TM)", "(tm)",
" CPU", " FPU", " APU", " Processor",
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
" with Radeon Graphics"
};
ffStrbufRemoveStringsA(&result.name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
ffStrbufSubstrBeforeFirstC(&result.name, '@'); //Cut the speed output in the name as we append our own
ffStrbufTrimRight(&result.name, ' '); //If we removed the @ in previous step there was most likely a space before it
detectCPU(instance, &result);
);
}
+1 -1
View File
@@ -22,6 +22,6 @@ typedef struct FFCPUResult
double temperature;
} FFCPUResult;
const FFCPUResult* ffDetectCPU();
const FFCPUResult* ffDetectCPU(const FFinstance* instance);
#endif
+6 -7
View File
@@ -12,12 +12,14 @@ static double getFrequency(const char* propName)
return herz / 1000.0; //to GHz
}
void ffDetectCPUImpl(FFCPUResult* cpu)
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached)
{
ffStrbufInit(&cpu->name);
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
//TODO find a way to detect this
cpu->temperature = FF_CPU_TEMP_UNSET;
if(cached)
return;
ffStrbufInit(&cpu->vendor);
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1);
@@ -36,7 +38,4 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
cpu->frequencyMax = getFrequency("hw.cpufrequency_max");
if(cpu->frequencyMax == 0.0)
cpu->frequencyMax = getFrequency("hw.cpufrequency");
//TODO find a way to detect this
cpu->temperature = FF_CPU_TEMP_UNSET;
}
+4 -5
View File
@@ -1,11 +1,12 @@
#include "cpu.h"
#include "common/sysctl.h"
void ffDetectCPUImpl(FFCPUResult* cpu)
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached)
{
ffStrbufInitA(&cpu->vendor, 0);
cpu->temperature = FF_CPU_TEMP_UNSET;
if(cached)
return;
ffStrbufInit(&cpu->name);
ffSysctlGetString("hw.model", &cpu->name);
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
@@ -14,6 +15,4 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
cpu->frequencyMin = ffSysctlGetInt("hw.clockrate", 0) / 1000.0;
cpu->frequencyMax = cpu->frequencyMin;
cpu->temperature = FF_CPU_TEMP_UNSET;
}
+5 -6
View File
@@ -62,7 +62,7 @@ static double getFrequency(const char* info, const char* scaling)
static double detectCPUTemp()
{
const FFTempsResult *temps = ffDetectTemps();
const FFTempsResult* temps = ffDetectTemps();
for(uint32_t i = 0; i < temps->values.length; i++)
{
@@ -78,10 +78,11 @@ static double detectCPUTemp()
return FF_CPU_TEMP_UNSET;
}
void ffDetectCPUImpl(FFCPUResult* cpu)
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached)
{
ffStrbufInit(&cpu->name);
ffStrbufInit(&cpu->vendor);
cpu->temperature = detectCPUTemp();
if(cached)
return;
FFstrbuf physicalCoresBuffer;
ffStrbufInit(&physicalCoresBuffer);
@@ -102,7 +103,5 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq");
cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq");
cpu->temperature = detectCPUTemp();
ffStrbufDestroy(&physicalCoresBuffer);
}
+33 -32
View File
@@ -8,10 +8,7 @@
void ffPrintCPU(FFinstance* instance)
{
if(ffPrintFromCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS))
return;
const FFCPUResult* cpu = ffDetectCPU();
const FFCPUResult* cpu = ffDetectCPU(instance);
if(cpu->vendor.length == 0 && cpu->name.length == 0 && cpu->coresOnline <= 1)
{
@@ -19,35 +16,39 @@ void ffPrintCPU(FFinstance* instance)
return;
}
FFstrbuf output;
ffStrbufInitA(&output, 128);
if(cpu->name.length > 0)
ffStrbufAppend(&output, &cpu->name);
else if(cpu->vendor.length > 0)
if(instance->config.cpu.outputFormat.length == 0)
{
ffStrbufAppend(&output, &cpu->vendor);
ffStrbufAppendS(&output, " CPU");
ffPrintLogoAndKey(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu.key);
if(cpu->name.length > 0)
ffStrbufWriteTo(&cpu->name, stdout);
else if(cpu->vendor.length > 0)
{
ffStrbufWriteTo(&cpu->vendor, stdout);
fputs(" CPU", stdout);
}
else
fputs("CPU", stdout);
if(cpu->coresOnline > 1)
printf(" (%u)", cpu->coresOnline);
if(cpu->frequencyMax > 0.0)
printf(" @ %.9g GHz", cpu->frequencyMax);
putchar('\n');
}
else
ffStrbufAppendS(&output, "CPU");
if(cpu->coresOnline > 1)
ffStrbufAppendF(&output, " (%u)", cpu->coresOnline);
if(cpu->frequencyMax > 0.0)
ffStrbufAppendF(&output, " @ %.9gGHz", cpu->frequencyMax);
ffPrintAndWriteToCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpu, &output, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature}
});
ffStrbufDestroy(&output);
{
ffPrintFormat(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature}
});
}
}