diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c642658f..338c2bd6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.1.0) # Threads::Threads is needed project(fastfetch) @@ -19,16 +19,21 @@ execute_process( set(PROJECT_VERSION "r${GIT_REV_LIST}.${GIT_REV_PARSE}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAFS} -Wall -O3") + if(BUILD_TESTS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -march=native -O3 -pipe -fno-plt") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -pipe -fno-plt") endif(BUILD_TESTS) configure_file(src/fastfetch_config.h.in fastfetch_config.h) -find_package (PkgConfig QUIET) +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +find_package (PkgConfig) if(${PkgConfig_FOUND}) - pkg_check_modules (GLIB2 QUIET glib-2.0) + pkg_check_modules (GLIB2 glib-2.0) endif(${PkgConfig_FOUND}) if(NOT DEFINED GLIB2_INCLUDE_DIRS) @@ -88,6 +93,7 @@ add_executable(fastfetch target_link_libraries(fastfetch ${CMAKE_DL_LIBS} + Threads::Threads ) add_executable(flashfetch @@ -101,6 +107,7 @@ target_compile_definitions(flashfetch PUBLIC target_link_libraries(flashfetch ${CMAKE_DL_LIBS} + Threads::Threads ) if(BUILD_TESTS) @@ -111,5 +118,6 @@ if(BUILD_TESTS) target_link_libraries(fastfetch-test-performance ${CMAKE_DL_LIBS} + Threads::Threads ) endif(BUILD_TESTS) diff --git a/completions/bash b/completions/bash index 1b02c866d..71585e046 100644 --- a/completions/bash +++ b/completions/bash @@ -114,6 +114,7 @@ __fastfetch_completion() "--show-errors" "--color-logo" "--print-remaining-logo" + "--multithreading" ) local FF_OPTIONS_STRING=( diff --git a/src/common.c b/src/common.c index 2127f77ed..6b586627d 100644 --- a/src/common.c +++ b/src/common.c @@ -6,6 +6,7 @@ #include #include #include +#include void ffInitState(FFstate* state) { @@ -80,6 +81,69 @@ void ffDefaultConfig(FFconfig* config) ffStrbufInitA(&config->diskFolders, 1); } +static inline void* calculatePlasmaThreadMain(void* instance) +{ + ffCalculatePlasma((FFinstance*)instance, NULL, NULL, NULL); + return NULL; +} + +static inline void* calculateGTK2ThreadMain(void* instance) +{ + ffCalculateGTK2((FFinstance*)instance, NULL, NULL, NULL); + return NULL; +} + +static inline void* calculateGTK3ThreadMain(void* instance) +{ + ffCalculateGTK3((FFinstance*)instance, NULL, NULL, NULL); + return NULL; +} + +static inline void* calculateGTK4ThreadMain(void* instance) +{ + ffCalculateGTK4((FFinstance*)instance, NULL, NULL, NULL); + return NULL; +} + +static inline void* calculateWMThreadMain(void* instance) +{ + ffCalculateWM((FFinstance*)instance, NULL, NULL, NULL); + return NULL; +} + +static inline void* calculateTerminalThreadMain(void* instance) +{ + ffCalculateTerminal((FFinstance*)instance, NULL, NULL, NULL); + return NULL; +} + +void ffStartCalculationThreads(FFinstance* instance) +{ + pthread_t wmThread; + pthread_create(&wmThread, NULL, calculateWMThreadMain, instance); + pthread_detach(wmThread); + + pthread_t gtk2Thread; + pthread_create(>k2Thread, NULL, calculateGTK2ThreadMain, instance); + pthread_detach(gtk2Thread); + + pthread_t gtk3Thread; + pthread_create(>k3Thread, NULL, calculateGTK3ThreadMain, instance); + pthread_detach(gtk3Thread); + + pthread_t gtk4Thread; + pthread_create(>k4Thread, NULL, calculateGTK4ThreadMain, instance); + pthread_detach(gtk4Thread); + + pthread_t terminalThread; + pthread_create(&terminalThread, NULL, calculateTerminalThreadMain, instance); + pthread_detach(terminalThread); + + pthread_t plasmaThread; + pthread_create(&plasmaThread, NULL, calculatePlasmaThreadMain, instance); + pthread_detach(plasmaThread); +} + static void ffCleanup(FFinstance* instance) { // Place for cleaning up diff --git a/src/fastfetch.c b/src/fastfetch.c index 7640b25a0..fa8f56c6a 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -26,6 +26,7 @@ typedef struct FFdata FFvaluestore valuestore; FFstrbuf structure; FFstrbuf logoName; + bool multithreading; } FFdata; static inline void printHelp() @@ -53,6 +54,7 @@ static inline void printHelp() " --show-errors : print occuring errors\n" " -r --recache : if set to true, no cached values will be used\n" " --print-remaining-logo : print the remaining logo, if it is higher than the number of lines shown\n" + " --multithreading : use multiple threads to calculate values\n" "\n" "Logo options:\n" " -l , --logo : sets the shown logo. Also changes the main color accordingly\n" @@ -433,6 +435,7 @@ static inline bool optionParseBoolean(const char* str) return ( strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0 || + strcasecmp(str, "on") == 0 || strcasecmp(str, "1") == 0 ); } @@ -547,6 +550,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.colorLogo = optionParseBoolean(value); else if(strcasecmp(key, "--print-remaining-logo") == 0) instance->config.printRemainingLogo = optionParseBoolean(value); + else if(strcasecmp(key, "--multithreading") == 0) + data->multithreading = optionParseBoolean(value); else if(strcasecmp(key, "--structure") == 0) optionParseString(key, value, &data->structure); else if(strcasecmp(key, "-l") == 0 || strcasecmp(key, "--logo") == 0) @@ -850,6 +855,9 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char static void run(FFinstance* instance, FFdata* data) { + if(data->multithreading) + ffStartCalculationThreads(instance); + if(data->structure.length == 0) ffStrbufSetS(&data->structure, FASTFETCH_DEFAULT_STRUCTURE); @@ -863,6 +871,16 @@ static void run(FFinstance* instance, FFdata* data) lastIndex = colonIndex + 1; } + + ffFinish(instance); +} + +static void initData(FFdata* data) +{ + ffValuestoreInit(&data->valuestore); + ffStrbufInitA(&data->structure, 256); + ffStrbufInit(&data->logoName); + data->multithreading = true; } int main(int argc, const char** argv) @@ -872,19 +890,11 @@ int main(int argc, const char** argv) ffDefaultConfig(&instance.config); FFdata data; - ffValuestoreInit(&data.valuestore); - ffStrbufInitA(&data.structure, 256); - ffStrbufInit(&data.logoName); + initData(&data); parseConfigFile(&instance, &data); parseArguments(&instance, &data, argc, argv); applyData(&instance, &data); //Here we do things that need to be done after parsing all options run(&instance, &data); - - ffFinish(&instance); - - ffStrbufDestroy(&data.structure); - ffStrbufDestroy(&data.logoName); - ffValuestoreDelete(&data.valuestore); } diff --git a/src/fastfetch.h b/src/fastfetch.h index 50f015361..79dc598f8 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -131,6 +131,7 @@ typedef struct FFformatarg //Common functions void ffInitState(FFstate* state); void ffDefaultConfig(FFconfig* config); +void ffStartCalculationThreads(FFinstance* instance); void ffPrintKey(FFinstance* instance, FFstrbuf* customKey, const char* defKey); void ffPrintLogoAndKey(FFinstance* instance, FFstrbuf* customKey, const char* defKey); void ffPrintError(FFinstance* instance, FFstrbuf* customKey, const char* defKey, const char* message, ...); diff --git a/src/flashfetch.c b/src/flashfetch.c index 1153d322b..63b3310a2 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -10,6 +10,9 @@ int main(int argc, char** argv) ffLoadLogoSet(&instance.config, "arch"); ffStrbufSetS(&instance.config.color, instance.config.logo.color); //Use the primary color of the logo as key color + //Multithreading --> better performance + ffStartCalculationThreads(&instance); + //Printing ffPrintTitle(&instance); ffPrintSeperator(&instance); diff --git a/src/helpers/calculateGtk.c b/src/helpers/calculateGtk.c index fba4654c4..788053aee 100644 --- a/src/helpers/calculateGtk.c +++ b/src/helpers/calculateGtk.c @@ -2,6 +2,7 @@ #include "dconf/client/dconf-client.h" #include "dlfcn.h" +#include static inline bool allPropertiesSet(FFstrbuf* themeNamePtr, FFstrbuf* iconsNamePtr, FFstrbuf* fontNamePtr) { @@ -13,16 +14,22 @@ static inline bool allPropertiesSet(FFstrbuf* themeNamePtr, FFstrbuf* iconsNameP static void parseGTKDConfSettings(FFinstance* instance, FFstrbuf* themeNamePtr, FFstrbuf* iconsNamePtr, FFstrbuf* fontNamePtr) { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static const gchar* themeName; static const gchar* iconsName; static const gchar* fontName; static bool init = false; + + pthread_mutex_lock(&mutex); + if(init) { ffStrbufAppendS(themeNamePtr, themeName); ffStrbufAppendS(iconsNamePtr, iconsName); ffStrbufAppendS(fontNamePtr, fontName); + pthread_mutex_unlock(&mutex); return; } init = true; @@ -81,6 +88,8 @@ static void parseGTKDConfSettings(FFinstance* instance, FFstrbuf* themeNamePtr, ffStrbufAppendS(themeNamePtr, themeName); ffStrbufAppendS(iconsNamePtr, iconsName); ffStrbufAppendS(fontNamePtr, fontName); + + pthread_mutex_unlock(&mutex); } static void parseGTKConfigFile(FFstrbuf* fileName, FFstrbuf* themeNamePtr, FFstrbuf* iconsNamePtr, FFstrbuf* fontNamePtr) @@ -249,19 +258,28 @@ static void calculateGTK(FFinstance* instance, const char* version, FFstrbuf* th } #define FF_CALCULATE_GTK_IMPL(version) \ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \ static FFstrbuf themeName; \ static FFstrbuf iconsName; \ static FFstrbuf fontName; \ - if(themeNamePtr != NULL) *themeNamePtr = &themeName; \ - if(iconsNamePtr != NULL) *iconsNamePtr = &iconsName; \ - if(fontNamePtr != NULL) *fontNamePtr = &fontName; \ static bool init = false; \ - if(init) return; \ + if(themeNamePtr != NULL) \ + *themeNamePtr = &themeName; \ + if(iconsNamePtr != NULL) \ + *iconsNamePtr = &iconsName; \ + if(fontNamePtr != NULL) \ + *fontNamePtr = &fontName; \ + pthread_mutex_lock(&mutex); \ + if(init){ \ + pthread_mutex_unlock(&mutex);\ + return; \ + } \ init = true; \ ffStrbufInit(&themeName); \ ffStrbufInit(&iconsName); \ ffStrbufInit(&fontName); \ - calculateGTK(instance, #version, &themeName, &iconsName, &fontName); + calculateGTK(instance, #version, &themeName, &iconsName, &fontName); \ + pthread_mutex_unlock(&mutex); void ffCalculateGTK2(FFinstance* instance, FFstrbuf** themeNamePtr, FFstrbuf** iconsNamePtr, FFstrbuf** fontNamePtr) { diff --git a/src/helpers/calculatePlasma.c b/src/helpers/calculatePlasma.c index 0ba8c422e..c6eaee637 100644 --- a/src/helpers/calculatePlasma.c +++ b/src/helpers/calculatePlasma.c @@ -1,10 +1,15 @@ #include "fastfetch.h" +#include + void ffCalculatePlasma(FFinstance* instance, FFstrbuf** themeNamePtr, FFstrbuf** iconsNamePtr, FFstrbuf** fontNamePtr) { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFstrbuf themeName; static FFstrbuf iconsName; static FFstrbuf fontName; + static bool init = false; if(themeNamePtr != NULL) *themeNamePtr = &themeName; @@ -15,9 +20,14 @@ void ffCalculatePlasma(FFinstance* instance, FFstrbuf** themeNamePtr, FFstrbuf** if(fontNamePtr != NULL) *fontNamePtr = &fontName; - static bool init = false; + pthread_mutex_lock(&mutex); + if(init) + { + pthread_mutex_unlock(&mutex); return; + } + init = true; ffStrbufInit(&themeName); @@ -64,4 +74,6 @@ void ffCalculatePlasma(FFinstance* instance, FFstrbuf** themeNamePtr, FFstrbuf** //So the pure existence of the file sets this font value if not set other in the file itself. if(fontName.length == 0) ffStrbufAppendS(&fontName, "Noto Sans, 10"); + + pthread_mutex_unlock(&mutex); } diff --git a/src/helpers/calculateTerminal.c b/src/helpers/calculateTerminal.c index 479e0e490..a98a89e31 100644 --- a/src/helpers/calculateTerminal.c +++ b/src/helpers/calculateTerminal.c @@ -1,5 +1,7 @@ #include "fastfetch.h" +#include + static void getTerminalName(FFinstance* instance, const char* pid, FFstrbuf* exeName, FFstrbuf* processName, FFstrbuf* error) { char statFile[234]; @@ -49,6 +51,8 @@ static void getTerminalName(FFinstance* instance, const char* pid, FFstrbuf* exe void ffCalculateTerminal(FFinstance* instance, FFstrbuf** exeNamePtr, FFstrbuf** processNamePtr, FFstrbuf** errorPtr) { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFstrbuf exeName; static FFstrbuf processName; static FFstrbuf error; @@ -63,8 +67,13 @@ void ffCalculateTerminal(FFinstance* instance, FFstrbuf** exeNamePtr, FFstrbuf** if(errorPtr != NULL) *errorPtr = &error; + pthread_mutex_lock(&mutex); + if(init) + { + pthread_mutex_unlock(&mutex); return; + } init = true; ffStrbufInit(&exeName); @@ -76,4 +85,5 @@ void ffCalculateTerminal(FFinstance* instance, FFstrbuf** exeNamePtr, FFstrbuf** getTerminalName(instance, ppid, &exeName, &processName, &error); + pthread_mutex_unlock(&mutex); } diff --git a/src/helpers/calculateWM.c b/src/helpers/calculateWM.c index 4545f227f..f0086fa58 100644 --- a/src/helpers/calculateWM.c +++ b/src/helpers/calculateWM.c @@ -1,9 +1,12 @@ #include "fastfetch.h" #include +#include void ffCalculateWM(FFinstance* instance, FFstrbuf** prettyNamePtr, FFstrbuf** processNamePtr, FFstrbuf** errorPtr) { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFstrbuf prettyName; static FFstrbuf processName; static FFstrbuf error; @@ -18,8 +21,14 @@ void ffCalculateWM(FFinstance* instance, FFstrbuf** prettyNamePtr, FFstrbuf** pr if(errorPtr != NULL) *errorPtr = &error; + pthread_mutex_lock(&mutex); + if(init) + { + pthread_mutex_unlock(&mutex); return; + } + init = true; ffStrbufInit(&prettyName); @@ -59,4 +68,6 @@ void ffCalculateWM(FFinstance* instance, FFstrbuf** prettyNamePtr, FFstrbuf** pr ffStrbufSetS(&error, "No process name matches the name of known display managers"); return; } + + pthread_mutex_unlock(&mutex); } diff --git a/tests/performance.c b/tests/performance.c index 2d1c4a5c0..ac61487b2 100644 --- a/tests/performance.c +++ b/tests/performance.c @@ -33,6 +33,11 @@ int main(int argc, char** argv) instance.config.cacheSave = false; ) + FASTFETCH_TEST_PERFORMANCE( + puts("Thread starting"); + ffStartCalculationThreads(&instance); + ) + FASTFETCH_TEST_PERFORMANCE(ffPrintTitle(&instance)) FASTFETCH_TEST_PERFORMANCE(ffPrintSeperator(&instance)) FASTFETCH_TEST_PERFORMANCE(ffPrintOS(&instance))