Skip to content

Commit

Permalink
Rework pthread on/off handling
Browse files Browse the repository at this point in the history
Add some generic code to handle most of the cases when pthreads is
disabled.  Apply those to oomtest.c so it will compile without pthreads.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
  • Loading branch information
cminyard committed Feb 10, 2020
1 parent 2aa9648 commit 8918de5
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 81 deletions.
2 changes: 2 additions & 0 deletions include/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

SUBDIRS = gensio

noinst_HEADERS = pthread_handler.h
28 changes: 28 additions & 0 deletions include/pthread_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* gensio - A library for abstracting stream I/O
* Copyright (C) 2020 Corey Minyard <minyard@acm.org>
*
* SPDX-License-Identifier: LGPL-2.1-only
*/

/*
* This allows a lot of pthread calls to be dummied out if pthreads is
* disabled.
*/
#ifdef USE_PTHREADS
#include <pthread.h>
#define lock_type pthread_mutex_t
#define LOCK_INIT(l) pthread_mutex_init(l, NULL)
#define LOCK_DESTROY(l) pthread_mutex_destroy(l)
#define LOCK(l) pthread_mutex_lock(l)
#define UNLOCK(l) pthread_mutex_unlock(l)
#define LOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#else
#include <assert.h>
#define lock_type int
#define LOCK_INIT(l) do { *l = 0; } while(0)
#define LOCK_DESTROY(l) do { assert(*l == 0); } while(0)
#define LOCK(l) do { assert(*l == 0); *l = 1; } while(0)
#define UNLOCK(l) do { assert(*l == 1); *l = 0; } while(0)
#define LOCK_INITIALIZER 0
#endif
2 changes: 1 addition & 1 deletion lib/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir) $(OPENSSL_INCLUDES)
AM_CFLAGS = -I$(top_srcdir)/include $(OPENSSL_INCLUDES)

lib_LTLIBRARIES = libgensio.la

Expand Down
73 changes: 32 additions & 41 deletions lib/gensio_selector.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,7 @@
#include <string.h>
#include <errno.h>

#ifdef USE_PTHREADS
#include <pthread.h>
#else
#define pthread_mutex_t int
#define pthread_mutex_lock(l) do { } while (0)
#define pthread_mutex_unlock(l) do { } while (0)
#define pthread_mutex_init(l, n) do { } while (0)
#define pthread_mutex_destroy(l) do { } while (0)
#define PTHREAD_MUTEX_INITIALIZER 0
#endif
#include "pthread_handler.h"

#include <gensio/gensio_selector.h>

Expand All @@ -40,15 +31,15 @@ struct gensio_data {

#ifdef OUT_OF_MEMORY_TEST
/* Declared in selector.c */
extern pthread_mutex_t oom_mutex;
extern lock_type oom_mutex;
extern bool oom_initialized;
extern bool oom_ready;
extern bool triggered;
extern unsigned int oom_count;
extern unsigned int oom_curr;
#endif
#ifdef TRACK_ALLOCED_MEMORY
pthread_mutex_t memtrk_mutex = PTHREAD_MUTEX_INITIALIZER;
lock_type memtrk_mutex = LOCK_INITIALIZER;
struct memory_link {
struct memory_link *next;
struct memory_link *prev;
Expand Down Expand Up @@ -77,7 +68,7 @@ gensio_sel_zalloc(struct gensio_os_funcs *f, unsigned int size)
{
bool triggerit = false;

pthread_mutex_lock(&oom_mutex);
LOCK(&oom_mutex);
if (!oom_initialized) {
char *s = getenv("GENSIO_OOM_TEST");

Expand All @@ -94,14 +85,14 @@ gensio_sel_zalloc(struct gensio_os_funcs *f, unsigned int size)
triggerit = true;
}
}
pthread_mutex_unlock(&oom_mutex);
UNLOCK(&oom_mutex);
if (triggerit)
return NULL;
}
#endif
#ifdef TRACK_ALLOCED_MEMORY
if (!memtracking_initialized) {
pthread_mutex_lock(&memtrk_mutex);
LOCK(&memtrk_mutex);
if (!memtracking_initialized) {
char *s = getenv("GENSIO_MEMTRACK");

Expand All @@ -112,7 +103,7 @@ gensio_sel_zalloc(struct gensio_os_funcs *f, unsigned int size)
memtracking_abort_on_lost = true;
}
}
pthread_mutex_unlock(&memtrk_mutex);
UNLOCK(&memtrk_mutex);
}
if (memtracking_ready) {
d = malloc(size + sizeof(struct memory_header));
Expand All @@ -129,13 +120,13 @@ gensio_sel_zalloc(struct gensio_os_funcs *f, unsigned int size)
#endif
memset(h->freers, 0, sizeof(void *) * 4);
h->inuse = true;
pthread_mutex_lock(&memtrk_mutex);
LOCK(&memtrk_mutex);
h->link.next = &memhead;
h->link.prev = memhead.prev;
memhead.prev->next = &h->link;
memhead.prev = &h->link;
freecount++;
pthread_mutex_unlock(&memtrk_mutex);
UNLOCK(&memtrk_mutex);
}
} else
#endif
Expand Down Expand Up @@ -174,7 +165,7 @@ gensio_sel_free(struct gensio_os_funcs *f, void *data)
h->freers[2] = __builtin_return_address(2);
h->freers[3] = __builtin_return_address(3);
#endif
pthread_mutex_lock(&memtrk_mutex);
LOCK(&memtrk_mutex);
h->link.next->prev = h->link.prev;
h->link.prev->next = h->link.next;
h->inuse = false;
Expand All @@ -184,15 +175,15 @@ gensio_sel_free(struct gensio_os_funcs *f, void *data)
h->link.prev = memfree.prev;
memfree.prev->next = &h->link;
memfree.prev = &h->link;
pthread_mutex_unlock(&memtrk_mutex);
UNLOCK(&memtrk_mutex);
} else
#endif
free(data);
}

struct gensio_lock {
struct gensio_os_funcs *f;
pthread_mutex_t lock;
lock_type lock;
};

static struct gensio_lock *
Expand All @@ -202,7 +193,7 @@ gensio_sel_alloc_lock(struct gensio_os_funcs *f)

if (lock) {
lock->f = f;
pthread_mutex_init(&lock->lock, NULL);
LOCK_INIT(&lock->lock);
}

return lock;
Expand All @@ -211,20 +202,20 @@ gensio_sel_alloc_lock(struct gensio_os_funcs *f)
static void
gensio_sel_free_lock(struct gensio_lock *lock)
{
pthread_mutex_destroy(&lock->lock);
LOCK_DESTROY(&lock->lock);
lock->f->free(lock->f, lock);
}

static void
gensio_sel_lock(struct gensio_lock *lock)
{
pthread_mutex_lock(&lock->lock);
LOCK(&lock->lock);
}

static void
gensio_sel_unlock(struct gensio_lock *lock)
{
pthread_mutex_unlock(&lock->lock);
UNLOCK(&lock->lock);
}

static int
Expand Down Expand Up @@ -308,7 +299,7 @@ struct gensio_timer {
void (*handler)(struct gensio_timer *t, void *cb_data);
void *cb_data;
sel_timer_t *sel_timer;
pthread_mutex_t lock;
lock_type lock;

void (*done_handler)(struct gensio_timer *t, void *cb_data);
void *done_cb_data;
Expand Down Expand Up @@ -339,7 +330,7 @@ gensio_sel_alloc_timer(struct gensio_os_funcs *f,
timer->f = f;
timer->handler = handler;
timer->cb_data = cb_data;
pthread_mutex_init(&timer->lock, NULL);
LOCK_INIT(&timer->lock);

rv = sel_alloc_timer(d->sel, gensio_timeout_handler, timer,
&timer->sel_timer);
Expand Down Expand Up @@ -396,10 +387,10 @@ gensio_stop_timer_done(struct selector_s *sel,
void (*done_handler)(struct gensio_timer *t, void *cb_data);
void *done_cb_data;

pthread_mutex_lock(&timer->lock);
LOCK(&timer->lock);
done_handler = timer->done_handler;
done_cb_data = timer->done_cb_data;
pthread_mutex_unlock(&timer->lock);
UNLOCK(&timer->lock);
done_handler(timer, done_cb_data);
}

Expand All @@ -411,9 +402,9 @@ gensio_sel_stop_timer_with_done(struct gensio_timer *timer,
{
int rv;

pthread_mutex_lock(&timer->lock);
LOCK(&timer->lock);
if (timer->done_handler) {
pthread_mutex_unlock(&timer->lock);
UNLOCK(&timer->lock);
return GE_INUSE;
}
rv = sel_stop_timer_with_done(timer->sel_timer, gensio_stop_timer_done,
Expand All @@ -422,7 +413,7 @@ gensio_sel_stop_timer_with_done(struct gensio_timer *timer,
timer->done_handler = done_handler;
timer->done_cb_data = cb_data;
}
pthread_mutex_unlock(&timer->lock);
UNLOCK(&timer->lock);
return gensio_os_err_to_err(timer->f, rv);
}

Expand Down Expand Up @@ -613,21 +604,21 @@ gensio_sel_free_funcs(struct gensio_os_funcs *f)
free(f);
}

static pthread_mutex_t once_lock = PTHREAD_MUTEX_INITIALIZER;
static lock_type once_lock = LOCK_INITIALIZER;

static void
gensio_sel_call_once(struct gensio_os_funcs *f, struct gensio_once *once,
void (*func)(void *cb_data), void *cb_data)
{
if (once->called)
return;
pthread_mutex_lock(&once_lock);
LOCK(&once_lock);
if (!once->called) {
once->called = true;
pthread_mutex_unlock(&once_lock);
UNLOCK(&once_lock);
func(cb_data);
} else {
pthread_mutex_unlock(&once_lock);
UNLOCK(&once_lock);
}
}

Expand Down Expand Up @@ -709,7 +700,7 @@ static int defoshnd_wake_sig = -1;
#ifdef USE_PTHREADS
struct sel_lock_s
{
pthread_mutex_t lock;
lock_type lock;
};

sel_lock_t *defsel_lock_alloc(void *cb_data)
Expand All @@ -719,24 +710,24 @@ sel_lock_t *defsel_lock_alloc(void *cb_data)
l = malloc(sizeof(*l));
if (!l)
return NULL;
pthread_mutex_init(&l->lock, NULL);
LOCK_INIT(&l->lock);
return l;
}

void defsel_lock_free(sel_lock_t *l)
{
pthread_mutex_destroy(&l->lock);
LOCK_DESTROY(&l->lock);
free(l);
}

void defsel_lock(sel_lock_t *l)
{
pthread_mutex_lock(&l->lock);
LOCK(&l->lock);
}

void defsel_unlock(sel_lock_t *l)
{
pthread_mutex_unlock(&l->lock);
UNLOCK(&l->lock);
}

static pthread_once_t defos_once = PTHREAD_ONCE_INIT;
Expand Down
8 changes: 4 additions & 4 deletions lib/selector.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#endif

#ifdef OUT_OF_MEMORY_TEST
#include <pthread.h>
#include "pthread_handler.h"
#include <assert.h>
/*
* Some memory allocation failure testing. If the GENSIO_OOM_TEST
Expand All @@ -48,7 +48,7 @@
* (below); it will cause specific values to be returned on an exit
* failure.
*/
pthread_mutex_t oom_mutex = PTHREAD_MUTEX_INITIALIZER;
lock_type oom_mutex = LOCK_INITIALIZER;
int oom_initialized;
int oom_ready;
int triggered;
Expand All @@ -66,7 +66,7 @@ sel_alloc(unsigned int size)
{
int triggerit = 0;

pthread_mutex_lock(&oom_mutex);
LOCK(&oom_mutex);
if (!oom_initialized) {
char *s = getenv("GENSIO_OOM_TEST");

Expand All @@ -83,7 +83,7 @@ sel_alloc(unsigned int size)
triggerit = 1;
}
}
pthread_mutex_unlock(&oom_mutex);
UNLOCK(&oom_mutex);
if (triggerit)
return NULL;
}
Expand Down
6 changes: 3 additions & 3 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

AM_CFLAGS = -I$(top_srcdir)/include

utst_builddir = $(shell readlink -f $(top_builddir))
utst_srcdir = $(shell readlink -f $(top_srcdir))

Expand All @@ -9,8 +11,6 @@ AM_TESTS_ENVIRONMENT = \
$(utst_srcdir)/tests/make_keys; \
fi; GENSIOT=$(top_builddir)/tools/gensiot PYTHON=$(PYTHON)

AM_CFLAGS = -I$(top_srcdir)/include

test_setup:
echo "$(AM_TESTS_ENVIRONMENT) $(utst_srcdir)/tests/"

Expand Down Expand Up @@ -127,7 +127,7 @@ test_fuzz: test_fuzz_certauth test_fuzz_mux test_fuzz_ssl test_fuzz_telnet \

oomtest_SOURCES = oomtest.c

oomtest_LDADD = $(top_builddir)/lib/libgensio.la $(OPENSSL_LIBS)
oomtest_LDADD = $(top_builddir)/lib/libgensio.la $(OPENSSL_LIBS) -lpthread

noinst_PROGRAMS = oomtest

Expand Down
Loading

0 comments on commit 8918de5

Please sign in to comment.