[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