Module: xenomai-forge
Branch: next
Commit: a36021cdf17298ef27830af5de651b0f92c6c663
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=a36021cdf17298ef27830af5de651b0f92c6c663

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu May  8 17:35:46 2014 +0200

copperplate/notifier: merge to threadobj building block

Now that the suspend/resume mechanism for Mercury is trivially simple,
just merge it into where it belongs to, i.e. in the threadobj
implementation.

---

 include/copperplate/Makefile.am |    1 -
 include/copperplate/Makefile.in |    1 -
 include/copperplate/notifier.h  |   55 ---------------------
 include/copperplate/threadobj.h |    2 -
 lib/copperplate/Makefile.am     |    1 -
 lib/copperplate/Makefile.in     |   50 ++++++++-----------
 lib/copperplate/notifier.c      |  103 ---------------------------------------
 lib/copperplate/threadobj.c     |   89 +++++++++++++++++++++++++--------
 8 files changed, 90 insertions(+), 212 deletions(-)

diff --git a/include/copperplate/Makefile.am b/include/copperplate/Makefile.am
index f721ff8..89b92ff 100644
--- a/include/copperplate/Makefile.am
+++ b/include/copperplate/Makefile.am
@@ -8,7 +8,6 @@ includesub_HEADERS =            \
        heapobj.h               \
        init.h                  \
        semobj.h                \
-       notifier.h              \
        reference.h             \
        registry.h              \
        syncobj.h               \
diff --git a/include/copperplate/Makefile.in b/include/copperplate/Makefile.in
index cc060cc..1db15f5 100644
--- a/include/copperplate/Makefile.in
+++ b/include/copperplate/Makefile.in
@@ -345,7 +345,6 @@ includesub_HEADERS = \
        heapobj.h               \
        init.h                  \
        semobj.h                \
-       notifier.h              \
        reference.h             \
        registry.h              \
        syncobj.h               \
diff --git a/include/copperplate/notifier.h b/include/copperplate/notifier.h
deleted file mode 100644
index 011accf..0000000
--- a/include/copperplate/notifier.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008 Philippe Gerum <r...@xenomai.org>.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
-
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
- */
-
-#ifndef _COPPERPLATE_NOTIFIER_H
-#define _COPPERPLATE_NOTIFIER_H
-
-#include <boilerplate/list.h>
-
-struct notifier {
-       pid_t owner;
-       struct pvholder link;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int notifier_init(struct notifier *nf, pid_t pid);
-
-static inline void notifier_destroy(struct notifier *nf)
-{
-}
-
-void notifier_destroy(struct notifier *nf);
-
-void notifier_signal(struct notifier *nf);
-
-void notifier_wait(void);
-
-void notifier_disable(struct notifier *nf);
-
-void notifier_release(struct notifier *nf);
-
-void notifier_pkg_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _COPPERPLATE_NOTIFIER_H */
diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index 754de3d..fd87829 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -77,14 +77,12 @@ void threadobj_save_timeout(struct threadobj_corespec 
*corespec,
 #else  /* CONFIG_XENO_MERCURY */
 
 #include <sys/time.h>
-#include <copperplate/notifier.h>
 
 struct threadobj_corespec {
        pthread_cond_t grant_sync;
        int policy_unlocked;
        int prio_unlocked;
        timer_t rr_timer;
-       struct notifier notifier;
        struct timespec wakeup;
        ticks_t period;
        /** Timeout reported by sysregd. */
diff --git a/lib/copperplate/Makefile.am b/lib/copperplate/Makefile.am
index 17ebeb4..2664e53 100644
--- a/lib/copperplate/Makefile.am
+++ b/lib/copperplate/Makefile.am
@@ -46,7 +46,6 @@ clean-local:
 libcopperplate_la_LIBADD = libversion.la
 
 if XENO_MERCURY
-libcopperplate_la_SOURCES += notifier.c
 libcopperplate_la_LIBADD += ../boilerplate/libboilerplate.la
 endif
 
diff --git a/lib/copperplate/Makefile.in b/lib/copperplate/Makefile.in
index a9b360e..0a948fe 100644
--- a/lib/copperplate/Makefile.in
+++ b/lib/copperplate/Makefile.in
@@ -79,17 +79,16 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-@XENO_MERCURY_TRUE@am__append_1 = notifier.c
-@XENO_MERCURY_TRUE@am__append_2 = ../boilerplate/libboilerplate.la
+@XENO_MERCURY_TRUE@am__append_1 = ../boilerplate/libboilerplate.la
+@XENO_REGISTRY_TRUE@am__append_2 = libregistry.la
 @XENO_REGISTRY_TRUE@am__append_3 = libregistry.la
-@XENO_REGISTRY_TRUE@am__append_4 = libregistry.la
 
 # The process shareable heap has real-time properties, therefore it
 # fits both the cobalt and mercury cores equally. Yummie.
-@XENO_PSHARED_TRUE@am__append_5 = heapobj-pshared.c reference.c
-@XENO_TLSF_TRUE@am__append_6 = heapobj-tlsf.c
-@XENO_TLSF_FALSE@am__append_7 = heapobj-malloc.c
-@XENO_REGISTRY_TRUE@am__append_8 = regd
+@XENO_PSHARED_TRUE@am__append_4 = heapobj-pshared.c reference.c
+@XENO_TLSF_TRUE@am__append_5 = heapobj-tlsf.c
+@XENO_TLSF_FALSE@am__append_6 = heapobj-malloc.c
+@XENO_REGISTRY_TRUE@am__append_7 = regd
 subdir = lib/copperplate
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
        $(top_srcdir)/config/depcomp COPYING
@@ -137,18 +136,17 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
-libcopperplate_la_DEPENDENCIES = libversion.la $(am__append_2) \
-       $(am__append_3)
+libcopperplate_la_DEPENDENCIES = libversion.la $(am__append_1) \
+       $(am__append_2)
 am__libcopperplate_la_SOURCES_DIST = clockobj.c cluster.c eventobj.c \
        init.c internal.c internal.h main.c syncobj.c semobj.c \
-       threadobj.c timerobj.c traceobj.c wrappers.c notifier.c \
-       heapobj-pshared.c reference.c heapobj-tlsf.c heapobj-malloc.c
-@XENO_MERCURY_TRUE@am__objects_1 = libcopperplate_la-notifier.lo
-@XENO_PSHARED_TRUE@am__objects_2 =  \
+       threadobj.c timerobj.c traceobj.c wrappers.c heapobj-pshared.c \
+       reference.c heapobj-tlsf.c heapobj-malloc.c
+@XENO_PSHARED_TRUE@am__objects_1 =  \
 @XENO_PSHARED_TRUE@    libcopperplate_la-heapobj-pshared.lo \
 @XENO_PSHARED_TRUE@    libcopperplate_la-reference.lo
-@XENO_TLSF_TRUE@am__objects_3 = libcopperplate_la-heapobj-tlsf.lo
-@XENO_TLSF_FALSE@am__objects_4 = libcopperplate_la-heapobj-malloc.lo
+@XENO_TLSF_TRUE@am__objects_2 = libcopperplate_la-heapobj-tlsf.lo
+@XENO_TLSF_FALSE@am__objects_3 = libcopperplate_la-heapobj-malloc.lo
 am_libcopperplate_la_OBJECTS = libcopperplate_la-clockobj.lo \
        libcopperplate_la-cluster.lo libcopperplate_la-eventobj.lo \
        libcopperplate_la-init.lo libcopperplate_la-internal.lo \
@@ -156,7 +154,7 @@ am_libcopperplate_la_OBJECTS = 
libcopperplate_la-clockobj.lo \
        libcopperplate_la-semobj.lo libcopperplate_la-threadobj.lo \
        libcopperplate_la-timerobj.lo libcopperplate_la-traceobj.lo \
        libcopperplate_la-wrappers.lo $(am__objects_1) \
-       $(am__objects_2) $(am__objects_3) $(am__objects_4)
+       $(am__objects_2) $(am__objects_3)
 libcopperplate_la_OBJECTS = $(am_libcopperplate_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -458,25 +456,25 @@ lib_LTLIBRARIES = libcopperplate.la
 libcopperplate_la_LDFLAGS = @XENO_LIB_LDFLAGS@ -version-info 0:0:0
 libcopperplate_la_SOURCES = clockobj.c cluster.c eventobj.c init.c \
        internal.c internal.h main.c syncobj.c semobj.c threadobj.c \
-       timerobj.c traceobj.c wrappers.c $(am__append_1) \
-       $(am__append_5) $(am__append_6) $(am__append_7)
+       timerobj.c traceobj.c wrappers.c $(am__append_4) \
+       $(am__append_5) $(am__append_6)
 libcopperplate_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@              \
        -I$(top_srcdir)                 \
        -I$(top_srcdir)/include         \
        -I$(top_srcdir)/lib
 
-noinst_LTLIBRARIES = libversion.la $(am__append_4)
+noinst_LTLIBRARIES = libversion.la $(am__append_3)
 libversion_la_CFLAGS = @XENO_USER_CFLAGS@
 libversion_la_SOURCES = version.c
-libcopperplate_la_LIBADD = libversion.la $(am__append_2) \
-       $(am__append_3)
+libcopperplate_la_LIBADD = libversion.la $(am__append_1) \
+       $(am__append_2)
 @XENO_REGISTRY_TRUE@libregistry_la_SOURCES = registry.c
 @XENO_REGISTRY_TRUE@libregistry_la_CPPFLAGS = \
 @XENO_REGISTRY_TRUE@   $(libcopperplate_la_CPPFLAGS)   \
 @XENO_REGISTRY_TRUE@   @XENO_FUSE_CFLAGS@
 
-SUBDIRS = . $(am__append_8)
+SUBDIRS = . $(am__append_7)
 SPARSE = sparse
 all: all-recursive
 
@@ -583,7 +581,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-init.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-internal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-main.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-notifier.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-reference.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-semobj.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ 
@am__quote@./$(DEPDIR)/libcopperplate_la-syncobj.Plo@am__quote@
@@ -699,13 +696,6 @@ libcopperplate_la-wrappers.lo: wrappers.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC 
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(libcopperplate_la_CPPFLAGS) $(CPPFLAGS) 
$(AM_CFLAGS) $(CFLAGS) -c -o libcopperplate_la-wrappers.lo `test -f 
'wrappers.c' || echo '$(srcdir)/'`wrappers.c
 
-libcopperplate_la-notifier.lo: notifier.c
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC 
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(libcopperplate_la_CPPFLAGS) $(CPPFLAGS) 
$(AM_CFLAGS) $(CFLAGS) -MT libcopperplate_la-notifier.lo -MD -MP -MF 
$(DEPDIR)/libcopperplate_la-notifier.Tpo -c -o libcopperplate_la-notifier.lo 
`test -f 'notifier.c' || echo '$(srcdir)/'`notifier.c
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) 
$(DEPDIR)/libcopperplate_la-notifier.Tpo 
$(DEPDIR)/libcopperplate_la-notifier.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='notifier.c' 
object='libcopperplate_la-notifier.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC 
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(libcopperplate_la_CPPFLAGS) $(CPPFLAGS) 
$(AM_CFLAGS) $(CFLAGS) -c -o libcopperplate_la-notifier.lo `test -f 
'notifier.c' || echo '$(srcdir)/'`notifier.c
-
 libcopperplate_la-heapobj-pshared.lo: heapobj-pshared.c
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC 
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(libcopperplate_la_CPPFLAGS) $(CPPFLAGS) 
$(AM_CFLAGS) $(CFLAGS) -MT libcopperplate_la-heapobj-pshared.lo -MD -MP -MF 
$(DEPDIR)/libcopperplate_la-heapobj-pshared.Tpo -c -o 
libcopperplate_la-heapobj-pshared.lo `test -f 'heapobj-pshared.c' || echo 
'$(srcdir)/'`heapobj-pshared.c
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) 
$(DEPDIR)/libcopperplate_la-heapobj-pshared.Tpo 
$(DEPDIR)/libcopperplate_la-heapobj-pshared.Plo
diff --git a/lib/copperplate/notifier.c b/lib/copperplate/notifier.c
deleted file mode 100644
index 0f02059..0000000
--- a/lib/copperplate/notifier.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2008 Philippe Gerum <r...@xenomai.org>.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
-
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
- */
-
-#include <signal.h>
-#include <memory.h>
-#include <errno.h>
-#include "copperplate/notifier.h"
-#include "boilerplate/signal.h"
-#include "internal.h"
-
-static void suspend_sighandler(int sig)
-{
-       notifier_wait();
-}
-
-static void resume_sighandler(int sig)
-{
-       /* nop */
-}
-
-int notifier_init(struct notifier *nf, pid_t pid)
-{
-       sigset_t set;
-
-       nf->owner = pid;
-       sigemptyset(&set);
-       sigaddset(&set, SIGRESM);
-       pthread_sigmask(SIG_BLOCK, &set, NULL);
-
-       return 0;
-}
-
-void notifier_signal(struct notifier *nf)
-{
-       copperplate_kill_tid(nf->owner, SIGSUSP);
-}
-
-void notifier_release(struct notifier *nf)
-{
-       copperplate_kill_tid(nf->owner, SIGRESM);
-}
-
-void notifier_wait(void)
-{
-       sigset_t set;
-
-       /*
-        * A suspended thread is supposed to do nothing but wait for
-        * the wake up signal, so we may happily block all signals but
-        * SIGRESM. Note that SIGRRB won't be accumulated during the
-        * sleep time anyhow, as the round-robin timer is based on
-        * CLOCK_THREAD_CPUTIME_ID, and we'll obviously don't consume
-        * any CPU time while blocked.
-        */
-       sigfillset(&set);
-       sigdelset(&set, SIGRESM);
-       sigsuspend(&set);
-}
-
-void notifier_disable(struct notifier *nf)
-{
-       /* Unblock any ongoing wait. */
-       copperplate_kill_tid(nf->owner, SIGRESM);
-}
-
-void notifier_pkg_init(void)
-{
-       struct sigaction sa;
-       /*
-        * We have two basic requirements for the notification
-        * scheme implementing the suspend/resume mechanism:
-        *
-        * - we have to rely on Linux signals for notification, which
-        * guarantees that the target thread will receive the suspend
-        * request asap, regardless of what it was doing when notified
-        * (syscall wait, pure runtime etc.).
-        *
-        * - we must process the suspension signal on behalf of the
-        * target thread, as we want that thread to block upon
-        * receipt.
-        */
-       memset(&sa, 0, sizeof(sa));
-       sa.sa_flags = SA_RESTART;
-       sa.sa_handler = suspend_sighandler;
-       sigaction(SIGSUSP, &sa, NULL);
-       sa.sa_handler = resume_sighandler;
-       sigaction(SIGRESM, &sa, NULL);
-}
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index 7a7f970..042828c 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -377,7 +377,6 @@ int threadobj_stat(struct threadobj *thobj, struct 
threadobj_stat *p) /* thobj->
 #else /* CONFIG_XENO_MERCURY */
 
 #include <sys/prctl.h>
-#include "copperplate/notifier.h"
 
 static int threadobj_lock_prio;
 
@@ -404,6 +403,33 @@ static void roundrobin_handler(int sig)
        sched_yield();
 }
 
+static void sleep_suspended(void)
+{
+       sigset_t set;
+
+       /*
+        * A suspended thread is supposed to do nothing but wait for
+        * the wake up signal, so we may happily block all signals but
+        * SIGRESM. Note that SIGRRB won't be accumulated during the
+        * sleep time anyhow, as the round-robin timer is based on
+        * CLOCK_THREAD_CPUTIME_ID, and we'll obviously don't consume
+        * any CPU time while blocked.
+        */
+       sigfillset(&set);
+       sigdelset(&set, SIGRESM);
+       sigsuspend(&set);
+}
+
+static void suspend_sighandler(int sig)
+{
+       sleep_suspended();
+}
+
+static void resume_sighandler(int sig)
+{
+       /* nop */
+}
+
 static inline void pkg_init_corespec(void)
 {
        struct sigaction sa;
@@ -422,8 +448,10 @@ static inline void pkg_init_corespec(void)
        sigaction(SIGRELS, &sa, NULL);
        sa.sa_handler = roundrobin_handler;
        sigaction(SIGRRB, &sa, NULL);
-
-       notifier_pkg_init();
+       sa.sa_handler = suspend_sighandler;
+       sigaction(SIGSUSP, &sa, NULL);
+       sa.sa_handler = resume_sighandler;
+       sigaction(SIGRESM, &sa, NULL);
 }
 
 static inline void threadobj_init_corespec(struct threadobj *thobj)
@@ -449,12 +477,27 @@ static inline void threadobj_uninit_corespec(struct 
threadobj *thobj)
 static inline int threadobj_setup_corespec(struct threadobj *thobj)
 {
        struct sigevent sev;
+       sigset_t set;
        int ret;
 
        prctl(PR_SET_NAME, (unsigned long)thobj->name, 0, 0, 0);
-       ret = notifier_init(&thobj->core.notifier, threadobj_get_pid(thobj));
-       if (ret)
-               return __bt(ret);
+
+       /*
+        * Do the per-thread setup for supporting the suspend/resume
+        * actions over Mercury. We have two basic requirements for
+        * this mechanism:
+        *
+        * - suspended requests must be handled asap, regardless of
+        * what the target thread is doing when notified (syscall
+        * wait, pure runtime etc.), hence the use of signals.
+        *
+        * - we must process the suspension signal on behalf of the
+        * target thread, as we want that thread to block upon
+        * receipt.
+        */
+       sigemptyset(&set);
+       sigaddset(&set, SIGRESM);
+       pthread_sigmask(SIG_BLOCK, &set, NULL);
 
        thobj->core.period = 0;
 
@@ -467,18 +510,14 @@ static inline int threadobj_setup_corespec(struct 
threadobj *thobj)
        sev.sigev_notify_thread_id = threadobj_get_pid(thobj);
        ret = timer_create(CLOCK_THREAD_CPUTIME_ID, &sev,
                           &thobj->core.rr_timer);
-       if (ret) {
-               ret = __bt(-errno);
-               notifier_destroy(&thobj->core.notifier);
-       }
+       if (ret)
+               return __bt(-errno);
 
        return 0;
 }
 
 static inline void threadobj_cleanup_corespec(struct threadobj *thobj)
 {
-       notifier_destroy(&thobj->core.notifier);
-
        if (thobj->core.rr_timer)
                timer_delete(thobj->core.rr_timer);
 }
@@ -492,11 +531,15 @@ static inline void threadobj_cancel_1_corespec(struct 
threadobj *thobj) /* thobj
        /*
         * If the target thread we are about to cancel gets suspended
         * while it is currently warming up, we have to unblock it
-        * from notifier_wait(), so that we don't get stuck in
+        * from sleep_suspended(), so that we don't get stuck in
         * cancel_sync(), waiting for a warmed up state which will
         * never come.
+        *
+        * Just send it SIGRESM unconditionally, this will either
+        * unblock it if the thread waits in sleep_suspended(), or
+        * lead to a nop since that signal is blocked otherwise.
         */
-       notifier_disable(&thobj->core.notifier);
+       copperplate_kill_tid(thobj->pid, SIGRESM);
 }
 
 static inline void threadobj_cancel_2_corespec(struct threadobj *thobj) /* 
thobj->lock held */
@@ -505,18 +548,22 @@ static inline void threadobj_cancel_2_corespec(struct 
threadobj *thobj) /* thobj
 
 int threadobj_suspend(struct threadobj *thobj) /* thobj->lock held */
 {
-       struct notifier *nf = &thobj->core.notifier;
-
        __threadobj_check_locked(thobj);
 
        if (thobj == threadobj_current()) {
                thobj->status |= __THREAD_S_SUSPENDED;
                threadobj_unlock(thobj);
-               notifier_wait();
+               sleep_suspended();
                threadobj_lock(thobj);
        } else if ((thobj->status & __THREAD_S_SUSPENDED) == 0) {
+               /*
+                * We prevent suspension requests from cumulating, so
+                * that we always have a flat, consistent sequence of
+                * alternate suspend/resume events. It's up to the
+                * client code to handle nested requests if need be.
+                */
                thobj->status |= __THREAD_S_SUSPENDED;
-               notifier_signal(nf);
+               copperplate_kill_tid(thobj->pid, SIGSUSP);
        }
 
        return 0;
@@ -529,7 +576,11 @@ int threadobj_resume(struct threadobj *thobj) /* 
thobj->lock held */
        if (thobj != threadobj_current() &&
            (thobj->status & __THREAD_S_SUSPENDED) != 0) {
                thobj->status &= ~__THREAD_S_SUSPENDED;
-               notifier_release(&thobj->core.notifier);
+               /*
+                * We prevent resumption requests from cumulating. See
+                * threadobj_suspend().
+                */
+               copperplate_kill_tid(thobj->pid, SIGRESM);
        }
 
        return 0;


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to