All of lore.kernel.org
 help / color / mirror / Atom feed
From: Philippe Gerum <rpm@xenomai.org>
To: Filip Van Rillaer <Filip.VanRillaer@domain.hid>
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] help: pipe + event flag group (or other	synchronisation mechanism
Date: Thu, 26 Jun 2008 13:38:41 +0200	[thread overview]
Message-ID: <48637FC1.2050708@domain.hid> (raw)
In-Reply-To: <406CC9939904F143B9D42CEEA3E56E563331EA@oab1mx1.oneaccess.intra>

[-- Attachment #1: Type: text/plain, Size: 1835 bytes --]

Filip Van Rillaer wrote:
> Hello, 
> 
> Our application is written with some kind of super-loop scheduling : we
> have many drivers that call rt_event_signal (when data have been written
> to the hardware or new data are available to be processed) and 1 task
> that is calling rt_event_wait. After receiving an event, the superloop
> task is then reading/writing the data from/to the appropriate
> driver. Those calls to the drivers must never block (except to some
> locking to protect the consistency of data-structures) to garantuee the
> real-time behaviour of the application.
> Now we want to communicate with the Linux-domain and thought we have to
> use the Xenomai pipe-object for that purpose.
> 
> How can the superloop task in Xenomai receive an event from
> the pipe-object when data are available to be read/written (so
> without already reading the data)?
> 
> The ideal solution would be if one can ask the pipe-driver to call a
> user-callback function when there is a change in the status (read/write)
> or an equivalent system to the EPOLL interface (from the uclinux domain).

There is a mechanism already available from the core message pipe
implementation, but it is not exported by the native API interface.

So you have two options:

- ask user-space to notify kernel space explicitly _after_ each sending; for
that you may even use rt_event_signal() from a plain Linux task to send a
specialized event to your superloop.

- try the attached patch, which exports the needed bits. It is called
rt_pipe_monitor(). Absolutely untested.

> 
> Best regards,
> Filip.
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help


-- 
Philippe.

[-- Attachment #2: async-pipe-monitoring.patch --]
[-- Type: text/x-diff, Size: 4590 bytes --]

Index: include/native/pipe.h
===================================================================
--- include/native/pipe.h	(revision 3989)
+++ include/native/pipe.h	(working copy)
@@ -32,6 +32,9 @@
 
 #define P_MINOR_AUTO	XNPIPE_MINOR_AUTO
 
+#define P_EVENT_INPUT	1
+#define P_EVENT_CLOSE	2
+
 typedef struct rt_pipe_placeholder {
     xnhandle_t opaque;
 } RT_PIPE_PLACEHOLDER;
@@ -64,6 +67,8 @@
 
     xnheap_t *bufpool;         /* !< Current buffer pool. */
 
+    void (*monitor)(struct rt_pipe *pipe, int event);
+
     xnheap_t privpool;         /* !< Private buffer pool. */
 
     size_t fillsz;		/* !< Bytes written to the buffer.  */
@@ -139,6 +144,9 @@
 int rt_pipe_flush(RT_PIPE *pipe,
 		  int mode);
 
+int rt_pipe_monitor(RT_PIPE *pipe,
+		    void (*fn)(RT_PIPE *pipe, int event));
+
 #ifdef CONFIG_XENO_OPT_NATIVE_PIPE
 
 int __native_pipe_pkg_init(void);
Index: ksrc/skins/native/pipe.c
===================================================================
--- ksrc/skins/native/pipe.c	(revision 3989)
+++ ksrc/skins/native/pipe.c	(working copy)
@@ -115,6 +115,28 @@
 	return retval;
 }
 
+static int __pipe_input_handler(int bminor,
+				xnpipe_mh_t *mh, int retval, void *cookie)
+{
+	RT_PIPE *pipe = (RT_PIPE *)cookie;
+	
+	if (pipe->monitor == NULL)
+		return retval;
+
+	if (retval == 0)
+		/* Callee may alter the return value passed to userland. */
+		retval = pipe->monitor(pipe, P_EVENT_INPUT);
+	else if (retval == -EPIPE)
+		pipe->monitor(pipe, P_EVENT_CLOSE);
+
+	/*
+	 * We don't notify the kernel endpoint about userland errors,
+	 * such as passing invalid buffer addresses (i.e. -EFAULT).
+	 */
+
+	return retval;
+}
+
 int __native_pipe_pkg_init(void)
 {
 	return 0;
@@ -229,6 +251,7 @@
 	pipe->buffer = NULL;
 	pipe->bufpool = &kheap;
 	pipe->fillsz = 0;
+	pipe->monitor = NULL;
 	pipe->status = 0;
 	pipe->handle = 0;	/* i.e. (still) unregistered pipe. */
 	pipe->magic = XENO_PIPE_MAGIC;
@@ -274,7 +297,7 @@
 
 	minor = xnpipe_connect(minor,
 			       &__pipe_output_handler,
-			       NULL, &__pipe_alloc_handler, pipe);
+			       &__pipe_input_handler, &__pipe_alloc_handler, pipe);
 
 	if (minor < 0) {
 		if (pipe->bufpool == &pipe->privpool)
@@ -372,7 +395,7 @@
 	}
 
 	removeq(pipe->rqueue, &pipe->rlink);
-
+	pipe->monitor = NULL;	/* Stop monitoring. */
 	err = xnpipe_disconnect(pipe->minor);
 
 	if (pipe->buffer != NULL) {
@@ -1049,6 +1072,74 @@
 	return xnpipe_flush(minor, mode);
 }
 
+/**
+ * @fn int rt_pipe_monitor(RT_PIPE *pipe, int (*fn)(RT_PIPE *pipe, int event))
+ *
+ * @brief Monitor a message pipe asynchronously.
+ *
+ * This service registers a notifier callback that will be called upon
+ * specific events occurring on the channel.  rt_pipe_monitor() is
+ * particularly useful to monitor a channel asynchronously while
+ * performing other tasks.
+ *
+ * @param pipe The descriptor address of the pipe to monitor.
+ *
+ * @param fn The notification handler. This user-provided routine will
+ * be passed the address of the message pipe descriptor receiving the
+ * event, and the event code.  Two events are currently defined:
+ *
+ * - P_EVENT_INPUT is sent when the user-space endpoint writes to the
+ *   pipe.
+ *
+ * - P_EVENT_CLOSE is sent when the user-space endpoint is closed.
+ *
+ * The notification handler is called on behalf of a fully atomic
+ * context; therefore, care must be taken to keep its overhead
+ * low. The Xenomai services that may be called from a notification
+ * handler are restricted to the set allowed to a real-time interrupt
+ * handler.
+ *
+ * @return Zero is returned upon success. Otherwise:
+ *
+ * - -EINVAL is returned if @a pipe is not a pipe descriptor.
+ *
+ * - -EIDRM is returned if @a pipe is a closed pipe descriptor.
+ *
+ * - -ENODEV or -EBADF are returned if @a pipe is scrambled.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Kernel-based task
+ *
+ * Rescheduling: never.
+ */
+
+int rt_pipe_monitor(RT_PIPE *pipe, void (*fn)(RT_PIPE *pipe, int event))
+{
+	int minor, err;
+	spl_t s;
+
+	xnlock_get_irqsave(&nklock, s);
+
+	pipe = xeno_h2obj_validate(pipe, XENO_PIPE_MAGIC, RT_PIPE);
+
+	if (!pipe) {
+		err = xeno_handle_error(pipe, XENO_PIPE_MAGIC, RT_PIPE);
+		xnlock_put_irqrestore(&nklock, s);
+		return err;
+	}
+
+	pipe->monitor = fn;
+
+	xnlock_put_irqrestore(&nklock, s);
+
+	return 0;
+	
+}
+
 /*@}*/
 
 EXPORT_SYMBOL(rt_pipe_create);
@@ -1061,3 +1152,4 @@
 EXPORT_SYMBOL(rt_pipe_alloc);
 EXPORT_SYMBOL(rt_pipe_free);
 EXPORT_SYMBOL(rt_pipe_flush);
+EXPORT_SYMBOL(rt_pipe_monitor);

  reply	other threads:[~2008-06-26 11:38 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-26 10:05 [Xenomai-help] help: pipe + event flag group (or other synchronisation mechanism Filip Van Rillaer
2008-06-26 11:38 ` Philippe Gerum [this message]
2008-06-26 22:00 ` Gilles Chanteperdrix

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48637FC1.2050708@domain.hid \
    --to=rpm@xenomai.org \
    --cc=Filip.VanRillaer@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.