summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2010-03-23 15:04:24 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2010-03-23 15:04:24 +0100
commit072fc663a83b2050d961d1c7ec7aa16f12842c9a (patch)
treeea701458975a339c4c729df7d72597cf4b300ea8
parente0afe5c8258d4b70ade84f1176c44ae6d593f2df (diff)
downloadrsyslog-072fc663a83b2050d961d1c7ec7aa16f12842c9a.tar.gz
rsyslog-072fc663a83b2050d961d1c7ec7aa16f12842c9a.tar.xz
rsyslog-072fc663a83b2050d961d1c7ec7aa16f12842c9a.zip
added replacements for atomic instructions on systems that do not support them.
[backport of Stefen Sledz' patch for v5]
-rw-r--r--ChangeLog2
-rw-r--r--configure.ac4
-rw-r--r--runtime/Makefile.am1
-rw-r--r--runtime/atomic.h117
-rw-r--r--runtime/rsyslog.c14
5 files changed, 138 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index dc12e856..b8deeb74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
Version 4.6.2 [v4-stable] (rgerhards), 2010-03-??
- new feature: "." action type added to support writing files to relative
pathes (this is primarily meant as a debug aid)
+- added replacements for atomic instructions on systems that do not
+ support them. [backport of Stefen Sledz' patch for v5)
- added new property replacer option "date-rfc3164-buggyday" primarily
to ease migration from syslog-ng. See property replacer doc for
details. [backport from 5.5.3 because urgently needed by some]
diff --git a/configure.ac b/configure.ac
index b059fe75..fcd70c30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -84,6 +84,7 @@ AC_TYPE_UINT8_T
AC_HEADER_TIME
AC_STRUCT_TM
AC_C_VOLATILE
+AC_C_TYPEOF
sa_includes="\
$ac_includes_default
@@ -126,6 +127,9 @@ AC_TRY_COMPILE([
# check for availability of atomic operations
RS_ATOMIC_OPERATIONS
+# fall back to POSIX sems for atomic operations (cpu expensive)
+AC_CHECK_HEADERS([semaphore.h])
+
# Additional module directories
AC_ARG_WITH(moddirs,
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index 14abe722..e5b3ccdf 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -9,6 +9,7 @@ librsyslog_la_SOURCES = \
rsyslog.h \
unicode-helper.h \
atomic.h \
+ atomic-posix-sem.c \
syslogd-types.h \
module-template.h \
obj-types.h \
diff --git a/runtime/atomic.h b/runtime/atomic.h
index 62ceb8b3..ea3be37a 100644
--- a/runtime/atomic.h
+++ b/runtime/atomic.h
@@ -53,6 +53,122 @@
# define ATOMIC_CAS(data, oldVal, newVal) __sync_bool_compare_and_swap(&(data), (oldVal), (newVal));
# define ATOMIC_CAS_VAL(data, oldVal, newVal) __sync_val_compare_and_swap(&(data), (oldVal), (newVal));
#else
+#ifdef HAVE_SEMAPHORE_H
+ /* we use POSIX semaphores instead */
+
+#include "rsyslog.h"
+#include <semaphore.h>
+
+extern sem_t atomicSem;
+rsRetVal atomicSemInit(void);
+void atomicSemExit(void);
+
+#if HAVE_TYPEOF
+#define my_typeof(x) typeof(x)
+#else /* sorry, can't determine types, using 'int' */
+#define my_typeof(x) int
+#endif
+
+# define ATOMIC_SUB(data, val) \
+({ \
+ my_typeof(data) tmp; \
+ sem_wait(&atomicSem); \
+ tmp = data; \
+ data -= val; \
+ sem_post(&atomicSem); \
+ tmp; \
+})
+
+# define ATOMIC_ADD(data, val) \
+({ \
+ my_typeof(data) tmp; \
+ sem_wait(&atomicSem); \
+ tmp = data; \
+ data += val; \
+ sem_post(&atomicSem); \
+ tmp; \
+})
+
+# define ATOMIC_INC_AND_FETCH(data) \
+({ \
+ my_typeof(data) tmp; \
+ sem_wait(&atomicSem); \
+ tmp = data; \
+ data += 1; \
+ sem_post(&atomicSem); \
+ tmp; \
+})
+
+# define ATOMIC_INC(data) ((void) ATOMIC_INC_AND_FETCH(data))
+
+# define ATOMIC_DEC_AND_FETCH(data) \
+({ \
+ sem_wait(&atomicSem); \
+ data -= 1; \
+ sem_post(&atomicSem); \
+ data; \
+})
+
+# define ATOMIC_DEC(data) ((void) ATOMIC_DEC_AND_FETCH(data))
+
+# define ATOMIC_FETCH_32BIT(data) ((unsigned) ATOMIC_ADD((data), 0xffffffff))
+
+# define ATOMIC_STORE_1_TO_32BIT(data) \
+({ \
+ my_typeof(data) tmp; \
+ sem_wait(&atomicSem); \
+ tmp = data; \
+ data = 1; \
+ sem_post(&atomicSem); \
+ tmp; \
+})
+
+# define ATOMIC_STORE_0_TO_INT(data) \
+({ \
+ my_typeof(data) tmp; \
+ sem_wait(&atomicSem); \
+ tmp = data; \
+ data = 0; \
+ sem_post(&atomicSem); \
+ tmp; \
+})
+
+# define ATOMIC_STORE_1_TO_INT(data) \
+({ \
+ my_typeof(data) tmp; \
+ sem_wait(&atomicSem); \
+ tmp = data; \
+ data = 1; \
+ sem_post(&atomicSem); \
+ tmp; \
+})
+
+# define ATOMIC_CAS(data, oldVal, newVal) \
+({ \
+ int ret; \
+ sem_wait(&atomicSem); \
+ if(data != oldVal) ret = 0; \
+ else \
+ { \
+ data = newVal; \
+ ret = 1; \
+ } \
+ sem_post(&atomicSem); \
+ ret; \
+})
+
+# define ATOMIC_CAS_VAL(data, oldVal, newVal) \
+({ \
+ sem_wait(&atomicSem); \
+ if(data == oldVal) \
+ { \
+ data = newVal; \
+ } \
+ sem_post(&atomicSem); \
+ data; \
+})
+
+#else /* not HAVE_SEMAPHORE_H */
/* note that we gained parctical proof that theoretical problems DO occur
* if we do not properly address them. See this blog post for details:
* http://blog.gerhards.net/2009/01/rsyslog-data-race-analysis.html
@@ -70,5 +186,6 @@
# define ATOMIC_STORE_0_TO_INT(data) (data) = 0
# define ATOMIC_CAS_VAL(data, oldVal, newVal) (data) = (newVal)
#endif
+#endif
#endif /* #ifndef INCLUDED_ATOMIC_H */
diff --git a/runtime/rsyslog.c b/runtime/rsyslog.c
index 443d0f41..5750ca76 100644
--- a/runtime/rsyslog.c
+++ b/runtime/rsyslog.c
@@ -80,6 +80,7 @@
#include "prop.h"
#include "rule.h"
#include "ruleset.h"
+#include "atomic.h"
/* forward definitions */
static rsRetVal dfltErrLogger(int, uchar *errMsg);
@@ -139,6 +140,12 @@ rsrtInit(char **ppErrObj, obj_if_t *pObjIF)
CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */
CHKiRet(objGetObjInterface(pObjIF)); /* this provides the root pointer for all other queries */
+#ifndef HAVE_ATOMIC_BUILTINS
+#ifdef HAVE_SEMAPHORE_H
+ CHKiRet(atomicSemInit());
+#endif /* HAVE_SEMAPHORE_H */
+#endif /* !defined(HAVE_ATOMIC_BUILTINS) */
+
/* initialize core classes. We must be very careful with the order of events. Some
* classes use others and if we do not initialize them in the right order, we may end
* up with an invalid call. The most important thing that can happen is that an error
@@ -215,6 +222,13 @@ rsrtExit(void)
glblClassExit();
rulesetClassExit();
ruleClassExit();
+
+#ifndef HAVE_ATOMIC_BUILTINS
+#ifdef HAVE_SEMAPHORE_H
+ atomicSemExit();
+#endif /* HAVE_SEMAPHORE_H */
+#endif /* !defined(HAVE_ATOMIC_BUILTINS) */
+
objClassExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */
}