Skip to content

Commit d31d157

Browse files
New caching mechanism for CPU
1 parent 07231ff commit d31d157

File tree

8 files changed

+201
-77
lines changed

8 files changed

+201
-77
lines changed

src/common/caching.c

Lines changed: 100 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
#include "common/printing.h"
55

66
#include <stdlib.h>
7+
#include <string.h>
78

89
#define FF_CACHE_VERSION_NAME "cacheversion"
910
#define FF_CACHE_VERSION_EXTENSION "ffv"
1011

1112
#define FF_CACHE_VALUE_EXTENSION "ffcv"
1213
#define FF_CACHE_SPLIT_EXTENSION "ffcs"
1314

14-
#define FF_CACHE_EXTENSION_DATA "ffcd"
15+
#define FF_CACHE_EXTENSION_V1 "ffc1"
1516

1617
static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
1718
{
@@ -211,24 +212,113 @@ void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const
211212
ffCacheClose(&cache);
212213
}
213214

214-
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data)
215+
typedef struct FFCacheRead
215216
{
217+
FFstrbuf data;
218+
uint32_t position;
219+
} FFCacheRead;
220+
221+
static bool cacheReadStrbuf(FFCacheRead* cacheRead, FFstrbuf* strbuf)
222+
{
223+
if(cacheRead->position >= cacheRead->data.length)
224+
return false;
225+
226+
ffStrbufAppendS(strbuf, cacheRead->data.chars + cacheRead->position);
227+
cacheRead->position += strbuf->length + 1; // skip the null byte too
228+
return true;
229+
}
230+
231+
static bool cacheReadData(FFCacheRead* cacheRead, size_t dataSize, void* data)
232+
{
233+
if(cacheRead->position + dataSize > cacheRead->data.length)
234+
return false;
235+
236+
memcpy(data, cacheRead->data.chars + cacheRead->position, dataSize);
237+
cacheRead->position += (uint32_t) dataSize;
238+
return true;
239+
}
240+
241+
static bool cacheResetStrbuf(FFCache* cache, FFstrbuf* strbuf)
242+
{
243+
FF_UNUSED(cache);
244+
ffStrbufClear(strbuf);
245+
return true;
246+
}
247+
248+
static bool cacheResetData(FFCache* cacheRead, size_t dataSize, void* data)
249+
{
250+
FF_UNUSED(cacheRead, dataSize, data);
251+
return true;
252+
}
253+
254+
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
255+
{
256+
if(instance->config.recache)
257+
return false;
258+
259+
FFCacheRead cache;
260+
bool result;
261+
216262
FFstrbuf path;
217263
ffStrbufInitA(&path, 128);
218-
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
219-
ffWriteFileData(path.chars, dataSize, data);
264+
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
265+
266+
cache.position = 0;
267+
268+
ffStrbufInitA(&cache.data, 256);
269+
result = ffAppendFileBuffer(path.chars, &cache.data);
270+
271+
if(result)
272+
result = callback(obj, &cache, (FFCacheMethodStrbuf) cacheReadStrbuf, (FFCacheMethodData) cacheReadData);
273+
274+
if(result)
275+
result = cache.position == cache.data.length;
276+
277+
if(!result)
278+
callback(obj, NULL, (FFCacheMethodStrbuf) cacheResetStrbuf, (FFCacheMethodData) cacheResetData);
279+
280+
ffStrbufDestroy(&cache.data);
220281
ffStrbufDestroy(&path);
282+
283+
return result;
221284
}
222285

223-
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data)
286+
typedef struct FFCacheWrite
224287
{
225-
if(instance->config.recache)
226-
return false;
288+
FFstrbuf data;
289+
} FFCacheWrite;
290+
291+
static bool cacheWriteStrbuf(FFCacheWrite* cacheWrite, FFstrbuf* strbuf)
292+
{
293+
ffStrbufEnsureFree(&cacheWrite->data, strbuf->length);
294+
memcpy(cacheWrite->data.chars + cacheWrite->data.length, strbuf->chars, strbuf->length +1); //Copy the nullbyte too
295+
cacheWrite->data.length += strbuf->length + 1;
296+
return true;
297+
}
298+
299+
static bool cacheWriteData(FFCacheWrite* cacheWrite, size_t dataSize, const void* data)
300+
{
301+
ffStrbufEnsureFree(&cacheWrite->data, (uint32_t) dataSize);
302+
memcpy(cacheWrite->data.chars + cacheWrite->data.length, data, dataSize);
303+
cacheWrite->data.length += (uint32_t) dataSize;
304+
return true;
305+
}
306+
307+
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
308+
{
309+
if(!instance->config.cacheSave)
310+
return;
311+
312+
FFCacheWrite cache;
227313

228314
FFstrbuf path;
229315
ffStrbufInitA(&path, 128);
230-
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
231-
ssize_t result = ffReadFileData(path.chars, dataSize, data);
316+
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
317+
318+
ffStrbufInitA(&cache.data, 256);
319+
callback(obj, &cache, (FFCacheMethodStrbuf) cacheWriteStrbuf, (FFCacheMethodData) cacheWriteData);
320+
ffWriteFileBuffer(path.chars, &cache.data);
321+
322+
ffStrbufDestroy(&cache.data);
232323
ffStrbufDestroy(&path);
233-
return result > 0 && (size_t) result == dataSize;
234324
}

src/common/caching.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModu
2121
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
2222
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
2323

24-
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data);
25-
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data);
24+
typedef void FFCache;
25+
26+
typedef bool(*FFCacheMethodStrbuf)(FFCache* cache, FFstrbuf* strbuf);
27+
typedef bool(*FFCacheMethodData)(FFCache* cache, size_t dataSize, void* data);
28+
typedef bool(*FFCacheMethodCallback)(void* data, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod);
29+
30+
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
31+
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
2632

2733
#endif

src/detection/cpu/cpu.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
11
#include "cpu.h"
2+
#include "common/caching.h"
23
#include "detection/internal.h"
34

4-
void ffDetectCPUImpl(FFCPUResult* cpu);
5+
#define FF_CPU_CACHE_NAME "cpu"
56

6-
const FFCPUResult* ffDetectCPU()
7+
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached);
8+
9+
static bool cacheCallback(FFCPUResult* cpu, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod)
10+
{
11+
return
12+
strbufMethod(cache, &cpu->vendor) &&
13+
strbufMethod(cache, &cpu->name) &&
14+
dataMethod(cache, sizeof(cpu->coresPhysical), &cpu->coresPhysical) &&
15+
dataMethod(cache, sizeof(cpu->coresLogical), &cpu->coresLogical) &&
16+
dataMethod(cache, sizeof(cpu->coresOnline), &cpu->coresOnline) &&
17+
dataMethod(cache, sizeof(cpu->frequencyMin), &cpu->frequencyMin) &&
18+
dataMethod(cache, sizeof(cpu->frequencyMax), &cpu->frequencyMax);
19+
}
20+
21+
static void detectCPU(const FFinstance* instance, FFCPUResult* cpu)
22+
{
23+
ffStrbufInit(&cpu->name);
24+
ffStrbufInit(&cpu->vendor);
25+
26+
bool cached = ffCacheRead(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
27+
28+
ffDetectCPUImpl(cpu, cached);
29+
30+
if(cached)
31+
return;
32+
33+
const char* removeStrings[] = {
34+
"(R)", "(r)", "(TM)", "(tm)",
35+
" CPU", " FPU", " APU", " Processor",
36+
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
37+
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
38+
" with Radeon Graphics"
39+
};
40+
ffStrbufRemoveStringsA(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
41+
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
42+
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
43+
44+
ffCacheWrite(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
45+
}
46+
47+
const FFCPUResult* ffDetectCPU(const FFinstance* instance)
748
{
849
FF_DETECTION_INTERNAL_GUARD(FFCPUResult,
9-
ffDetectCPUImpl(&result);
10-
11-
const char* removeStrings[] = {
12-
"(R)", "(r)", "(TM)", "(tm)",
13-
" CPU", " FPU", " APU", " Processor",
14-
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
15-
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
16-
" with Radeon Graphics"
17-
};
18-
ffStrbufRemoveStringsA(&result.name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
19-
ffStrbufSubstrBeforeFirstC(&result.name, '@'); //Cut the speed output in the name as we append our own
20-
ffStrbufTrimRight(&result.name, ' '); //If we removed the @ in previous step there was most likely a space before it
50+
detectCPU(instance, &result);
2151
);
2252
}

src/detection/cpu/cpu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ typedef struct FFCPUResult
2222
double temperature;
2323
} FFCPUResult;
2424

25-
const FFCPUResult* ffDetectCPU();
25+
const FFCPUResult* ffDetectCPU(const FFinstance* instance);
2626

2727
#endif

src/detection/cpu/cpu_apple.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ static double getFrequency(const char* propName)
1212
return herz / 1000.0; //to GHz
1313
}
1414

15-
void ffDetectCPUImpl(FFCPUResult* cpu)
15+
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached)
1616
{
17-
ffStrbufInit(&cpu->name);
18-
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
17+
//TODO find a way to detect this
18+
cpu->temperature = FF_CPU_TEMP_UNSET;
19+
if(cached)
20+
return;
1921

20-
ffStrbufInit(&cpu->vendor);
22+
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
2123
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
2224

2325
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1);
@@ -36,7 +38,4 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
3638
cpu->frequencyMax = getFrequency("hw.cpufrequency_max");
3739
if(cpu->frequencyMax == 0.0)
3840
cpu->frequencyMax = getFrequency("hw.cpufrequency");
39-
40-
//TODO find a way to detect this
41-
cpu->temperature = FF_CPU_TEMP_UNSET;
4241
}

src/detection/cpu/cpu_bsd.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#include "cpu.h"
22
#include "common/sysctl.h"
33

4-
void ffDetectCPUImpl(FFCPUResult* cpu)
4+
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached)
55
{
6-
ffStrbufInitA(&cpu->vendor, 0);
6+
cpu->temperature = FF_CPU_TEMP_UNSET;
7+
if(cached)
8+
return;
79

8-
ffStrbufInit(&cpu->name);
910
ffSysctlGetString("hw.model", &cpu->name);
1011

1112
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
@@ -14,6 +15,4 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
1415

1516
cpu->frequencyMin = ffSysctlGetInt("hw.clockrate", 0) / 1000.0;
1617
cpu->frequencyMax = cpu->frequencyMin;
17-
18-
cpu->temperature = FF_CPU_TEMP_UNSET;
1918
}

src/detection/cpu/cpu_linux.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static double getFrequency(const char* info, const char* scaling)
6262

6363
static double detectCPUTemp()
6464
{
65-
const FFTempsResult *temps = ffDetectTemps();
65+
const FFTempsResult* temps = ffDetectTemps();
6666

6767
for(uint32_t i = 0; i < temps->values.length; i++)
6868
{
@@ -78,10 +78,11 @@ static double detectCPUTemp()
7878
return FF_CPU_TEMP_UNSET;
7979
}
8080

81-
void ffDetectCPUImpl(FFCPUResult* cpu)
81+
void ffDetectCPUImpl(FFCPUResult* cpu, bool cached)
8282
{
83-
ffStrbufInit(&cpu->name);
84-
ffStrbufInit(&cpu->vendor);
83+
cpu->temperature = detectCPUTemp();
84+
if(cached)
85+
return;
8586

8687
FFstrbuf physicalCoresBuffer;
8788
ffStrbufInit(&physicalCoresBuffer);
@@ -102,7 +103,5 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
102103
cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq");
103104
cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq");
104105

105-
cpu->temperature = detectCPUTemp();
106-
107106
ffStrbufDestroy(&physicalCoresBuffer);
108107
}

src/modules/cpu.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,47 @@
88

99
void ffPrintCPU(FFinstance* instance)
1010
{
11-
if(ffPrintFromCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS))
12-
return;
13-
14-
const FFCPUResult* cpu = ffDetectCPU();
11+
const FFCPUResult* cpu = ffDetectCPU(instance);
1512

1613
if(cpu->vendor.length == 0 && cpu->name.length == 0 && cpu->coresOnline <= 1)
1714
{
1815
ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, "No CPU detected");
1916
return;
2017
}
2118

22-
FFstrbuf output;
23-
ffStrbufInitA(&output, 128);
24-
25-
if(cpu->name.length > 0)
26-
ffStrbufAppend(&output, &cpu->name);
27-
else if(cpu->vendor.length > 0)
19+
if(instance->config.cpu.outputFormat.length == 0)
2820
{
29-
ffStrbufAppend(&output, &cpu->vendor);
30-
ffStrbufAppendS(&output, " CPU");
21+
ffPrintLogoAndKey(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu.key);
22+
23+
if(cpu->name.length > 0)
24+
ffStrbufWriteTo(&cpu->name, stdout);
25+
else if(cpu->vendor.length > 0)
26+
{
27+
ffStrbufWriteTo(&cpu->vendor, stdout);
28+
fputs(" CPU", stdout);
29+
}
30+
else
31+
fputs("CPU", stdout);
32+
33+
if(cpu->coresOnline > 1)
34+
printf(" (%u)", cpu->coresOnline);
35+
36+
if(cpu->frequencyMax > 0.0)
37+
printf(" @ %.9g GHz", cpu->frequencyMax);
38+
39+
putchar('\n');
3140
}
3241
else
33-
ffStrbufAppendS(&output, "CPU");
34-
35-
if(cpu->coresOnline > 1)
36-
ffStrbufAppendF(&output, " (%u)", cpu->coresOnline);
37-
38-
if(cpu->frequencyMax > 0.0)
39-
ffStrbufAppendF(&output, " @ %.9gGHz", cpu->frequencyMax);
40-
41-
ffPrintAndWriteToCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpu, &output, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){
42-
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name},
43-
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor},
44-
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical},
45-
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical},
46-
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline},
47-
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin},
48-
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax},
49-
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature}
50-
});
51-
52-
ffStrbufDestroy(&output);
42+
{
43+
ffPrintFormat(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){
44+
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name},
45+
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor},
46+
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical},
47+
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical},
48+
{FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline},
49+
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin},
50+
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax},
51+
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature}
52+
});
53+
}
5354
}

0 commit comments

Comments
 (0)