From 4a6d73787de534cbd7d5fc7a6b60af64de66e7ea Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 22 Jun 2012 12:48:14 -0400 Subject: [PATCH] Fix inappropriate lib behavior: don't call exit() Use abort() (implemented through the new urcu_die()) instead of exit(-1) for unrecoverable errors. Fixes #152 Signed-off-by: Mathieu Desnoyers --- Makefile.am | 2 ++ urcu-bp.c | 21 ++++++++------------- urcu-call-rcu-impl.h | 41 +++++++++++++++++++++-------------------- urcu-defer-impl.h | 14 +++++--------- urcu-die.h | 37 +++++++++++++++++++++++++++++++++++++ urcu-qsbr.c | 21 ++++++++------------- urcu.c | 33 ++++++++++++--------------------- 7 files changed, 93 insertions(+), 76 deletions(-) create mode 100644 urcu-die.h diff --git a/Makefile.am b/Makefile.am index 933e538..2396fcf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,6 +22,8 @@ nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ urcu/tls-compat.h nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h +dist_noinst_HEADERS = urcu-die.h + EXTRA_DIST = $(top_srcdir)/urcu/arch/*.h $(top_srcdir)/urcu/uatomic/*.h \ gpl-2.0.txt lgpl-2.1.txt lgpl-relicensing.txt \ LICENSE compat_arch_x86.c \ diff --git a/urcu-bp.c b/urcu-bp.c index 67eae07..b9c89d8 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -42,6 +42,8 @@ #include "urcu-pointer.h" #include "urcu/tls-compat.h" +#include "urcu-die.h" + /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE #include "urcu-bp.h" @@ -142,17 +144,12 @@ static void mutex_lock(pthread_mutex_t *mutex) #ifndef DISTRUST_SIGNALS_EXTREME ret = pthread_mutex_lock(mutex); - if (ret) { - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret) + urcu_die(ret); #else /* #ifndef DISTRUST_SIGNALS_EXTREME */ while ((ret = pthread_mutex_trylock(mutex)) != 0) { - if (ret != EBUSY && ret != EINTR) { - printf("ret = %d, errno = %d\n", ret, errno); - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret != EBUSY && ret != EINTR) + urcu_die(ret); poll(NULL,0,10); } #endif /* #else #ifndef DISTRUST_SIGNALS_EXTREME */ @@ -163,10 +160,8 @@ static void mutex_unlock(pthread_mutex_t *mutex) int ret; ret = pthread_mutex_unlock(mutex); - if (ret) { - perror("Error in pthread mutex unlock"); - exit(-1); - } + if (ret) + urcu_die(ret); } void update_counter_and_wait(void) diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index 8ed2ab3..13b24ff 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -41,6 +41,7 @@ #include "urcu/list.h" #include "urcu/futex.h" #include "urcu/tls-compat.h" +#include "urcu-die.h" /* Data structure that identifies a call_rcu thread. */ @@ -151,20 +152,22 @@ static int sched_getcpu(void) static void call_rcu_lock(pthread_mutex_t *pmp) { - if (pthread_mutex_lock(pmp) != 0) { - perror("pthread_mutex_lock"); - exit(-1); - } + int ret; + + ret = pthread_mutex_lock(pmp); + if (ret) + urcu_die(ret); } /* Release the specified pthread mutex. */ static void call_rcu_unlock(pthread_mutex_t *pmp) { - if (pthread_mutex_unlock(pmp) != 0) { - perror("pthread_mutex_unlock"); - exit(-1); - } + int ret; + + ret = pthread_mutex_unlock(pmp); + if (ret) + urcu_die(ret); } #if HAVE_SCHED_SETAFFINITY @@ -222,11 +225,11 @@ static void *call_rcu_thread(void *arg) struct call_rcu_data *crdp = (struct call_rcu_data *)arg; struct rcu_head *rhp; int rt = !!(uatomic_read(&crdp->flags) & URCU_CALL_RCU_RT); + int ret; - if (set_thread_cpu_affinity(crdp) != 0) { - perror("pthread_setaffinity_np"); - exit(-1); - } + ret = set_thread_cpu_affinity(crdp); + if (ret) + urcu_die(errno); /* * If callbacks take a read-side lock, we need to be registered. @@ -308,12 +311,11 @@ static void call_rcu_data_init(struct call_rcu_data **crdpp, int cpu_affinity) { struct call_rcu_data *crdp; + int ret; crdp = malloc(sizeof(*crdp)); - if (crdp == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(-1); - } + if (crdp == NULL) + urcu_die(errno); memset(crdp, '\0', sizeof(*crdp)); cds_wfq_init(&crdp->cbs); crdp->qlen = 0; @@ -323,10 +325,9 @@ static void call_rcu_data_init(struct call_rcu_data **crdpp, crdp->cpu_affinity = cpu_affinity; cmm_smp_mb(); /* Structure initialized before pointer is planted. */ *crdpp = crdp; - if (pthread_create(&crdp->tid, NULL, call_rcu_thread, crdp) != 0) { - perror("pthread_create"); - exit(-1); - } + ret = pthread_create(&crdp->tid, NULL, call_rcu_thread, crdp); + if (ret) + urcu_die(ret); } /* diff --git a/urcu-defer-impl.h b/urcu-defer-impl.h index f65e410..a7d0b2f 100644 --- a/urcu-defer-impl.h +++ b/urcu-defer-impl.h @@ -49,6 +49,7 @@ #include #include #include +#include "urcu-die.h" /* * Number of entries in the per-thread defer queue. Must be power of 2. @@ -141,17 +142,12 @@ static void mutex_lock_defer(pthread_mutex_t *mutex) #ifndef DISTRUST_SIGNALS_EXTREME ret = pthread_mutex_lock(mutex); - if (ret) { - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret) + urcu_die(ret); #else /* #ifndef DISTRUST_SIGNALS_EXTREME */ while ((ret = pthread_mutex_trylock(mutex)) != 0) { - if (ret != EBUSY && ret != EINTR) { - printf("ret = %d, errno = %d\n", ret, errno); - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret != EBUSY && ret != EINTR) + urcu_die(ret); poll(NULL,0,10); } #endif /* #else #ifndef DISTRUST_SIGNALS_EXTREME */ diff --git a/urcu-die.h b/urcu-die.h new file mode 100644 index 0000000..227c8dc --- /dev/null +++ b/urcu-die.h @@ -0,0 +1,37 @@ +#ifndef _URCU_DIE_H +#define _URCU_DIE_H + +/* + * urcu-die.h + * + * Userspace RCU library unrecoverable error handling + * + * Copyright (c) 2012 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#define urcu_die(cause) \ +do { \ + fprintf(stderr, "(" __FILE__ ":%s@%u) Unrecoverable error: %s\n", \ + __func__, __LINE__, strerror(cause)); \ + abort(); \ +} while (0) + +#endif /* _URCU_DIE_H */ diff --git a/urcu-qsbr.c b/urcu-qsbr.c index b20d564..d3a6849 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -42,6 +42,8 @@ #include "urcu-pointer.h" #include "urcu/tls-compat.h" +#include "urcu-die.h" + /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE #include "urcu-qsbr.h" @@ -82,17 +84,12 @@ static void mutex_lock(pthread_mutex_t *mutex) #ifndef DISTRUST_SIGNALS_EXTREME ret = pthread_mutex_lock(mutex); - if (ret) { - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret) + urcu_die(ret); #else /* #ifndef DISTRUST_SIGNALS_EXTREME */ while ((ret = pthread_mutex_trylock(mutex)) != 0) { - if (ret != EBUSY && ret != EINTR) { - printf("ret = %d, errno = %d\n", ret, errno); - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret != EBUSY && ret != EINTR) + urcu_die(ret); poll(NULL,0,10); } #endif /* #else #ifndef DISTRUST_SIGNALS_EXTREME */ @@ -103,10 +100,8 @@ static void mutex_unlock(pthread_mutex_t *mutex) int ret; ret = pthread_mutex_unlock(mutex); - if (ret) { - perror("Error in pthread mutex unlock"); - exit(-1); - } + if (ret) + urcu_die(ret); } /* diff --git a/urcu.c b/urcu.c index 5fb4db8..a5178c0 100644 --- a/urcu.c +++ b/urcu.c @@ -42,6 +42,8 @@ #include "urcu-pointer.h" #include "urcu/tls-compat.h" +#include "urcu-die.h" + /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE #include "urcu.h" @@ -110,17 +112,12 @@ static void mutex_lock(pthread_mutex_t *mutex) #ifndef DISTRUST_SIGNALS_EXTREME ret = pthread_mutex_lock(mutex); - if (ret) { - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret) + urcu_die(ret); #else /* #ifndef DISTRUST_SIGNALS_EXTREME */ while ((ret = pthread_mutex_trylock(mutex)) != 0) { - if (ret != EBUSY && ret != EINTR) { - printf("ret = %d, errno = %d\n", ret, errno); - perror("Error in pthread mutex lock"); - exit(-1); - } + if (ret != EBUSY && ret != EINTR) + urcu_die(ret); if (CMM_LOAD_SHARED(URCU_TLS(rcu_reader).need_mb)) { cmm_smp_mb(); _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); @@ -136,10 +133,8 @@ static void mutex_unlock(pthread_mutex_t *mutex) int ret; ret = pthread_mutex_unlock(mutex); - if (ret) { - perror("Error in pthread mutex unlock"); - exit(-1); - } + if (ret) + urcu_die(ret); } #ifdef RCU_MEMBARRIER @@ -432,10 +427,8 @@ void rcu_init(void) act.sa_flags = SA_SIGINFO | SA_RESTART; sigemptyset(&act.sa_mask); ret = sigaction(SIGRCU, &act, NULL); - if (ret) { - perror("Error in sigaction"); - exit(-1); - } + if (ret) + urcu_die(errno); } void rcu_exit(void) @@ -444,10 +437,8 @@ void rcu_exit(void) int ret; ret = sigaction(SIGRCU, NULL, &act); - if (ret) { - perror("Error in sigaction"); - exit(-1); - } + if (ret) + urcu_die(errno); assert(act.sa_sigaction == sigrcu_handler); assert(cds_list_empty(®istry)); } -- 2.39.5