[Cbe-oss-dev] [PATCH 2/2] libspe2: Make speevent thread-safe
Kazunori Asayama
asayama at sm.sony.co.jp
Fri Nov 17 16:51:13 EST 2006
Attached is a patch to make the 'speevent' part of libspe2 thread-safe.
--
(ASAYAMA Kazunori
(asayama at sm.sony.co.jp))
t
-------------- next part --------------
Index: libspe2/speevent/Makefile
===================================================================
--- libspe2.orig/speevent/Makefile
+++ libspe2/speevent/Makefile
@@ -44,7 +44,7 @@ clean:
rm -f libspeevent.a
$(libspeevent_SO): $(libspeevent_OBJS)
- $(CC) $(CFLAGS) -shared -o $@ $^ -lrt -Wl,--soname=${libspeevent_SONAME}
+ $(CC) $(CFLAGS) -shared -o $@ $^ -lrt -lpthread -Wl,--soname=${libspeevent_SONAME}
$(libspeevent_A): $(libspeevent_OBJS)
$(CROSS)ar -r $(libspeevent_A) $(libspeevent_OBJS) ../spebase/*.o
Index: libspe2/speevent/spe_event.c
===================================================================
--- libspe2.orig/speevent/spe_event.c
+++ libspe2/speevent/spe_event.c
@@ -42,6 +42,16 @@
( (spe)->event_private = (evctx) )
+void _event_spe_context_lock(spe_context_ptr_t spe)
+{
+ pthread_mutex_lock(&__SPE_EVENT_CONTEXT_PRIV_GET(spe)->lock);
+}
+
+void _event_spe_context_unlock(spe_context_ptr_t spe)
+{
+ pthread_mutex_unlock(&__SPE_EVENT_CONTEXT_PRIV_GET(spe)->lock);
+}
+
int _event_spe_stop_info_read (spe_context_ptr_t spe, spe_stop_info_t *stopinfo)
{
spe_context_event_priv_ptr_t evctx;
@@ -146,19 +156,23 @@ int _event_spe_event_handler_register(sp
return -1;
}
+ _event_spe_context_lock(event->spe); /* for spe->event_private->events */
+
if (event->events & SPE_EVENT_OUT_INTR_MBOX) {
fd = __base_spe_event_source_acquire(event->spe, FD_IBOX);
if (fd == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
ev_buf = &evctx->events[__SPE_EVENT_OUT_INTR_MBOX];
- *ev_buf = *event;
ev_buf->events = SPE_EVENT_OUT_INTR_MBOX;
+ ev_buf->data = event->data;
ep_event.events = EPOLLIN;
ep_event.data.ptr = ev_buf;
if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
}
@@ -166,16 +180,18 @@ int _event_spe_event_handler_register(sp
if (event->events & SPE_EVENT_IN_MBOX) {
fd = __base_spe_event_source_acquire(event->spe, FD_WBOX);
if (fd == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
ev_buf = &evctx->events[__SPE_EVENT_IN_MBOX];
- *ev_buf = *event;
ev_buf->events = SPE_EVENT_IN_MBOX;
+ ev_buf->data = event->data;
ep_event.events = EPOLLOUT;
ep_event.data.ptr = ev_buf;
if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
}
@@ -183,16 +199,18 @@ int _event_spe_event_handler_register(sp
if (event->events & SPE_EVENT_TAG_GROUP) {
fd = __base_spe_event_source_acquire(event->spe, FD_MFC);
if (fd == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
ev_buf = &evctx->events[__SPE_EVENT_TAG_GROUP];
- *ev_buf = *event;
ev_buf->events = SPE_EVENT_TAG_GROUP;
+ ev_buf->data = event->data;
ep_event.events = EPOLLIN;
ep_event.data.ptr = ev_buf;
if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
}
@@ -201,16 +219,19 @@ int _event_spe_event_handler_register(sp
fd = evctx->stop_event_pipe[0];
ev_buf = &evctx->events[__SPE_EVENT_SPE_STOPPED];
- *ev_buf = *event;
ev_buf->events = SPE_EVENT_SPE_STOPPED;
+ ev_buf->data = event->data;
ep_event.events = EPOLLIN;
ep_event.data.ptr = ev_buf;
if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
}
+ _event_spe_context_unlock(event->spe);
+
return 0;
}
/*
@@ -240,13 +261,17 @@ int _event_spe_event_handler_deregister(
errno = ENOTSUP;
return -1;
}
+
+ _event_spe_context_lock(event->spe); /* for spe->event_private->events */
if (event->events & SPE_EVENT_OUT_INTR_MBOX) {
fd = __base_spe_event_source_acquire(event->spe, FD_IBOX);
if (fd == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
evctx->events[__SPE_EVENT_OUT_INTR_MBOX].events = 0;
@@ -255,9 +280,11 @@ int _event_spe_event_handler_deregister(
if (event->events & SPE_EVENT_IN_MBOX) {
fd = __base_spe_event_source_acquire(event->spe, FD_WBOX);
if (fd == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
evctx->events[__SPE_EVENT_IN_MBOX].events = 0;
@@ -266,9 +293,11 @@ int _event_spe_event_handler_deregister(
if (event->events & SPE_EVENT_TAG_GROUP) {
fd = __base_spe_event_source_acquire(event->spe, FD_MFC);
if (fd == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
evctx->events[__SPE_EVENT_TAG_GROUP].events = 0;
@@ -277,11 +306,14 @@ int _event_spe_event_handler_deregister(
if (event->events & SPE_EVENT_SPE_STOPPED) {
fd = evctx->stop_event_pipe[0];
if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) {
+ _event_spe_context_unlock(event->spe);
return -1;
}
evctx->events[__SPE_EVENT_SPE_STOPPED].events = 0;
}
+ _event_spe_context_unlock(event->spe);
+
return 0;
}
@@ -315,7 +347,10 @@ int _event_spe_event_wait(spe_event_hand
if (rc > 0) {
int i;
for (i = 0; i < rc; i++) {
- events[i] = *(spe_event_unit_t *)(ep_events[i].data.ptr);
+ spe_event_unit_t *ev = (spe_event_unit_t *)(ep_events[i].data.ptr);
+ _event_spe_context_lock(ev->spe); /* lock ev itself */
+ events[i] = *ev;
+ _event_spe_context_unlock(ev->spe);
}
}
@@ -339,6 +374,8 @@ int _event_spe_context_finalize(spe_cont
close(evctx->stop_event_pipe[0]);
close(evctx->stop_event_pipe[1]);
+ pthread_mutex_destroy(&evctx->lock);
+
free(evctx);
return 0;
@@ -348,6 +385,7 @@ struct spe_context_event_priv * _event_s
{
spe_context_event_priv_ptr_t evctx;
int rc;
+ int i;
evctx = calloc(1, sizeof(*evctx));
if (!evctx) {
@@ -360,6 +398,12 @@ struct spe_context_event_priv * _event_s
return NULL;
}
+ for (i = 0; i < sizeof(evctx->events) / sizeof(evctx->events[0]); i++) {
+ evctx->events[i].spe = spe;
+ }
+
+ pthread_mutex_init(&evctx->lock, NULL);
+
return evctx;
}
Index: libspe2/speevent/speevent.h
===================================================================
--- libspe2.orig/speevent/speevent.h
+++ libspe2/speevent/speevent.h
@@ -34,6 +34,7 @@ enum __spe_event_types {
/* private types */
typedef struct spe_context_event_priv
{
+ pthread_mutex_t lock;
int stop_event_pipe[2];
spe_event_unit_t events[__NUM_SPE_EVENT_TYPES];
} spe_context_event_priv_t, *spe_context_event_priv_ptr_t;
@@ -77,4 +78,7 @@ struct spe_context_event_priv * _event_s
int _event_spe_context_run (spe_context_ptr_t spe, unsigned int *entry, unsigned int runflags, void *argp, void *envp, spe_stop_info_t *stopinfo);
+void _event_spe_context_lock(spe_context_ptr_t spe);
+void _event_spe_context_unlock(spe_context_ptr_t spe);
+
#endif /*SPEEVENT_H_*/
More information about the cbe-oss-dev
mailing list