changeset 939:12fa2ae6445d

Get rid of "busy-waiting" (Christof Meerwald) This patch from Christof Meerwald, slightly modified, reduces mcabber CPU usage and the number of context switches per second.
author Mikael Berthe <mikael@lilotux.net>
date Tue, 11 Jul 2006 22:50:48 +0200
parents 40175f3dcef7
children fc30221b952d
files mcabber/src/jabglue.c mcabber/src/main.c mcabber/src/screen.c mcabber/src/screen.h
diffstat 4 files changed, 61 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/jabglue.c	Sat Jul 08 23:32:49 2006 +0200
+++ b/mcabber/src/jabglue.c	Tue Jul 11 22:50:48 2006 +0200
@@ -168,6 +168,9 @@
 void jb_main()
 {
   time_t now;
+  fd_set fds;
+  long autoaway_timeout;
+  struct timeval tv;
   static time_t last_eviqs_check = 0;
 
   if (!online) {
@@ -181,7 +184,30 @@
     return;
   }
 
-  jab_poll(jc, 50);
+  FD_ZERO(&fds);
+  FD_SET(0, &fds);
+  FD_SET(jc->fd, &fds);
+
+  tv.tv_sec = 60;
+  tv.tv_usec = 0;
+
+  if (KeepaliveDelay) {
+    time(&now);
+    if (now > LastPingTime + (time_t)KeepaliveDelay) {
+      tv.tv_sec = 0;
+    } else {
+      tv.tv_sec = LastPingTime + (time_t)KeepaliveDelay - now;
+    }
+  }
+
+  autoaway_timeout = scr_GetAutoAwayTimeout();
+  if (tv.tv_sec > autoaway_timeout)
+    tv.tv_sec = autoaway_timeout;
+
+  if (select(jc->fd + 1, &fds, NULL, NULL, &tv) > 0) {
+    if (FD_ISSET(jc->fd, &fds))
+      jab_poll(jc, 0);
+  }
 
   if (jstate == STATE_CONNECTING) {
     if (jc) {
--- a/mcabber/src/main.c	Sat Jul 08 23:32:49 2006 +0200
+++ b/mcabber/src/main.c	Tue Jul 11 22:50:48 2006 +0200
@@ -235,10 +235,8 @@
   char *configFile = NULL;
   const char *optstring;
   int optval, optval2;
-  int key;
   unsigned int ping;
   int ret;
-  unsigned int refresh = 0;
   keycode kcode;
 
   credits();
@@ -330,27 +328,20 @@
   scr_LogPrint(LPRINT_DEBUG, "Entering into main loop...");
 
   for (ret = 0 ; ret != 255 ; ) {
+    scr_DoUpdate();
     scr_Getch(&kcode);
-    key = kcode.value;
 
-    /* The refresh is really an ugly hack, but we need to call doupdate()
-       from time to time to catch the RESIZE events, because getch keep
-       returning ERR until a real key is pressed :-(
-       However, it allows us to handle an autoaway check here...
-     */
-    if (key != ERR) {
+    if (kcode.value != ERR) {
       ret = process_key(kcode);
-      refresh = 0;
-    } else if (refresh++ > 1) {
-      doupdate();
-      refresh = 0;
+    } else {
       scr_CheckAutoAway(FALSE);
+
+      if (update_roster)
+	scr_DrawRoster();
+
+      scr_DoUpdate();
+      jb_main();
     }
-
-    if (key != KEY_RESIZE)
-      jb_main();
-    if (update_roster)
-      scr_DrawRoster();
   }
 
   jb_disconnect();
--- a/mcabber/src/screen.c	Sat Jul 08 23:32:49 2006 +0200
+++ b/mcabber/src/screen.c	Tue Jul 11 22:50:48 2006 +0200
@@ -83,6 +83,7 @@
 int utf8_mode = 0;
 static bool Autoaway;
 static bool Curses;
+static time_t LastActivity;
 
 static char       inputLine[INPUTLINE_LENGTH+1];
 static char      *ptr_inputline;
@@ -368,7 +369,6 @@
       wprintw(logWnd,
               "\n%s*Error: cannot convert string to locale.", strtimestamp);
       update_panels();
-      doupdate();
       g_free(buffer);
       g_free(btext);
       return;
@@ -383,7 +383,6 @@
     if (Curses) {
       wprintw(logWnd, "\n%s", buffer_locale);
       update_panels();
-      doupdate();
       scr_WriteInWindow(NULL, buf_specialwindow, timestamp,
                         HBB_PREFIX_SPECIAL, FALSE);
     } else {
@@ -733,7 +732,6 @@
     scr_UpdateWindow(win_entry);
     top_panel(inputPanel);
     update_panels();
-    doupdate();
   } else if (!(prefix_flags & HBB_PREFIX_NOFLAG)) {
     setmsgflg = TRUE;
   }
@@ -758,7 +756,6 @@
   if (forceupdate) {
     top_panel(inputPanel);
     update_panels();
-    doupdate();
   }
   g_free(sm);
 }
@@ -952,7 +949,7 @@
 
 //  scr_UpdateChatStatus(forceupdate)
 // Redraw the buddy status bar.
-// Set forceupdate to TRUE if doupdate() must be called.
+// Set forceupdate to TRUE if update_panels() must be called.
 void scr_UpdateChatStatus(int forceupdate)
 {
   unsigned short btype, isgrp, ismuc, isspe;
@@ -974,7 +971,6 @@
   if (!current_buddy) {
     if (forceupdate) {
       update_panels();
-      doupdate();
     }
     return;
   }
@@ -1002,7 +998,6 @@
     g_free(buf_locale);
     if (forceupdate) {
       update_panels();
-      doupdate();
     }
     return;
   }
@@ -1041,7 +1036,6 @@
 
   if (forceupdate) {
     update_panels();
-    doupdate();
   }
 }
 
@@ -1085,7 +1079,6 @@
   // Leave now if buddylist is empty or the roster is hidden
   if (!buddylist || !Roster_Width) {
     update_panels();
-    doupdate();
     curs_set(cursor_backup);
     return;
   }
@@ -1212,7 +1205,6 @@
   g_free(name);
   top_panel(inputPanel);
   update_panels();
-  doupdate();
   curs_set(cursor_backup);
 }
 
@@ -1270,7 +1262,6 @@
 
   scr_WriteMessage(jidfrom, text, timestamp, prefix);
   update_panels();
-  doupdate();
 }
 
 void scr_WriteOutgoingMessage(const char *jidto, const char *text)
@@ -1309,10 +1300,24 @@
   }
 }
 
+unsigned int scr_GetAutoAwayTimeout()
+{
+  unsigned int autoaway_timeout = settings_opt_get_int("autoaway");
+  time_t now;
+
+  if (Autoaway || !autoaway_timeout)
+    return (unsigned)INT_MAX;
+
+  time(&now);
+  if (now > LastActivity + (time_t)autoaway_timeout)
+    return 0;
+  else
+    return LastActivity + (time_t)autoaway_timeout - now;
+}
+
 // Check if we should enter/leave automatic away status
 void scr_CheckAutoAway(int activity)
 {
-  static time_t LastActivity;
   enum imstatus cur_st;
   unsigned int autoaway_timeout = settings_opt_get_int("autoaway");
 
@@ -1532,7 +1537,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_BufferClear()
@@ -1556,7 +1560,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_BufferPurge()
@@ -1587,7 +1590,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_BufferScrollLock(lock)
@@ -1632,7 +1634,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_BufferTopBottom()
@@ -1660,7 +1661,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_BufferSearch(direction, text)
@@ -1694,7 +1694,6 @@
 
     // Finished :)
     update_panels();
-    doupdate();
   } else
     scr_LogPrint(LPRINT_NORMAL, "Search string not found");
 }
@@ -1728,7 +1727,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_BufferDate(t)
@@ -1756,7 +1754,6 @@
 
   // Finished :)
   update_panels();
-  doupdate();
 }
 
 //  scr_set_chatmode()
@@ -2401,6 +2398,11 @@
   return;
 }
 
+inline void scr_DoUpdate(void)
+{
+  doupdate();
+}
+
 static int bindcommand(keycode kcode)
 {
   gchar asciikey[16];
@@ -2666,8 +2668,6 @@
   if (completion_started && key != 9 && key != KEY_RESIZE)
     scr_end_current_completion();
   refresh_inputline();
-  if (!update_roster)
-    doupdate();
   return 0;
 }
 
--- a/mcabber/src/screen.h	Sat Jul 08 23:32:49 2006 +0200
+++ b/mcabber/src/screen.h	Tue Jul 11 22:50:48 2006 +0200
@@ -65,6 +65,8 @@
 void scr_Getch(keycode *kcode);
 int process_key(keycode kcode);
 
+inline void scr_DoUpdate(void);
+
 void scr_InitLocaleCharSet(void);
 void scr_InitCurses(void);
 void scr_TerminateCurses(void);
@@ -89,6 +91,7 @@
 
 inline void scr_Beep(void);
 
+unsigned int scr_GetAutoAwayTimeout();
 void scr_CheckAutoAway(int activity);
 
 // For commands...