From a0b24c550577e6c40e17d03529da6a89a71d4cfb Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Tue, 27 May 2008 11:17:51 +0200 Subject: [PATCH] [statusbar] Implement multi-threading per statusbar More more efficient than before. Signed-off-by: Julien Danjou --- awesome.c | 21 +++------------------ statusbar.c | 51 +++++++++++++++++++++++++++++++++++++-------------- statusbar.h | 3 +-- structs.h | 9 ++++++++- widget.c | 4 ++-- 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/awesome.c b/awesome.c index fa9a62329..e172da640 100644 --- a/awesome.c +++ b/awesome.c @@ -34,8 +34,6 @@ #include #include -#include - #include #include @@ -49,7 +47,6 @@ #include "event.h" #include "layout.h" #include "screen.h" -#include "statusbar.h" #include "window.h" #include "client.h" #include "focus.h" @@ -65,12 +62,6 @@ bool running = true; awesome_t globalconf; -#define a_thread_refresh(id, fct) \ - do { \ - if(pthread_create(id, NULL, fct, NULL)) \ - perror("error creating thread\n"); \ - } while(0) - typedef struct { xcb_window_t id; @@ -294,7 +285,6 @@ main(int argc, char **argv) xcb_generic_event_t *ev; struct sockaddr_un *addr; client_t *c; - pthread_t tid_statusbar; static struct option long_options[] = { {"help", 0, NULL, 'h'}, @@ -341,6 +331,9 @@ main(int argc, char **argv) /* Text won't be printed correctly otherwise */ setlocale(LC_CTYPE, ""); + /* initialize Glib for thread safeness */ + g_thread_init(NULL); + /* X stuff */ globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); if(xcb_connection_has_error(globalconf.connection)) @@ -483,12 +476,8 @@ main(int argc, char **argv) signal(SIGHUP, &exit_on_signal); /* refresh everything before waiting events */ - statusbar_refresh(NULL); layout_refresh(); - /* initialize Glib for thread safeness */ - g_thread_init(NULL); - /* main event loop, also reads status text from socket */ while(running) { @@ -540,16 +529,12 @@ main(int argc, char **argv) p_delete(&ev); } while((ev = xcb_poll_for_event(globalconf.connection))); - a_thread_refresh(&tid_statusbar, &statusbar_refresh); layout_refresh(); - pthread_join(tid_statusbar, NULL); /* need to resync */ xcb_aux_sync(globalconf.connection); } - a_thread_refresh(&tid_statusbar, &statusbar_refresh); layout_refresh(); - pthread_join(tid_statusbar, NULL); xcb_aux_sync(globalconf.connection); } diff --git a/statusbar.c b/statusbar.c index 77bc07c3e..900e93669 100644 --- a/statusbar.c +++ b/statusbar.c @@ -21,6 +21,9 @@ #include #include + +#include + #include #include @@ -31,6 +34,7 @@ #include "window.h" extern awesome_t globalconf; +extern bool running; static void statusbar_draw(statusbar_t *statusbar) @@ -39,7 +43,7 @@ statusbar_draw(statusbar_t *statusbar) int left = 0, right = 0; area_t rectangle = { 0, 0, 0, 0, NULL, NULL }; - statusbar->need_update = false; + statusbar->need_update.value = false; if(!statusbar->position) return; @@ -81,6 +85,25 @@ statusbar_draw(statusbar_t *statusbar) simplewindow_refresh_drawable(statusbar->sw); } +static void * +statusbar_refresh(void *p) +{ + statusbar_t *statusbar = (statusbar_t *) p; + + while(running) + { + pthread_mutex_lock(&statusbar->need_update.lock); + + while(!statusbar->need_update.value) + pthread_cond_wait(&statusbar->need_update.cond, &statusbar->need_update.lock); + + statusbar_draw(statusbar); + pthread_mutex_unlock(&statusbar->need_update.lock); + } + + return NULL; +} + static void statusbar_position_update(statusbar_t *statusbar, position_t position) { @@ -276,19 +299,13 @@ statusbar_position_update(statusbar_t *statusbar, position_t position) statusbar_draw(statusbar); } -void * -statusbar_refresh(void *p __attribute__ ((unused))) +void +statusbar_needupdate(statusbar_t *statusbar) { - int screen; - statusbar_t *statusbar; - - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) - for(statusbar = globalconf.screens[screen].statusbar; - statusbar; - statusbar = statusbar->next) - if(statusbar->need_update) - statusbar_draw(statusbar); - return NULL; + pthread_mutex_lock(&statusbar->need_update.lock); + statusbar->need_update.value = true; + pthread_mutex_unlock(&statusbar->need_update.lock); + pthread_cond_broadcast(&statusbar->need_update.cond); } statusbar_t * @@ -357,7 +374,7 @@ luaA_statusbar_widget_add(lua_State *L) widget_t **widget = luaL_checkudata(L, 2, "widget"); widget_node_t *w = p_new(widget_node_t, 1); - (*sb)->need_update = true; + statusbar_needupdate(*sb); w->widget = *widget; widget_node_list_append(&(*sb)->widgets, w); widget_ref(widget); @@ -394,6 +411,12 @@ luaA_statusbar_add(lua_State *L) (*sb)->screen = screen; (*sb)->phys_screen = screen_virttophys(screen); + /* Initialize thread stuffs and start it */ + pthread_cond_init(&(*sb)->need_update.cond, NULL); + pthread_mutex_init(&(*sb)->need_update.lock, NULL); + if(pthread_create(&(*sb)->tid, NULL, statusbar_refresh, *sb)) + perror("unable to create thread"); + return 0; } diff --git a/statusbar.h b/statusbar.h index a1ab23dca..505d53603 100644 --- a/statusbar.h +++ b/statusbar.h @@ -23,7 +23,6 @@ #define AWESOME_STATUSBAR_H #include "structs.h" -#include "widget.h" #include "common/refcount.h" #include "common/swindow.h" @@ -36,8 +35,8 @@ statusbar_delete(statusbar_t **statusbar) p_delete(statusbar); } -void * statusbar_refresh(void *); statusbar_t * statusbar_getbyname(int, const char *); +void statusbar_needupdate(statusbar_t *); DO_RCNT(statusbar_t, statusbar, statusbar_delete) DO_SLIST(statusbar_t, statusbar, statusbar_delete) diff --git a/structs.h b/structs.h index 4e66b710c..727bfe0ec 100644 --- a/structs.h +++ b/structs.h @@ -211,7 +211,14 @@ struct statusbar_t /** Draw context */ draw_context_t *ctx; /** Need update */ - bool need_update; + struct + { + bool value; + pthread_mutex_t lock; + pthread_cond_t cond; + } need_update; + /** Thread id */ + pthread_t tid; /** Default colors */ struct { diff --git a/widget.c b/widget.c index 83b83e754..77919cfe8 100644 --- a/widget.c +++ b/widget.c @@ -129,7 +129,7 @@ widget_invalidate_cache(int screen, int flags) for(widget = statusbar->widgets; widget; widget = widget->next) if(widget->widget->cache_flags & flags) { - statusbar->need_update = true; + statusbar_needupdate(statusbar); break; } } @@ -148,7 +148,7 @@ widget_invalidate_statusbar_bywidget(widget_t *widget) for(witer = statusbar->widgets; witer; witer = witer->next) if(witer->widget == widget) { - statusbar->need_update = true; + statusbar_needupdate(statusbar); break; } }