Dear all,

while cleaning up the code i was checking the the mutex frequenies and 
stumbled upon "nsd:conf" (the string name of nsconf.state.lock). We see 
on our production server up to 16.000 locks per second on this mutex, 
this is a factor of 25 higher then the total number of e.g. the 
nsd:queue lock that we have reduced.

most of the "nsd:conf"  locks are coming from Ns_InfoStarted() in 
Ns_ConfigCreateSection(), which is called whenever ConfigGet is called, 
which is a frequent operation.

It is somewhat strange that we use most hammered mutex for a rather - 
what it looks to me - minor issue, a check, if the server is started or 
not. It looks to me, as if some people already looked at this heavy 
hammering issue (see comment "This dirty-read is worth the effort." 
below), where there seems to be a very simple solution for pratically 
eliminating this issue, which is also much faster: Why not call 
GetSection() in ConfigGet() instead of Ns_ConfigCreateSection()?

I have changed this locally, all tests run fine, but since the soultion 
is no much straightforward, i wonder, whether i have missed something on 
this. The relevant snippets are below, also these modifying the starting 
state.

all the best
-gustaf neumann



--- a/nsd/config.c      Thu Dec 20 12:47:08 2012 +0100
+++ b/nsd/config.c      Sat Dec 22 12:02:13 2012 +0100
@@ -816,7 +816,7 @@
  
      s = NULL;
      if (section != NULL && key != NULL) {
-        set = Ns_ConfigCreateSection(section);
+        set = GetSection(section, 0);
          if (set != NULL) {
              int  i;
              if (exact) {



config.c:
Ns_Set * Ns_ConfigCreateSection(CONST char *section) {
     int create = Ns_InfoStarted() ? 0 : 1;
     return (section ? GetSection(section, create) : NULL);
}


static char *
ConfigGet(CONST char *section, CONST char *key, int exact, CONST char 
*defstr)
{
     Ns_Set         *set;
     char           *s;

     s = NULL;
     if (section != NULL && key != NULL) {
       set = Ns_ConfigCreateSection(section);
...
}


int Ns_InfoStarted(int caller) {
     int             started;

     Ns_MutexLock(&nsconf.state.lock);
     started = nsconf.state.started;
     Ns_MutexUnlock(&nsconf.state.lock);
     return started;
}



nsconf.c:

NsInitConf() {
       ...
       nsconf.state.started = 1;
       ...
}


nsmain.c
Ns_Main() {
    ...
     /*
      * Mark the server stopped until initialization is complete.
      */

     Ns_MutexLock(&nsconf.state.lock);
     nsconf.state.started = 0;
     Ns_MutexUnlock(&nsconf.state.lock);

     .....
     /*
      * Run pre-startups and start the servers.
      */

     NsRunPreStartupProcs();
     NsStartServers();
     NsStartDrivers();

     /*
      * Signal startup is complete.
      */

     StatusMsg(running);

     Ns_MutexLock(&nsconf.state.lock);
     nsconf.state.started = 1;
     Ns_CondBroadcast(&nsconf.state.cond);
     Ns_MutexUnlock(&nsconf.state.lock);
     ...
}

....

int
Ns_WaitForStartup(void)
{

     /*
      * This dirty-read is worth the effort.
      */
     if (nsconf.state.started) {
         return NS_OK;
     }

     Ns_MutexLock(&nsconf.state.lock);
     while (!nsconf.state.started) {
         Ns_CondWait(&nsconf.state.cond, &nsconf.state.lock);
     }
     Ns_MutexUnlock(&nsconf.state.lock);
     return NS_OK;
}








------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
Remotely access PCs and mobile devices and provide instant support
Improve your efficiency, and focus on delivering more value-add services
Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________
naviserver-devel mailing list
naviserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

Reply via email to