Global: removes FFlist::elementSize

Improves performance of module Sound and PhysicalMemory
This commit is contained in:
李通洲
2026-04-14 10:41:18 +08:00
committed by Carter Li
parent ee7f574349
commit c7ecc33b64
170 changed files with 669 additions and 585 deletions
+45 -36
View File
@@ -11,46 +11,49 @@
typedef struct FFlist {
uint8_t* data;
uint32_t elementSize;
uint32_t length;
uint32_t capacity;
} FFlist;
void* ffListAdd(FFlist* list);
void* ffListAdd(FFlist* list, uint32_t elementSize);
// Removes the first element, and copy its value to `*result`
bool ffListShift(FFlist* list, void* result);
bool ffListShift(FFlist* list, uint32_t elementSize, void* result);
// Removes the last element, and copy its value to `*result`
bool ffListPop(FFlist* list, void* result);
bool ffListPop(FFlist* list, uint32_t elementSize, void* result);
static inline void ffListInit(FFlist* list, uint32_t elementSize) {
assert(elementSize > 0);
list->elementSize = elementSize;
static inline void ffListInit(FFlist* list) {
list->capacity = 0;
list->length = 0;
list->data = NULL;
}
static inline void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity) {
ffListInit(list, elementSize);
ffListInit(list);
list->capacity = capacity;
list->data = __builtin_expect(capacity == 0, 0) ? NULL : (uint8_t*) malloc((size_t) list->capacity * list->elementSize);
list->data = __builtin_expect(capacity == 0, 0) ? NULL : (uint8_t*) malloc((size_t) capacity * elementSize);
}
static inline FFlist ffListCreate(uint32_t elementSize) {
FF_A_NODISCARD static inline FFlist ffListCreate() {
FFlist result;
ffListInit(&result, elementSize);
ffListInit(&result);
return result;
}
static inline void* ffListGet(const FFlist* list, uint32_t index) {
assert(list->capacity > index);
return list->data + (index * list->elementSize);
FF_A_NODISCARD static inline FFlist ffListCreateA(uint32_t elementSize, uint32_t capacity) {
FFlist result;
ffListInitA(&result, elementSize, capacity);
return result;
}
FF_A_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool (*compFunc)(const void*, const void*)) {
FF_A_NODISCARD static inline void* ffListGet(const FFlist* list, uint32_t elementSize, uint32_t index) {
assert(list->capacity > index);
return list->data + (index * elementSize);
}
FF_A_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, uint32_t elementSize, void* compElement, bool (*compFunc)(const void*, const void*)) {
for (uint32_t i = 0; i < list->length; i++) {
if (compFunc(ffListGet(list, i), compElement)) {
if (compFunc(ffListGet(list, elementSize, i), compElement)) {
return i;
}
}
@@ -58,24 +61,23 @@ FF_A_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, v
return list->length;
}
static inline bool ffListContains(const FFlist* list, void* compElement, bool (*compFunc)(const void*, const void*)) {
return ffListFirstIndexComp(list, compElement, compFunc) != list->length;
FF_A_NODISCARD static inline bool ffListContains(const FFlist* list, uint32_t elementSize, void* compElement, bool (*compFunc)(const void*, const void*)) {
return ffListFirstIndexComp(list, elementSize, compElement, compFunc) != list->length;
}
static inline void ffListSort(FFlist* list, int (*compar)(const void*, const void*)) {
qsort(list->data, list->length, list->elementSize, compar);
static inline void ffListSort(FFlist* list, uint32_t elementSize, int (*compar)(const void*, const void*)) {
qsort(list->data, list->length, elementSize, compar);
}
// Move the contents of `src` into `list`, and left `src` empty
static inline void ffListInitMove(FFlist* list, FFlist* src) {
if (src) {
list->elementSize = src->elementSize;
list->capacity = src->capacity;
list->length = src->length;
list->data = src->data;
ffListInit(src, list->elementSize);
ffListInit(src);
} else {
ffListInit(list, 0);
ffListInit(list);
}
}
@@ -94,35 +96,29 @@ static inline void ffListClear(FFlist* list) {
list->length = 0;
}
static inline void ffListReserve(FFlist* list, uint32_t newCapacity) {
static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t newCapacity) {
if (__builtin_expect(newCapacity <= list->capacity, false)) {
return;
}
list->data = (uint8_t*) realloc(list->data, (size_t) newCapacity * list->elementSize);
list->data = (uint8_t*) realloc(list->data, (size_t) newCapacity * elementSize);
list->capacity = newCapacity;
}
#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
assert(sizeof(itemType) == (listVar).elementSize); \
for (itemType* itemVarName = (itemType*) (listVar).data; \
itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \
++itemVarName)
#define FF_LIST_AUTO_DESTROY FFlist FF_A_CLEANUP(ffListDestroy)
#define FF_LIST_GET(itemType, listVar, index) \
({ \
assert(sizeof(itemType) == (listVar).elementSize); \
assert((listVar).capacity > (index)); \
(itemType*) (listVar).data + (index); \
#define FF_LIST_GET(itemType, listVar, index) \
({ \
assert((listVar).capacity > (index)); \
(itemType*) (listVar).data + (index); \
})
#define FF_LIST_ADD(itemType, listVar) \
({ \
assert(sizeof(itemType) == (listVar).elementSize); \
(itemType*) ffListAdd(&(listVar)); \
})
#define FF_LIST_ADD(itemType, listVar) (itemType*) ffListAdd(&(listVar), (uint32_t) sizeof(itemType))
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
#define FF_LIST_LAST(itemType, listVar) \
@@ -130,3 +126,16 @@ static inline void ffListReserve(FFlist* list, uint32_t newCapacity) {
assert((listVar).length > 0); \
FF_LIST_GET(itemType, listVar, ((listVar).length - 1)); \
})
#define FF_LIST_CONTAINS(listVar, pCompElement, compFunc) \
({ \
typedef __typeof__(*(pCompElement)) compElementType; \
typedef bool compFuncType(const compElementType*, const compElementType*); \
static_assert(__builtin_types_compatible_p(__typeof__(compFunc), compFuncType), "In compatible callback function"); \
ffListContains(&(listVar), (uint32_t) sizeof(*(pCompElement)), (pCompElement), (bool (*)(const void*, const void*)) compFunc); \
})
#define FF_LIST_SHIFT(listVar, pResult) \
ffListShift(&(listVar), (uint32_t) sizeof(*(pResult)), (pResult))
#define FF_LIST_POP(listVar, pResult) \
ffListPop(&(listVar), (uint32_t) sizeof(*(pResult)), (pResult))
+6 -6
View File
@@ -6,8 +6,8 @@
void ffPlatformInit(FFPlatform* platform) {
ffStrbufInit(&platform->homeDir);
ffStrbufInit(&platform->cacheDir);
ffListInit(&platform->configDirs, sizeof(FFstrbuf));
ffListInit(&platform->dataDirs, sizeof(FFstrbuf));
ffListInit(&platform->configDirs);
ffListInit(&platform->dataDirs);
ffStrbufInit(&platform->exePath);
ffStrbufInit(&platform->cwd);
@@ -77,8 +77,8 @@ void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path) {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(path);
ffStrbufEnsureEndsWithC(&buffer, '/');
if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) {
ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
if (!FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
}
}
@@ -87,7 +87,7 @@ void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char*
ffStrbufAppend(&buffer, &platform->homeDir);
ffStrbufAppendS(&buffer, suffix);
ffStrbufEnsureEndsWithC(&buffer, '/');
if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) {
ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
}
}
+4 -4
View File
@@ -77,8 +77,8 @@ static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
CoTaskMemFree(pPath);
ffStrbufReplaceAllC(&buffer, '\\', '/');
ffStrbufEnsureEndsWithC(&buffer, '/');
if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) {
ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
if (!FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
}
}
}
@@ -98,8 +98,8 @@ static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char*
ffStrbufEnsureEndsWithC(&buffer, '/');
}
if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) {
ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
}
}
+8 -8
View File
@@ -3,32 +3,32 @@
#include <stdlib.h>
#include <string.h>
void* ffListAdd(FFlist* list) {
void* ffListAdd(FFlist* list, uint32_t elementSize) {
if (list->length == list->capacity) {
ffListReserve(list, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
}
++list->length;
return ffListGet(list, list->length - 1);
return ffListGet(list, elementSize, list->length - 1);
}
bool ffListShift(FFlist* list, void* result) {
bool ffListShift(FFlist* list, uint32_t elementSize, void* result) {
if (list->length == 0) {
return false;
}
memcpy(result, list->data, list->elementSize);
memmove(list->data, list->data + list->elementSize, (size_t) list->elementSize * (list->length - 1));
memcpy(result, list->data, elementSize);
memmove(list->data, list->data + elementSize, (size_t) elementSize * (list->length - 1));
--list->length;
return true;
}
bool ffListPop(FFlist* list, void* result) {
bool ffListPop(FFlist* list, uint32_t elementSize, void* result) {
if (list->length == 0) {
return false;
}
memcpy(result, ffListGet(list, list->length - 1), list->elementSize);
memcpy(result, ffListGet(list, elementSize, list->length - 1), elementSize);
--list->length;
return true;
}
+4 -4
View File
@@ -12,7 +12,7 @@ void ffFontInit(FFfont* font) {
ffStrbufInit(&font->pretty);
ffStrbufInit(&font->name);
ffStrbufInit(&font->size);
ffListInit(&font->styles, sizeof(FFstrbuf));
ffListInit(&font->styles);
}
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude) {
@@ -93,7 +93,7 @@ void ffFontInitQt(FFfont* font, const char* data) {
data++;
if (isalpha(*data)) {
do {
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
if (data) {
@@ -152,7 +152,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
ffStrStartsWithIgnCase(wordStart, "Condensed") ||
ffStrStartsWithIgnCase(wordStart, "Expanded")) {
if (alternativeBuffer == NULL) {
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
alternativeBuffer = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInit(alternativeBuffer);
}
@@ -271,7 +271,7 @@ void ffFontInitXlfd(FFfont* font, const char* xlfd) {
{
// ignore "normal" (case-insensitive)
if (!(length == 6 && ffStrStartsWithIgnCase(pstart, "normal"))) {
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInitNS(style, length, pstart);
}
}
+11 -12
View File
@@ -232,18 +232,17 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
if (!ffAppendFileBuffer("/sys/firmware/dmi/tables/DMI", &buffer))
# elif defined(__OpenBSD__)
{
FF_DEBUG("Using OpenBSD /var/run/dmesg.boot implementation");
char dmesg[8192];
ssize_t size = ffReadFileData("/var/run/dmesg.boot", sizeof(dmesg), dmesg);
if (size <= 0) {
goto fallback;
}
char* line = memmem(dmesg, sizeof(dmesg), "\nbios0 at mainbios0: SMBIOS rev. ", strlen("\nbios0 at mainbios0: SMBIOS rev. "));
if (!line) {
goto fallback;
}
line += strlen("\nbios0 at mainbios0: SMBIOS rev. ");
FF_DEBUG("Using OpenBSD /var/run/dmesg.boot implementation");
char dmesg[8192];
ssize_t size = ffReadFileData("/var/run/dmesg.boot", sizeof(dmesg), dmesg);
if (size <= 0) {
goto fallback;
}
char* line = memmem(dmesg, sizeof(dmesg), "\nbios0 at mainbios0: SMBIOS rev. ", strlen("\nbios0 at mainbios0: SMBIOS rev. "));
if (!line) {
goto fallback;
}
line += strlen("\nbios0 at mainbios0: SMBIOS rev. ");
}
# endif
{
-8
View File
@@ -178,14 +178,6 @@ static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const
}
FFlist* list = (FFlist*) arg->value;
if (list->elementSize != sizeof(FFstrbuf)) {
if (error) {
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: expected list of strbuf for REG_MULTI_SZ", nameA.chars);
}
return false;
}
ffListClear(list);
for (