From 749dba1ce8883b3d438d969b736633b3b79cf5cc Mon Sep 17 00:00:00 2001 From: nova Date: Thu, 14 May 2026 18:50:36 +0200 Subject: [PATCH] yet another change to the rendering pipeline --- main.c | 37 ++----------------------------------- threading.c | 38 +++++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/main.c b/main.c index 527e337..1694d80 100644 --- a/main.c +++ b/main.c @@ -160,43 +160,10 @@ void render_pass(){ mvwin(win_b, terminal_height-1, 0); } - /* render_queue is modified both by this and its associated thread without mutexes, this is intentional. - * reason being that since rendering is done in the same thread as the logic, - * using mutexes actually slows this down more than the result of an unknown state. - * an unknown state may be an incomplete render, which in my tests wont crash, or one too many renders. - * both of these chances are non distructive. - * doing rendering async is done because - * A: its funny - * B: previous render pipelines may have caused win_r to lack behind - * C: slowdown as a result of too many renders */ - if (render_queue[RENDER_QUEUE_TOP] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) { - wnoutrefresh(win_t); - render_queue[RENDER_QUEUE_TOP] = 0; - status |= STATUS_UPDATE_ASYNC_REFRESH; - } - if (render_queue[RENDER_QUEUE_LFT] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) { - wnoutrefresh(win_l); - render_queue[RENDER_QUEUE_LFT] = 0; - status |= STATUS_UPDATE_ASYNC_REFRESH; - } - if (render_queue[RENDER_QUEUE_MID] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) { - wnoutrefresh(win_m); - render_queue[RENDER_QUEUE_MID] = 0; - status |= STATUS_UPDATE_ASYNC_REFRESH; - } - if (render_queue[RENDER_QUEUE_RGT] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) { - wnoutrefresh(win_r); - render_queue[RENDER_QUEUE_RGT] = 0; - status |= STATUS_UPDATE_ASYNC_REFRESH; - } - if (render_queue[RENDER_QUEUE_BTM] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) { - wnoutrefresh(win_b); - render_queue[RENDER_QUEUE_BTM] = 0; - status |= STATUS_UPDATE_ASYNC_REFRESH; - } - if (status & STATUS_UPDATE_SCREEN_MASK) { + if (pthread_mutex_lock(&mutex_render) == 0 || status & STATUS_UPDATE_SCREEN_MASK) { doupdate(); status &= ~STATUS_UPDATE_SCREEN_MASK; + pthread_mutex_unlock(&mutex_render); } } /*this function exists for things done at startup (initialization, reading config, etc)*/ diff --git a/threading.c b/threading.c index 46364b4..e958c60 100644 --- a/threading.c +++ b/threading.c @@ -18,7 +18,7 @@ pthread_mutex_t mutex_btm; pthread_mutex_t mutex_lft; pthread_mutex_t mutex_mid; pthread_mutex_t mutex_rgt; -pthread_mutex_t mutex_selection; +pthread_mutex_t mutex_render; pthread_cond_t cond_mid; pthread_cond_t cond_rgt; pthread_cond_t cond_lft; @@ -46,7 +46,6 @@ unsigned long top_width; extern unsigned int terminal_width; extern unsigned int status; -volatile char render_queue[RENDER_QUEUE_BTM+1]; extern char *global_path; unsigned int btm_status; @@ -104,18 +103,19 @@ void *thread_mid(){ } /* rendering */ - render_queue[RENDER_QUEUE_MID] = 0; + pthread_mutex_lock(&mutex_render); werase(win_m); if (mid_dir.file_count == 0) { mvwaddstr(win_m, 0, 0, "empty"); } else { print_dir(win_m, 1, &mid_dir); } - render_queue[RENDER_QUEUE_MID] = 1; + wnoutrefresh(win_m); + pthread_mutex_unlock(&mutex_render); - pthread_cond_signal(&cond_rgt); pthread_cond_signal(&cond_top); pthread_cond_signal(&cond_btm); + pthread_cond_signal(&cond_rgt); pthread_mutex_unlock(&mutex_mid); @@ -149,7 +149,6 @@ void *thread_lft(){ char *path = malloc(strlen(global_path)+1); memcpy(path, global_path, strlen(global_path)+1); - render_queue[RENDER_QUEUE_LFT] = 0; if (strcmp(path, "/") != 0) { path[strrchr(path, '/')-path+1] = '\0'; path[strrchr(path, '/')-path] = '\0'; @@ -176,14 +175,15 @@ void *thread_lft(){ } /* rendering */ + pthread_mutex_lock(&mutex_render); werase(win_l); print_dir(win_l, 0, &lft_dir); - render_queue[RENDER_QUEUE_LFT] = 1; + wnoutrefresh(win_l); + pthread_mutex_unlock(&mutex_render); pthread_mutex_unlock(&mutex_lft); free(path); - pthread_mutex_unlock(&mutex_lft); } pthread_exit(0); @@ -214,7 +214,6 @@ void *thread_rgt(){ pthread_mutex_unlock(&mutex_mid); - render_queue[RENDER_QUEUE_RGT] = 0; werase(win_r); if (rgt_dir.current_file->permissions & S_IRUSR) { if (rgt_dir.current_file->file_type &= FILE_TYPE_DIR) { @@ -231,22 +230,27 @@ void *thread_rgt(){ } else { /* the hovered dir is empty */ rgt_dir.current_file = NULL; } + pthread_mutex_lock(&mutex_render); print_dir(win_r, 0, &rgt_dir); + wnoutrefresh(win_r); + pthread_mutex_unlock(&mutex_render); } else if ((status & STATUS_DELTA_TIME) != STATUS_DELTA_TIME && rgt_dir.file_count > 0) { free(rgt_buffer); rgt_buffer = preview_file(rgt_dir.current_file); rgt_dir.current_file->file_type |= FILE_TYPE_OPEN_FILE; + pthread_mutex_lock(&mutex_render); if (rgt_dir.current_file->file_type == FILE_TYPE_OPEN_FILE) { mvwaddnstr(win_r, 0, 0, rgt_buffer, (terminal_width/2) * terminal_width); } else if ((rgt_dir.current_file->permissions & S_IRUSR) == 0) { mvwaddstr(win_r, 0, 0, "not accessible"); } + wnoutrefresh(win_r); + pthread_mutex_unlock(&mutex_render); } } - render_queue[RENDER_QUEUE_RGT] = 1; pthread_mutex_unlock(&mutex_rgt); unsigned long i; @@ -268,7 +272,6 @@ void *thread_top(){ pthread_cond_wait(&cond_top, &mutex_top); - render_queue[RENDER_QUEUE_TOP] = 0; free(top_buffer); if(global_path == NULL) { @@ -284,6 +287,8 @@ void *thread_top(){ /* rendering */ + pthread_mutex_lock(&mutex_mid); + pthread_mutex_lock(&mutex_render); werase(win_t); if (*top_buffer != ' ') { /*printing ' ' (standard initialized value, see threading_init) makes valgrind throw a fuss*/ wattron(win_t, COLOR_PAIR(COLOR_PATH)); @@ -294,7 +299,9 @@ void *thread_top(){ mvwaddstr(win_t, 0, strlen(top_buffer)+1, mid_dir.current_file->file_name); } } - render_queue[RENDER_QUEUE_TOP] = 1; + wnoutrefresh(win_t); + pthread_mutex_unlock(&mutex_render); + pthread_mutex_unlock(&mutex_mid); pthread_mutex_unlock(&mutex_top); @@ -312,7 +319,6 @@ void *thread_btm(){ pthread_cond_wait(&cond_btm, &mutex_btm); unsigned int local_status = btm_status; - render_queue[RENDER_QUEUE_BTM] = 0; if (local_status & (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY)) { /*{{{ parse storage info; the fold of shame*/ @@ -410,11 +416,13 @@ void *thread_btm(){ /* rendering */ + pthread_mutex_lock(&mutex_render); werase(win_b); if (*top_buffer != ' ') { /*printing ' ' (standard initialized value, see threading_init) makes valgrind throw a fuss*/ mvwprintw(win_b, 0, 0, "%s", btm_buffer); } - render_queue[RENDER_QUEUE_BTM] = 1; + wnoutrefresh(win_b); + pthread_mutex_unlock(&mutex_render); pthread_mutex_unlock(&mutex_btm); /*the printing of all possible inputs are done in user_interactions */ @@ -439,7 +447,7 @@ void threading_init(){ pthread_mutex_init(&mutex_lft, NULL); pthread_mutex_init(&mutex_btm, NULL); pthread_mutex_init(&mutex_rgt, NULL); - pthread_mutex_init(&mutex_selection, NULL); + pthread_mutex_init(&mutex_render, NULL); pthread_cond_init(&cond_rgt, NULL); pthread_cond_init(&cond_lft, NULL); pthread_cond_init(&cond_mid, NULL);