]> git.itanic.dy.fi Git - rrdd/commitdiff
process: Add debug wrappers for pthread mutex operations
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Fri, 8 Jul 2016 19:42:42 +0000 (22:42 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Fri, 8 Jul 2016 19:42:42 +0000 (22:42 +0300)
This is the beginning of the work to convert the concurrency model
from fork-bomb based model to pthreads.

To get started, add a wrapper functions to handle locking. Namely,
these wrappers will log where the lock was acquired and will print out
who is holding it in case of contention.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
Makefile
process.c
process.h

index cdf6dd746339baed0c5d5b9a8909b2f7fdd5421d..2cafd3d0345f3f32484fae90ff650f7890c63142 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 CC=gcc
 LD=ld
 CC=gcc
 LD=ld
-CFLAGS=-Wall -O2 -g -fPIC
+CFLAGS=-Wall -O2 -g -fPIC -D_GNU_SOURCE
 
 RRDD_OBJS= main.o process.o rrdtool.o parser.o built_in_parsers.o string.o \
                debug.o config.o plugin_manager.o
 
 RRDD_OBJS= main.o process.o rrdtool.o parser.o built_in_parsers.o string.o \
                debug.o config.o plugin_manager.o
@@ -27,7 +27,8 @@ default: rrdd
 all: rrdd $(ALL_PARSERS)
 
 rrdd: $(RRDD_OBJS)
 all: rrdd $(ALL_PARSERS)
 
 rrdd: $(RRDD_OBJS)
-       $(QUIET_LINK)$(CC) -o rrdd $(RRDD_OBJS) -lconfig -ldl -rdynamic
+       $(QUIET_LINK)$(CC) -o rrdd $(RRDD_OBJS) -lconfig -ldl -rdynamic \
+               -lpthread
 
 onewire_parser.so: $(ONEWIRE_PARSER_OBJS)
        $(QUIET_LINK)$(CC) $(CFLAGS) -lownet -shared -fPIC $< -o $@
 
 onewire_parser.so: $(ONEWIRE_PARSER_OBJS)
        $(QUIET_LINK)$(CC) $(CFLAGS) -lownet -shared -fPIC $< -o $@
index d6ed65199b97a5e4a0658ec8b408b2140667a942..ad47196501ecc3a70b773f252e170ba2dfabe9bb 100644 (file)
--- a/process.c
+++ b/process.c
@@ -1,4 +1,3 @@
-#define _GNU_SOURCE
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/select.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/select.h>
@@ -702,3 +701,38 @@ int register_event_handler(struct event_handler *handler)
 
        return 0;
 }
 
        return 0;
 }
+
+void _mutex_lock_acquired(struct mutex *lock, char *file, int line)
+{
+       lock->line = line;
+       lock->file = file;
+}
+
+int _mutex_lock(struct mutex *lock, char *file, int line)
+{
+       int ret = 0;
+
+       if (!pthread_mutex_trylock(&lock->lock))
+               goto out_lock;
+
+       pr_info("Lock contention on lock %s on %s:%d\n",
+               lock->name, lock->file, lock->line);
+
+       ret = pthread_mutex_lock(&lock->lock);
+       if (ret)
+               pr_err("Acquirin lock %s failed: %m, acquired %s:%d\n",
+                       lock->name, lock->file, lock->line);
+
+out_lock:
+       _mutex_lock_acquired(lock, file, line);
+       return ret;
+}
+
+int _mutex_unlock(struct mutex *lock)
+{
+       lock->line = 0;
+       lock->file = NULL;
+       pthread_mutex_unlock(&lock->lock);
+
+       return 0;
+}
index ae9db12b97457f90e5d4256c0e42e3ba5ffdb506..2589ea9a5251174c6632bf0b87620912c54e1cc3 100644 (file)
--- a/process.h
+++ b/process.h
@@ -9,6 +9,7 @@
 #include <error.h>
 #include <errno.h>
 #include <stdint.h>
 #include <error.h>
 #include <errno.h>
 #include <stdint.h>
+#include <pthread.h>
 
 struct event_handler;
 
 
 struct event_handler;
 
@@ -21,6 +22,14 @@ struct event_handler {
        char *name;
 };
 
        char *name;
 };
 
+struct mutex {
+       pthread_mutex_t lock;
+       int line;
+       char *file;
+       time_t lock_time;
+       char *name;
+};
+
 int register_event_handler(struct event_handler *handler);
 
 int get_child_count(void);
 int register_event_handler(struct event_handler *handler);
 
 int get_child_count(void);
@@ -37,5 +46,12 @@ int run_piped(const char *cmd, char *const argv[],
 int run_piped_stream(const char *cmd, char *const argv[],
                     FILE **stdinf, FILE **stdoutf, FILE **stderrf);
 
 int run_piped_stream(const char *cmd, char *const argv[],
                     FILE **stdinf, FILE **stdoutf, FILE **stderrf);
 
+void _mutex_lock_acquired(struct mutex *lock, char *file, int line);
+int _mutex_lock(struct mutex *lock, char *file, int line);
+int _mutex_unlock(struct mutex *lock);
+
+#define mutex_lock(lock) _mutex_lock(lock, __FILE__, __LINE__)
+#define mutex_unlock(lock) _mutex_unlock(lock)
+#define mutex_lock_acquired(lock) _mutex_lock_acquired(lock, __FILE__, __LINE__)
 
 #endif
 
 #endif