mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2024-11-23 11:49:50 +00:00
Remove the dependency on pthreads, and move dispatching to a separate translation unit
git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@663 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
parent
08a79a3aec
commit
a125325ca4
@ -1,5 +1,12 @@
|
||||
test-lite: test-lite.c kqlite.c lite.h
|
||||
gcc -D_GNU_SOURCE=1 -g -O0 -std=c99 -Wall -Werror -fopenmp -o test-lite test-lite.c kqlite.c
|
||||
gcc -D_GNU_SOURCE=1 -g -O0 -std=c99 -Wall -Werror -o test-lite test-lite.c kqlite.c
|
||||
|
||||
#TODO:
|
||||
test-dispatch: test-dispatch.c lite.h
|
||||
gcc -D_GNU_SOURCE=1 -g -O0 -std=c99 -Wall -Werror -fopenmp -o test-dispatch kqlite.c test-dispatch.c dispatch.c
|
||||
|
||||
check: test-lite
|
||||
./test-lite
|
||||
|
||||
clean:
|
||||
rm -f test-lite *.o
|
||||
|
47
kqlite/dispatch.c
Normal file
47
kqlite/dispatch.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Mark Heily <mark@heily.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif /* _OPENMP */
|
||||
|
||||
/*
|
||||
* EXPERIMENTAL dispatching API
|
||||
*/
|
||||
void
|
||||
kq_dispatch(kqueue_t kq, void (*cb)(kqueue_t, struct kevent))
|
||||
{
|
||||
const int maxevents = 64; /* Should be more like 2xNCPU */
|
||||
struct kevent events[maxevents];
|
||||
ssize_t nevents;
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
nevents = kq_event(kq, NULL, 0, (struct kevent *) &events, maxevents, NULL);
|
||||
if (nevents < 0)
|
||||
abort();
|
||||
#pragma omp parallel
|
||||
{
|
||||
for (i = 0; i < nevents; i++) {
|
||||
#pragma omp single nowait
|
||||
(*cb)(kq, events[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif /* _OPENMP */
|
||||
|
||||
#include "./lite.h"
|
||||
#include "./utarray.h"
|
||||
|
||||
@ -44,7 +40,6 @@
|
||||
#include <sys/event.h>
|
||||
#elif defined(__linux__)
|
||||
#define USE_EPOLL
|
||||
#include <pthread.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/signalfd.h>
|
||||
@ -52,6 +47,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef KQ_THREADSAFE
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
static char * epoll_event_to_str(struct epoll_event *);
|
||||
#else
|
||||
#error Unsupported operating system type
|
||||
@ -70,7 +69,17 @@ struct kqueue {
|
||||
the 'ident' parameter of the 'struct kevent' in the knote.
|
||||
*/
|
||||
UT_array *knote[EVFILT_SYSCOUNT];
|
||||
|
||||
/* This allows all kevents to share a single inotify descriptor.
|
||||
* Key: inotify watch descriptor returned by inotify_add_watch()
|
||||
* Value: pointer to knote
|
||||
*/
|
||||
UT_array *ino_knote;
|
||||
|
||||
#ifdef KQ_THREADSAFE
|
||||
pthread_mutex_t kq_mtx;
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error Undefined event system
|
||||
#endif
|
||||
@ -84,7 +93,7 @@ struct knote {
|
||||
struct kevent kev;
|
||||
union {
|
||||
int timerfd; /* Each EVFILT_TIMER kevent has a timerfd */
|
||||
int inofd; /* Each EVFILT_VNODE kevent has an inotify fd */
|
||||
int ino_wd; /* EVFILT_VNODE: index within kq->ino_knote */
|
||||
} aux;
|
||||
int deleted; /* When EV_DELETE is used, it marks the knote deleted instead of freeing the object. This helps with threadsafety by ensuring that threads don't try to access a freed object. It doesn't help with memory usage, as the memory is never reclaimed. */
|
||||
};
|
||||
@ -92,15 +101,19 @@ struct knote {
|
||||
static inline void
|
||||
kq_lock(kqueue_t kq)
|
||||
{
|
||||
#ifdef KQ_THREADSAFE
|
||||
if (pthread_mutex_lock(&kq->kq_mtx) != 0)
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
kq_unlock(kqueue_t kq)
|
||||
{
|
||||
#ifdef KQ_THREADSAFE
|
||||
if (pthread_mutex_unlock(&kq->kq_mtx) != 0)
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
UT_icd knote_icd = { sizeof(struct knote), NULL, NULL, NULL };
|
||||
@ -127,8 +140,10 @@ kq_init(void)
|
||||
if ((kq = malloc(sizeof(*kq))) == NULL)
|
||||
return (NULL);
|
||||
|
||||
#ifdef KQ_THREADSAFE
|
||||
if (pthread_mutex_init(&kq->kq_mtx, NULL) != 0)
|
||||
goto errout;
|
||||
#endif
|
||||
|
||||
/* Create an index of kevents to allow lookups from epev.data.u32 */
|
||||
|
||||
@ -457,31 +472,6 @@ int kq_event(kqueue_t kq, const struct kevent *changelist, int nchanges,
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* EXPERIMENTAL dispatching API
|
||||
*/
|
||||
void
|
||||
kq_dispatch(kqueue_t kq, void (*cb)(kqueue_t, struct kevent))
|
||||
{
|
||||
const int maxevents = 64; /* Should be more like 2xNCPU */
|
||||
struct kevent events[maxevents];
|
||||
ssize_t nevents;
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
nevents = kq_event(kq, NULL, 0, (struct kevent *) &events, maxevents, NULL);
|
||||
if (nevents < 0)
|
||||
abort();
|
||||
#pragma omp parallel
|
||||
{
|
||||
for (i = 0; i < nevents; i++) {
|
||||
#pragma omp single nowait
|
||||
(*cb)(kq, events[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_EPOLL)
|
||||
static char *
|
||||
epoll_event_to_str(struct epoll_event *evt)
|
||||
|
Loading…
Reference in New Issue
Block a user