All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] help: pipe + event flag group (or other synchronisation mechanism
@ 2008-06-26 10:05 Filip Van Rillaer
  2008-06-26 11:38 ` Philippe Gerum
  2008-06-26 22:00 ` Gilles Chanteperdrix
  0 siblings, 2 replies; 3+ messages in thread
From: Filip Van Rillaer @ 2008-06-26 10:05 UTC (permalink / raw)
  To: xenomai

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

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).

Best regards,
Filip.


[-- Attachment #2: Type: text/html, Size: 1915 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Xenomai-help] help: pipe + event flag group (or other synchronisation mechanism
  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
  2008-06-26 22:00 ` Gilles Chanteperdrix
  1 sibling, 0 replies; 3+ messages in thread
From: Philippe Gerum @ 2008-06-26 11:38 UTC (permalink / raw)
  To: Filip Van Rillaer; +Cc: xenomai

[-- 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);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Xenomai-help] help: pipe + event flag group (or other synchronisation mechanism
  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
@ 2008-06-26 22:00 ` Gilles Chanteperdrix
  1 sibling, 0 replies; 3+ messages in thread
From: Gilles Chanteperdrix @ 2008-06-26 22:00 UTC (permalink / raw)
  To: Filip Van Rillaer; +Cc: xenomai

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).

Xenomai posix skin has support for the "select" call, which requires
some support from each driver, and you can already select from a posix
message queue. This is another solution.

-- 


					    Gilles.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-06-26 22:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2008-06-26 22:00 ` Gilles Chanteperdrix

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.