From cf38fc81759b01af5125b1a05e0d6fe8e2e1bc21 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 22 Oct 2008 13:54:40 +0200 Subject: added a setting "$OptimizeForUniprocessor" ...to enable users to turn off pthread_yield calls which are counter-productive on multiprocessor machines (but have been shown to be useful on uniprocessors) --- ChangeLog | 3 +++ doc/rsyslog_conf.html | 6 ++++-- runtime/glbl.c | 5 +++++ runtime/glbl.h | 1 + runtime/queue.c | 5 ++++- runtime/queue.h | 1 + runtime/wti.c | 15 ++++++++++++++- runtime/wti.h | 1 + runtime/wtp.c | 16 +++++++++++++++- runtime/wtp.h | 1 + 10 files changed, 49 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 41aef49f..6856c3e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,9 @@ version before switching to this one. receive loop (aka receiving messsages at a high rate) - doc bugfix: queue doc had wrong parameter name for setting controlling worker thread shutdown period +- added a setting "$OptimizeForUniprocessor" to enable users to turn off + pthread_yield calls which are counter-productive on multiprocessor + machines (but have been shown to be useful on uniprocessors) --------------------------------------------------------------------------- Version 3.21.6 [DEVEL] (rgerhards), 2008-10-22 - consolidated time calls during msg object creation, improves performance diff --git a/doc/rsyslog_conf.html b/doc/rsyslog_conf.html index 2b773476..be543833 100644 --- a/doc/rsyslog_conf.html +++ b/doc/rsyslog_conf.html @@ -236,8 +236,10 @@ supported in order to be compliant to the upcoming new syslog RFC series.
  • $ModLoad
  • $RepeatedMsgReduction
  • $ResetConfigVariables
  • -
  • $WorkDirectory <name> (directory for spool -and other work files)
  • +
  • $OptimizeForUniprocessor [on/off] - turns on optimizatons which lead to better +performance on uniprocessors. If you run on multicore-machiens, turning this off lessens CPU load. The +default may change as uniprocessor systems become less common.
  • +
  • $WorkDirectory <name> (directory for spool and other work files)
  • $UDPServerAddress <IP> (imudp) -- local IP address (or name) the UDP listens should bind to
  • $UDPServerRun <port> (imudp) -- former diff --git a/runtime/glbl.c b/runtime/glbl.c index 1114fcd3..c752288f 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -51,6 +51,7 @@ DEFobjStaticHelpers * class... */ static uchar *pszWorkDir = NULL; +static int bOptimizeUniProc = 1; /* enable uniprocessor optimizations */ static int iMaxLine = 2048; /* maximum length of a syslog message */ static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */ static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */ @@ -85,6 +86,7 @@ static dataType Get##nameFunc(void) \ return(nameVar); \ } +SIMP_PROP(OptimizeUniProc, bOptimizeUniProc, int) SIMP_PROP(MaxLine, iMaxLine, int) SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may check the family argument */ SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int) @@ -173,6 +175,7 @@ CODESTARTobjQueryInterface(glbl) pIf->Get##name = Get##name; \ pIf->Set##name = Set##name; SIMP_PROP(MaxLine); + SIMP_PROP(OptimizeUniProc); SIMP_PROP(DefPFFamily); SIMP_PROP(DropMalPTRMsgs); SIMP_PROP(Option_DisallowWarning); @@ -216,6 +219,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a pszWorkDir = NULL; } bDropMalPTRMsgs = 0; + bOptimizeUniProc = 1; return RS_RET_OK; } @@ -235,6 +239,7 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */ CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercafile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCAF, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrKeyFile, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCertFile, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrBinary, NULL, &bOptimizeUniProc, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); ENDObjClassInit(glbl) diff --git a/runtime/glbl.h b/runtime/glbl.h index 0c83bdd5..0b871b3c 100644 --- a/runtime/glbl.h +++ b/runtime/glbl.h @@ -41,6 +41,7 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */ dataType (*Get##name)(void); \ rsRetVal (*Set##name)(dataType); SIMP_PROP(MaxLine, int) + SIMP_PROP(OptimizeUniProc, int) SIMP_PROP(DefPFFamily, int) SIMP_PROP(DropMalPTRMsgs, int) SIMP_PROP(Option_DisallowWarning, int) diff --git a/runtime/queue.c b/runtime/queue.c index 7fa2df91..a3e29a96 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -1285,6 +1285,7 @@ rsRetVal queueConstruct(queue_t **ppThis, queueType_t qType, int iWorkerThreads, /* we have an object, so let's fill the properties */ objConstructSetObjInfo(pThis); + pThis->bOptimizeUniProc = glbl.GetOptimizeUniProc(); if((pThis->pszSpoolDir = (uchar*) strdup((char*)glbl.GetWorkDir())) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); @@ -2208,8 +2209,10 @@ finalize_it: /* the following pthread_yield is experimental, but brought us performance * benefit. For details, please see http://kb.monitorware.com/post14216.html#p14216 * rgerhards, 2008-10-09 + * but this is only true for uniprocessors, so we guard it with an optimize flag -- rgerhards, 2008-10-22 */ - pthread_yield(); + if(pThis->bOptimizeUniProc) + pthread_yield(); } RETiRet; diff --git a/runtime/queue.h b/runtime/queue.h index 9e75b31b..a2dd594f 100644 --- a/runtime/queue.h +++ b/runtime/queue.h @@ -58,6 +58,7 @@ typedef struct qWrkThrd_s { typedef struct queue_s { BEGINobjInstance; queueType_t qType; + int bOptimizeUniProc; /* cache for the equally-named global setting, pulled at time of queue creation */ int bEnqOnly; /* does queue run in enqueue-only mode (1) or not (0)? */ int bSaveOnShutdown;/* persists everthing on shutdown (if DA!)? 1-yes, 0-no */ int bQueueStarted; /* has queueStart() been called on this queue? 1-yes, 0-no */ diff --git a/runtime/wti.c b/runtime/wti.c index 4abca090..e8a77474 100644 --- a/runtime/wti.c +++ b/runtime/wti.c @@ -45,9 +45,11 @@ #include "wtp.h" #include "wti.h" #include "obj.h" +#include "glbl.h" /* static data */ DEFobjStaticHelpers +DEFobjCurrIf(glbl) /* forward-definitions */ @@ -202,6 +204,7 @@ ENDobjDestruct(wti) /* Standard-Constructor for the wti object */ BEGINobjConstruct(wti) /* be sure to specify the object type also in END macro! */ + pThis->bOptimizeUniProc = glbl.GetOptimizeUniProc(); pthread_cond_init(&pThis->condExitDone, NULL); pthread_mutex_init(&pThis->mut, NULL); ENDobjConstruct(wti) @@ -367,7 +370,8 @@ wtiWorker(wti_t *pThis) wtpProcessThrdChanges(pWtp); pthread_testcancel(); /* see big comment in function header */ # if !defined(__hpux) /* pthread_yield is missing there! */ - pthread_yield(); /* see big comment in function header */ + if(pThis->bOptimizeUniProc) + pthread_yield(); /* see big comment in function header */ # endif /* if we have a rate-limiter set for this worker pool, let's call it. Please @@ -466,6 +470,14 @@ finalize_it: /* dummy */ rsRetVal wtiQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } +/* exit our class + */ +BEGINObjClassExit(wti, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ +CODESTARTObjClassExit(nsdsel_gtls) + /* release objects we no longer need */ + objRelease(glbl, CORE_COMPONENT); +ENDObjClassExit(wti) + /* Initialize the wti class. Must be called as the very first method * before anything else is called inside this class. @@ -473,6 +485,7 @@ rsRetVal wtiQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } */ BEGINObjClassInit(wti, 1, OBJ_IS_CORE_MODULE) /* one is the object version (most important for persisting) */ /* request objects we use */ + CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDObjClassInit(wti) /* diff --git a/runtime/wti.h b/runtime/wti.h index 0cd6744e..6b60b833 100644 --- a/runtime/wti.h +++ b/runtime/wti.h @@ -31,6 +31,7 @@ /* the worker thread instance class */ typedef struct wti_s { BEGINobjInstance; + int bOptimizeUniProc; /* cache for the equally-named global setting, pulled at time of queue creation */ pthread_t thrdID; /* thread ID */ qWrkCmd_t tCurrCmd; /* current command to be carried out by worker */ obj_t *pUsrp; /* pointer to an object meaningful for current user pointer (e.g. queue pUsr data elemt) */ diff --git a/runtime/wtp.c b/runtime/wtp.c index 45034fa7..06173e04 100644 --- a/runtime/wtp.c +++ b/runtime/wtp.c @@ -46,9 +46,11 @@ #include "wtp.h" #include "wti.h" #include "obj.h" +#include "glbl.h" /* static data */ DEFobjStaticHelpers +DEFobjCurrIf(glbl) /* forward-definitions */ @@ -75,6 +77,7 @@ static rsRetVal NotImplementedDummy() { return RS_RET_OK; } /* Standard-Constructor for the wtp object */ BEGINobjConstruct(wtp) /* be sure to specify the object type also in END macro! */ + pThis->bOptimizeUniProc = glbl.GetOptimizeUniProc(); pthread_mutex_init(&pThis->mut, NULL); pthread_cond_init(&pThis->condThrdTrm, NULL); /* set all function pointers to "not implemented" dummy so that we can safely call them */ @@ -484,7 +487,8 @@ wtpStartWrkr(wtp_t *pThis, int bLockMutex) * hold the queue's mutex, but at least it has a chance to start on a single-CPU system. */ # if !defined(__hpux) /* pthread_yield is missing there! */ - pthread_yield(); + if(pThis->bOptimizeUniProc) + pthread_yield(); # endif /* indicate we just started a worker and would like to see it running */ @@ -617,12 +621,22 @@ finalize_it: /* dummy */ rsRetVal wtpQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } +/* exit our class + */ +BEGINObjClassExit(wtp, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ +CODESTARTObjClassExit(nsdsel_gtls) + /* release objects we no longer need */ + objRelease(glbl, CORE_COMPONENT); +ENDObjClassExit(wtp) + + /* Initialize the stream class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-09 */ BEGINObjClassInit(wtp, 1, OBJ_IS_CORE_MODULE) /* request objects we use */ + CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDObjClassInit(wtp) /* diff --git a/runtime/wtp.h b/runtime/wtp.h index 13ebe536..88d88afd 100644 --- a/runtime/wtp.h +++ b/runtime/wtp.h @@ -52,6 +52,7 @@ typedef enum { /* the worker thread pool (wtp) object */ typedef struct wtp_s { BEGINobjInstance; + int bOptimizeUniProc; /* cache for the equally-named global setting, pulled at time of queue creation */ wtpState_t wtpState; int iNumWorkerThreads;/* number of worker threads to use */ int iCurNumWrkThrd;/* current number of active worker threads */ -- cgit