From 73053ddf3386604f19b494afd9c234ac50427d6c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 16 Sep 2014 15:48:49 -0700 Subject: Locks: Rework to avoid unnecessary display reopening The extremely useful "Locks" plugin eats quite a lot of CPU (>2% here on a old-ish laptop), unfortunately. The plug-in unnecessary reopens the display, which is quite expensive operation. It results into 16 syscalls: socket(PF_LOCAL) -> connect(sun_path=@"/tmp/.X11-unix/X0"}) -> getpeername() -> uname() -> access(".Xauthority") -> open(".Xauthority") -> fstat() -> mmap() -> read() -> close() -> munmap() -> getsockname() -> fcntl(F_SETFD) -> fcntl(F_SETFL) -> shutdown() -> close() This is almost half of all the syscalls that we ought to execute for the plug-in to work. Now, considering the useful work and that "Locks" runs every 200 milliseconds, it gives us >300 syscalls (and a lot more wake-ups) per second. This commit fixes the reopening issue, effectively halving the CPU consumption (down to ~1%). The patch also makes it easier to implement event-driven indicators that will reduce the idle CPU consumption to 0. --- src/Plugins/Locks.hs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Plugins/Locks.hs b/src/Plugins/Locks.hs index 3c1e0a9..b30eb1b 100644 --- a/src/Plugins/Locks.hs +++ b/src/Plugins/Locks.hs @@ -30,22 +30,30 @@ locks = [ ( xK_Caps_Lock, "CAPS" ) , ( xK_Scroll_Lock, "SCROLL" ) ] +run' :: Display -> Window -> IO String +run' d root = do + modMap <- getModifierMapping d + ( _, _, _, _, _, _, _, m ) <- queryPointer d root + + ls <- filterM ( \( ks, _ ) -> do + kc <- keysymToKeycode d ks + return $ case find (elem kc . snd) modMap of + Nothing -> False + Just ( i, _ ) -> testBit m (fromIntegral i) + ) locks + + return $ unwords $ map snd ls + instance Exec Locks where alias Locks = "locks" rate Locks = 2 - run Locks = do + start Locks cb = do d <- openDisplay "" root <- rootWindow d (defaultScreen d) - modMap <- getModifierMapping d - ( _, _, _, _, _, _, _, m ) <- queryPointer d root + forever $ do + cb =<< run' d root + tenthSeconds $ rate Locks - ls <- filterM ( \( ks, _ ) -> do - kc <- keysymToKeycode d ks - return $ case find (elem kc . snd) modMap of - Nothing -> False - Just ( i, _ ) -> testBit m (fromIntegral i) - ) locks closeDisplay d - - return $ unwords $ map snd ls + return () -- cgit v1.2.3