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
[email protected]
https://lists.sourceforge.net/lists/listinfo/naviserver-devel