All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [PATCH] private heaps for native pipes
@ 2005-11-25 18:24 Jan Kiszka
  2005-11-25 18:34 ` Philippe Gerum
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Kiszka @ 2005-11-25 18:24 UTC (permalink / raw)
  To: xenomai-core

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

Hi,

this is basically the last version of my rt_pipe_create-ext patch to add
private, user-resizeable heaps to native pipes. Joerg has tested this
patch successfully under the 2.1 trunk, and I added a ChangeLog snippet.
Attached both 2.0.x and 2.1.x patches - please apply at least the 2.1
variant.

Jan

[-- Attachment #2: rt_pipe_create-ext.patch-2.0 --]
[-- Type: text/plain, Size: 12426 bytes --]

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 182)
+++ ChangeLog	(working copy)
@@ -1,3 +1,12 @@
+2005-11-25  Jan Kiszka <jan.kiszka@domain.hid>
+
+	* skins/native/{pipe.c,pipe.h,syscall.c,lib/pipe.c}: Added poolsize
+	parameter to rt_pipe_create for setting up pipes with private buffer
+	pools of user-defined size. Also, the addressed pipe has to be passed
+	to rt_pipe_alloc and rt_pipe_free now.
+
+	* testsuite/klatency/latency-module.c: Adapted to rt_pipe_* changes.
+
 2005-11-21  Philippe Gerum  <rpm@xenomai.org>
 
 	* skins/native, nucleus/pipe.c: Globally replace ENOSPC by
Index: skins/native/pipe.h
===================================================================
--- skins/native/pipe.h	(revision 182)
+++ skins/native/pipe.h	(working copy)
@@ -37,6 +37,8 @@
 
 #ifdef __KERNEL__
 
+#include <nucleus/heap.h>
+
 #define XENO_PIPE_MAGIC 0x55550202
 
 typedef xnpipe_mh_t RT_PIPE_MSG;
@@ -57,6 +59,10 @@
 
     RT_PIPE_MSG *buffer;	/* !< Buffer used in byte stream mode. */
 
+    xnheap_t *bufpool;		/* !< Current buffer pool. */
+
+    xnheap_t privpool;		/* !< Private buffer pool. */
+
     size_t fillsz;		/* !< Bytes written to the buffer.  */
 
     u_long flushable;		/* !< Flush request flag. */
@@ -85,7 +91,8 @@
 
 int rt_pipe_create(RT_PIPE *pipe,
 		   const char *name,
-		   int minor);
+		   int minor,
+		   size_t poolsize);
 
 int rt_pipe_delete(RT_PIPE *pipe);
 
@@ -113,9 +120,11 @@
 		     size_t size,
 		     int mode);
 
-RT_PIPE_MSG *rt_pipe_alloc(size_t size);
+RT_PIPE_MSG *rt_pipe_alloc(RT_PIPE *pipe,
+                           size_t size);
 
-int rt_pipe_free(RT_PIPE_MSG *msg);
+int rt_pipe_free(RT_PIPE *pipe,
+                 RT_PIPE_MSG *msg);
 
 ssize_t rt_pipe_flush(RT_PIPE *pipe);
 
Index: skins/native/syscall.c
===================================================================
--- skins/native/syscall.c	(revision 182)
+++ skins/native/syscall.c	(working copy)
@@ -3194,6 +3194,7 @@
     char name[XNOBJECT_NAME_LEN];
     RT_PIPE_PLACEHOLDER ph;
     int err, minor;
+    size_t poolsize;
     RT_PIPE *pipe;
 
     if (!__xn_access_ok(curr,VERIFY_WRITE,__xn_reg_arg1(regs),sizeof(ph)))
@@ -3213,12 +3214,15 @@
     /* Device minor. */
     minor = (int)__xn_reg_arg3(regs);
 
+    /* Buffer pool size. */
+    poolsize = (size_t)__xn_reg_arg4(regs);
+
     pipe = (RT_PIPE *)xnmalloc(sizeof(*pipe));
 
     if (!pipe)
 	return -ENOMEM;
 
-    err = rt_pipe_create(pipe,name,minor);
+    err = rt_pipe_create(pipe,name,minor,poolsize);
 
     if (err == 0)
 	{
@@ -3332,7 +3336,7 @@
     /* Zero-sized messages are allowed, so we still need to free the
        message buffer even if no data copy took place. */
 
-    rt_pipe_free(msg);
+    rt_pipe_free(pipe,msg);
 
     return err;
 }
@@ -3374,7 +3378,7 @@
     if (!__xn_access_ok(curr,VERIFY_READ,__xn_reg_arg2(regs),size))
 	return -EFAULT;
 
-    msg = rt_pipe_alloc(size);
+    msg = rt_pipe_alloc(pipe,size);
 	
     if (!msg)
 	return -ENOMEM;
@@ -3386,7 +3390,7 @@
     if (err != size)
 	/* If the operation failed, we need to free the message buffer
 	   by ourselves. */
-	rt_pipe_free(msg);
+	rt_pipe_free(pipe,msg);
 
     return err;
 }
@@ -3436,7 +3440,7 @@
 	}
     else
 	{
-	msg = rt_pipe_alloc(size);
+	msg = rt_pipe_alloc(pipe,size);
 	
 	if (!msg)
 	    return -ENOMEM;
@@ -3449,7 +3453,7 @@
     err = rt_pipe_stream(pipe,buf,size);
 
     if (msg)
-	rt_pipe_free(msg);
+	rt_pipe_free(pipe,msg);
 
     return err;
 }
@@ -3595,7 +3599,7 @@
     [__xeno_intr_enable ] = { &__rt_intr_enable, __xn_exec_any },
     [__xeno_intr_disable ] = { &__rt_intr_disable, __xn_exec_any },
     [__xeno_intr_inquire ] = { &__rt_intr_inquire, __xn_exec_any },
-    [__xeno_pipe_create ] = { &__rt_pipe_create, __xn_exec_any },
+    [__xeno_pipe_create ] = { &__rt_pipe_create, __xn_exec_lostage },
     [__xeno_pipe_bind ] = { &__rt_pipe_bind, __xn_exec_conforming },
     [__xeno_pipe_delete ] = { &__rt_pipe_delete, __xn_exec_any },
     [__xeno_pipe_read ] = { &__rt_pipe_read, __xn_exec_primary },
Index: skins/native/lib/pipe.c
===================================================================
--- skins/native/lib/pipe.c	(revision 182)
+++ skins/native/lib/pipe.c	(working copy)
@@ -23,13 +23,15 @@
 
 int rt_pipe_create (RT_PIPE *pipe,
 		    const char *name,
-		    int minor)
+		    int minor,
+		    size_t poolsize)
 {
-    return XENOMAI_SKINCALL3(__xeno_muxid,
+    return XENOMAI_SKINCALL4(__xeno_muxid,
 			     __xeno_pipe_create,
 			     pipe,
 			     name,
-			     minor);
+			     minor,
+			     poolsize);
 }
 
 int rt_pipe_bind (RT_PIPE *pipe,
Index: skins/native/pipe.c
===================================================================
--- skins/native/pipe.c	(revision 182)
+++ skins/native/pipe.c	(working copy)
@@ -50,8 +50,6 @@
 #include <native/registry.h>
 #include <native/pipe.h>
 
-static xnheap_t *__pipe_heap = &kheap;
-
 static int __pipe_flush_apc;
 
 static DECLARE_XNQUEUE(__pipe_flush_q);
@@ -83,6 +81,14 @@
 
 #endif /* CONFIG_XENO_NATIVE_EXPORT_REGISTRY */
 
+static void __pipe_flush_pool (xnheap_t *heap,
+                               void *poolmem,
+                               u_long poolsize,
+                               void *cookie)
+{
+    xnarch_sysfree(poolmem,poolsize);
+}
+
 static inline ssize_t __pipe_flush (RT_PIPE *pipe)
 
 {
@@ -122,8 +128,10 @@
 				   size_t size,
 				   void *cookie)
 {
+    RT_PIPE *pipe = (RT_PIPE *)cookie;
+
     /* Allocate memory for the incoming message. */
-    return xnheap_alloc(__pipe_heap,size);
+    return xnheap_alloc(pipe->bufpool,size);
 }
 
 static int __pipe_output_handler (int bminor,
@@ -131,8 +139,10 @@
 				  int retval,
 				  void *cookie)
 {
+    RT_PIPE *pipe = (RT_PIPE *)cookie;
+
     /* Free memory from output/discarded message. */
-    xnheap_free(__pipe_heap,mh);
+    xnheap_free(pipe->bufpool,mh);
     return retval;
 }
 
@@ -154,7 +164,7 @@
 }
 
 /**
- * @fn int rt_pipe_create(RT_PIPE *pipe,const char *name,int minor)
+ * @fn int rt_pipe_create(RT_PIPE *pipe,const char *name,int minor, size_t poolsize)
  * @brief Create a message pipe.
  *
  * This service opens a bi-directional communication channel allowing
@@ -201,6 +211,10 @@
  * /proc/xenomai/registry/pipes/@a name to the allocated pipe device
  * entry (i.e. /dev/rtp*).
  *
+ * @param poolsize Specifies the size of a dedicated buffer pool for the
+ * pipe. Passing 0 means that all message allocations for this pipe are
+ * performed on the system heap.
+ *
  * @return 0 is returned upon success. Otherwise:
  *
  * - -ENOMEM is returned if the system fails to get enough dynamic
@@ -232,20 +246,55 @@
 
 int rt_pipe_create (RT_PIPE *pipe,
 		    const char *name,
-		    int minor)
+		    int minor,
+		    size_t poolsize)
 {
     int err = 0;
+    void *poolmem;
 
-    if (xnpod_asynch_p())
+    if (!xnpod_root_p())
 	return -EPERM;
 
     pipe->buffer = NULL;
+    pipe->bufpool = &kheap;
     pipe->fillsz = 0;
     pipe->flushable = 0;
     pipe->handle = 0;    /* i.e. (still) unregistered pipe. */
     pipe->magic = XENO_PIPE_MAGIC;
     xnobject_copy_name(pipe->name,name);
 
+    if (poolsize > 0)
+	{
+	/* Make sure we won't hit trivial argument errors when calling
+	   xnheap_init(). */
+
+	if (poolsize < 2 * PAGE_SIZE)
+	    poolsize = 2 * PAGE_SIZE;
+
+	/* Account for the overhead so that the actual free space is large
+	   enough to match the requested size. */
+
+	poolsize += xnheap_overhead(poolsize,PAGE_SIZE);
+	poolsize = PAGE_ALIGN(poolsize);
+
+	poolmem = xnarch_sysalloc(poolsize);
+
+	if (!poolmem)
+	    return -ENOMEM;
+
+	err = xnheap_init(&pipe->privpool,
+	                  poolmem,
+	                  poolsize,
+	                  PAGE_SIZE); /* Use natural page size */
+	if (err)
+	    {
+	    xnarch_sysfree(poolmem,poolsize);
+	    return err;
+	    }
+
+	pipe->bufpool = &pipe->privpool;
+	}
+
     minor = xnpipe_connect(minor,
 			 &__pipe_output_handler,
 			 NULL,
@@ -253,7 +302,12 @@
 			 pipe);
 
     if (minor < 0)
+	{
+	if (pipe->bufpool == &pipe->privpool)
+	    xnheap_destroy(&pipe->privpool,__pipe_flush_pool,NULL);
+
 	return minor;
+	}
 
     pipe->minor = minor;
 
@@ -337,14 +391,15 @@
     if (!pipe)
 	{
 	err = xeno_handle_error(pipe,XENO_PIPE_MAGIC,RT_PIPE);
-	goto unlock_and_exit;
+	xnlock_put_irqrestore(&nklock,s);
+	return err;
 	}
 
     if (__test_and_clear_bit(0,&pipe->flushable))
 	{
 	/* Purge data waiting for flush. */
 	removeq(&__pipe_flush_q,&pipe->link);
-	rt_pipe_free(pipe->buffer);
+	rt_pipe_free(pipe,pipe->buffer);
 	}
 
     err = xnpipe_disconnect(pipe->minor);
@@ -356,10 +411,11 @@
 
     xeno_mark_deleted(pipe);
 
- unlock_and_exit:
-
     xnlock_put_irqrestore(&nklock,s);
 
+    if (pipe->bufpool == &pipe->privpool)
+	xnheap_destroy(&pipe->privpool,__pipe_flush_pool,NULL);
+
     return err;
 }
 
@@ -572,7 +628,7 @@
     /* Zero-sized messages are allowed, so we still need to free the
        message buffer even if no data copy took place. */
 
-    rt_pipe_free(msg);
+    rt_pipe_free(pipe,msg);
 
     return nbytes;
 }
@@ -767,7 +823,7 @@
 	/* Try flushing the streaming buffer in any case. */
 	return rt_pipe_send(pipe,NULL,0,mode);
 
-    msg = rt_pipe_alloc(size);
+    msg = rt_pipe_alloc(pipe,size);
 	
     if (!msg)
 	return -ENOMEM;
@@ -779,7 +835,7 @@
     if (nbytes != size)
 	/* If the operation failed, we need to free the message buffer
 	   by ourselves. */
-	rt_pipe_free(msg);
+	rt_pipe_free(pipe,msg);
 
     return nbytes;
 }
@@ -886,7 +942,7 @@
 
 	if (pipe->buffer == NULL)
 	    {
-	    pipe->buffer = rt_pipe_alloc(CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ);
+	    pipe->buffer = rt_pipe_alloc(pipe,CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ);
 
 	    if (pipe->buffer == NULL)
 		{
@@ -984,15 +1040,17 @@
 }
 
 /**
- * @fn RT_PIPE_MSG *rt_pipe_alloc(size_t size)
+ * @fn RT_PIPE_MSG *rt_pipe_alloc(RT_PIPE *pipe,size_t size)
  *
  * @brief Allocate a message pipe buffer.
  *
- * This service allocates a message buffer from the system heap which
+ * This service allocates a message buffer from the pipe's heap which
  * can be subsequently filled by the caller then passed to
  * rt_pipe_send() for sending. The beginning of the available data
  * area of @a size contiguous bytes is accessible from P_MSGPTR(msg).
  *
+ * @param pipe The descriptor address of the affected pipe.
+ *
  * @param size The requested size in bytes of the buffer. This value
  * should represent the size of the payload data.
  *
@@ -1010,10 +1068,11 @@
  * Rescheduling: never.
  */
 
-RT_PIPE_MSG *rt_pipe_alloc (size_t size)
+RT_PIPE_MSG *rt_pipe_alloc (RT_PIPE *pipe,
+                            size_t size)
 
 {
-    RT_PIPE_MSG *msg = (RT_PIPE_MSG *)xnheap_alloc(__pipe_heap,size + sizeof(RT_PIPE_MSG));
+    RT_PIPE_MSG *msg = (RT_PIPE_MSG *)xnheap_alloc(pipe->bufpool,size + sizeof(RT_PIPE_MSG));
 
     if (msg)
 	{
@@ -1025,13 +1084,15 @@
 }
 
 /**
- * @fn int rt_pipe_free(RT_PIPE_MSG *msg)
+ * @fn int rt_pipe_free(RT_PIPE *pipe,RT_PIPE_MSG *msg)
  *
  * @brief Free a message pipe buffer.
  *
  * This service releases a message buffer returned by
- * rt_pipe_receive() to the system heap.
+ * rt_pipe_receive() to the pipe's heap.
  *
+ * @param pipe The descriptor address of the affected pipe.
+ *
  * @param msg The address of the message buffer to free.
  *
  * @return 0 is returned upon success, or -EINVAL if @a msg is not a
@@ -1049,9 +1110,9 @@
  * Rescheduling: never.
  */
 
-int rt_pipe_free (RT_PIPE_MSG *msg)
+int rt_pipe_free (RT_PIPE *pipe,RT_PIPE_MSG *msg)
 {
-    return xnheap_free(__pipe_heap,msg);
+    return xnheap_free(pipe->bufpool,msg);
 }
 
 /*@}*/
Index: testsuite/klatency/latency-module.c
===================================================================
--- testsuite/klatency/latency-module.c	(revision 182)
+++ testsuite/klatency/latency-module.c	(working copy)
@@ -83,7 +83,7 @@
 	maxjitter = maxj;
 	avgjitter = sumj / sample_count;
 
-	msg = rt_pipe_alloc(sizeof(struct latency_stat));
+	msg = rt_pipe_alloc(&pipe,sizeof(struct latency_stat));
 
 	if (!msg)
 	    {
@@ -103,7 +103,7 @@
 	   ourselves. */
 
 	if (rt_pipe_send(&pipe,msg,sizeof(*s),0) != sizeof(*s))
-	    rt_pipe_free(msg);
+	    rt_pipe_free(&pipe,msg);
 	}
 }
 
@@ -128,7 +128,7 @@
 	return 2;
 	}
 
-    err = rt_pipe_create(&pipe,"klatency",0);
+    err = rt_pipe_create(&pipe,"klatency",0,0);
 
     if (err)
 	{

[-- Attachment #3: rt_pipe_create-ext.patch-2.1 --]
[-- Type: text/plain, Size: 12057 bytes --]

Index: include/native/pipe.h
===================================================================
--- include/native/pipe.h	(revision 182)
+++ include/native/pipe.h	(working copy)
@@ -23,6 +23,7 @@
 #define _XENO_PIPE_H
 
 #include <xenomai/nucleus/pipe.h>
+#include <xenomai/nucleus/heap.h>
 #include <xenomai/native/types.h>
 
 /* Operation flags. */
@@ -57,6 +58,10 @@
 
     RT_PIPE_MSG *buffer;	/* !< Buffer used in byte stream mode. */
 
+    xnheap_t *bufpool;         /* !< Current buffer pool. */
+
+    xnheap_t privpool;         /* !< Private buffer pool. */
+
     size_t fillsz;		/* !< Bytes written to the buffer.  */
 
     u_long flushable;		/* !< Flush request flag. */
@@ -85,7 +90,8 @@
 
 int rt_pipe_create(RT_PIPE *pipe,
 		   const char *name,
-		   int minor);
+		   int minor,
+		   size_t poolsize);
 
 int rt_pipe_delete(RT_PIPE *pipe);
 
@@ -116,9 +122,11 @@
 		     size_t size,
 		     int mode);
 
-RT_PIPE_MSG *rt_pipe_alloc(size_t size);
+RT_PIPE_MSG *rt_pipe_alloc(RT_PIPE *pipe,
+                           size_t size);
 
-int rt_pipe_free(RT_PIPE_MSG *msg);
+int rt_pipe_free(RT_PIPE *pipe,
+                 RT_PIPE_MSG *msg);
 
 int __native_pipe_pkg_init(void);
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 182)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2005-11-25  Jan Kiszka <jan.kiszka@domain.hid>
+
+	* ksrc/skins/native/{pipe.c,syscall.c}, src/skins/native/pipe.c,
+	include/native/pipe.h: Added poolsize parameter to rt_pipe_create
+	for setting up pipes with private buffer pools of user-defined
+	size. Also, the addressed pipe has to be passed to rt_pipe_alloc
+	and rt_pipe_free now.
+
 2005-11-25  Philippe Gerum  <rpm@xenomai.org>
 
 	* configure.in: Enable x86-tsc by default.
Index: src/skins/native/pipe.c
===================================================================
--- src/skins/native/pipe.c	(revision 182)
+++ src/skins/native/pipe.c	(working copy)
@@ -23,13 +23,15 @@
 
 int rt_pipe_create (RT_PIPE *pipe,
 		    const char *name,
-		    int minor)
+		    int minor,
+		    size_t poolsize)
 {
-    return XENOMAI_SKINCALL3(__native_muxid,
+    return XENOMAI_SKINCALL4(__native_muxid,
 			     __native_pipe_create,
 			     pipe,
 			     name,
-			     minor);
+			     minor,
+			     poolsize);
 }
 
 int rt_pipe_bind (RT_PIPE *pipe,
Index: ksrc/skins/native/syscall.c
===================================================================
--- ksrc/skins/native/syscall.c	(revision 182)
+++ ksrc/skins/native/syscall.c	(working copy)
@@ -3194,6 +3194,7 @@
     char name[XNOBJECT_NAME_LEN];
     RT_PIPE_PLACEHOLDER ph;
     int err, minor;
+    size_t poolsize;
     RT_PIPE *pipe;
 
     if (!__xn_access_ok(curr,VERIFY_WRITE,__xn_reg_arg1(regs),sizeof(ph)))
@@ -3213,12 +3214,15 @@
     /* Device minor. */
     minor = (int)__xn_reg_arg3(regs);
 
+    /* Buffer pool size. */
+    poolsize = (size_t)__xn_reg_arg4(regs);
+
     pipe = (RT_PIPE *)xnmalloc(sizeof(*pipe));
 
     if (!pipe)
 	return -ENOMEM;
 
-    err = rt_pipe_create(pipe,name,minor);
+    err = rt_pipe_create(pipe,name,minor,poolsize);
 
     if (err == 0)
 	{
@@ -3332,7 +3336,7 @@
     /* Zero-sized messages are allowed, so we still need to free the
        message buffer even if no data copy took place. */
 
-    rt_pipe_free(msg);
+    rt_pipe_free(pipe,msg);
 
     return err;
 }
@@ -3374,8 +3378,8 @@
     if (!__xn_access_ok(curr,VERIFY_READ,__xn_reg_arg2(regs),size))
 	return -EFAULT;
 
-    msg = rt_pipe_alloc(size);
-	
+    msg = rt_pipe_alloc(pipe,size);
+
     if (!msg)
 	return -ENOMEM;
 
@@ -3386,7 +3390,7 @@
     if (err != size)
 	/* If the operation failed, we need to free the message buffer
 	   by ourselves. */
-	rt_pipe_free(msg);
+       rt_pipe_free(pipe,msg);
 
     return err;
 }
@@ -3436,8 +3440,8 @@
 	}
     else
 	{
-	msg = rt_pipe_alloc(size);
-	
+       msg = rt_pipe_alloc(pipe,size);
+
 	if (!msg)
 	    return -ENOMEM;
 
@@ -3449,7 +3453,7 @@
     err = rt_pipe_stream(pipe,buf,size);
 
     if (msg)
-	rt_pipe_free(msg);
+       rt_pipe_free(pipe,msg);
 
     return err;
 }
@@ -3616,7 +3620,7 @@
     [__native_intr_enable ] = { &__rt_intr_enable, __xn_exec_any },
     [__native_intr_disable ] = { &__rt_intr_disable, __xn_exec_any },
     [__native_intr_inquire ] = { &__rt_intr_inquire, __xn_exec_any },
-    [__native_pipe_create ] = { &__rt_pipe_create, __xn_exec_any },
+    [__native_pipe_create ] = { &__rt_pipe_create, __xn_exec_lostage },
     [__native_pipe_bind ] = { &__rt_pipe_bind, __xn_exec_conforming },
     [__native_pipe_delete ] = { &__rt_pipe_delete, __xn_exec_any },
     [__native_pipe_read ] = { &__rt_pipe_read, __xn_exec_primary },
Index: ksrc/skins/native/pipe.c
===================================================================
--- ksrc/skins/native/pipe.c	(revision 182)
+++ ksrc/skins/native/pipe.c	(working copy)
@@ -50,8 +50,6 @@
 #include <xenomai/native/registry.h>
 #include <xenomai/native/pipe.h>
 
-static xnheap_t *__pipe_heap = &kheap;
-
 static int __pipe_flush_apc;
 
 static DECLARE_XNQUEUE(__pipe_flush_q);
@@ -83,6 +81,15 @@
 
 #endif /* CONFIG_XENO_NATIVE_EXPORT_REGISTRY */
 
+static void __pipe_flush_pool (xnheap_t *heap,
+                               void *poolmem,
+                               u_long poolsize,
+                               void *cookie)
+{
+    xnarch_sysfree(poolmem,poolsize);
+}
+
+
 static inline ssize_t __pipe_flush (RT_PIPE *pipe)
 
 {
@@ -122,8 +129,10 @@
 				   size_t size,
 				   void *cookie)
 {
+    RT_PIPE *pipe = (RT_PIPE *)cookie;
+
     /* Allocate memory for the incoming message. */
-    return xnheap_alloc(__pipe_heap,size);
+    return xnheap_alloc(pipe->bufpool,size);
 }
 
 static int __pipe_output_handler (int bminor,
@@ -131,8 +140,10 @@
 				  int retval,
 				  void *cookie)
 {
+    RT_PIPE *pipe = (RT_PIPE *)cookie;
+
     /* Free memory from output/discarded message. */
-    xnheap_free(__pipe_heap,mh);
+    xnheap_free(pipe->bufpool,mh);
     return retval;
 }
 
@@ -154,7 +165,7 @@
 }
 
 /**
- * @fn int rt_pipe_create(RT_PIPE *pipe,const char *name,int minor)
+ * @fn int rt_pipe_create(RT_PIPE *pipe,const char *name,int minor, size_t poolsize)
  * @brief Create a message pipe.
  *
  * This service opens a bi-directional communication channel allowing
@@ -201,6 +212,10 @@
  * /proc/xenomai/registry/pipes/@a name to the allocated pipe device
  * entry (i.e. /dev/rtp*).
  *
+ * @param poolsize Specifies the size of a dedicated buffer pool for the
+ * pipe. Passing 0 means that all message allocations for this pipe are
+ * performed on the system heap.
+ *
  * @return 0 is returned upon success. Otherwise:
  *
  * - -ENOMEM is returned if the system fails to get enough dynamic
@@ -232,20 +247,56 @@
 
 int rt_pipe_create (RT_PIPE *pipe,
 		    const char *name,
-		    int minor)
+		    int minor,
+		    size_t poolsize)
 {
     int err = 0;
+    void *poolmem;
 
-    if (xnpod_asynch_p())
+    if (!xnpod_root_p())
 	return -EPERM;
 
     pipe->buffer = NULL;
+    pipe->bufpool = &kheap;
     pipe->fillsz = 0;
     pipe->flushable = 0;
     pipe->handle = 0;    /* i.e. (still) unregistered pipe. */
     pipe->magic = XENO_PIPE_MAGIC;
     xnobject_copy_name(pipe->name,name);
 
+    if (poolsize > 0)
+        {
+        /* Make sure we won't hit trivial argument errors when calling
+           xnheap_init(). */
+
+        if (poolsize < 2 * PAGE_SIZE)
+            poolsize = 2 * PAGE_SIZE;
+
+        /* Account for the overhead so that the actual free space is large
+           enough to match the requested size. */
+
+        poolsize += xnheap_overhead(poolsize,PAGE_SIZE);
+        poolsize = PAGE_ALIGN(poolsize);
+
+        poolmem = xnarch_sysalloc(poolsize);
+
+        if (!poolmem)
+            return -ENOMEM;
+
+        err = xnheap_init(&pipe->privpool,
+                          poolmem,
+                          poolsize,
+                          PAGE_SIZE); /* Use natural page size */
+        if (err)
+            {
+            xnarch_sysfree(poolmem,poolsize);
+            return err;
+            }
+
+        pipe->bufpool = &pipe->privpool;
+        }
+
+
     minor = xnpipe_connect(minor,
 			 &__pipe_output_handler,
 			 NULL,
@@ -253,8 +304,12 @@
 			 pipe);
 
     if (minor < 0)
-	return minor;
+        {
+        if (pipe->bufpool == &pipe->privpool)
+            xnheap_destroy(&pipe->privpool,__pipe_flush_pool,NULL);
 
+        return minor;
+        }
     pipe->minor = minor;
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
@@ -337,14 +392,15 @@
     if (!pipe)
 	{
 	err = xeno_handle_error(pipe,XENO_PIPE_MAGIC,RT_PIPE);
-	goto unlock_and_exit;
+       xnlock_put_irqrestore(&nklock,s);
+       return err;
 	}
 
     if (__test_and_clear_bit(0,&pipe->flushable))
 	{
 	/* Purge data waiting for flush. */
 	removeq(&__pipe_flush_q,&pipe->link);
-	rt_pipe_free(pipe->buffer);
+       rt_pipe_free(pipe,pipe->buffer);
 	}
 
     err = xnpipe_disconnect(pipe->minor);
@@ -356,10 +412,11 @@
 
     xeno_mark_deleted(pipe);
 
- unlock_and_exit:
-
     xnlock_put_irqrestore(&nklock,s);
 
+    if (pipe->bufpool == &pipe->privpool)
+       xnheap_destroy(&pipe->privpool,__pipe_flush_pool,NULL);
+
     return err;
 }
 
@@ -572,7 +629,7 @@
     /* Zero-sized messages are allowed, so we still need to free the
        message buffer even if no data copy took place. */
 
-    rt_pipe_free(msg);
+    rt_pipe_free(pipe,msg);
 
     return nbytes;
 }
@@ -767,8 +824,8 @@
 	/* Try flushing the streaming buffer in any case. */
 	return rt_pipe_send(pipe,NULL,0,mode);
 
-    msg = rt_pipe_alloc(size);
-	
+    msg = rt_pipe_alloc(pipe,size);
+
     if (!msg)
 	return -ENOMEM;
 
@@ -779,7 +836,7 @@
     if (nbytes != size)
 	/* If the operation failed, we need to free the message buffer
 	   by ourselves. */
-	rt_pipe_free(msg);
+       rt_pipe_free(pipe,msg);
 
     return nbytes;
 }
@@ -886,7 +943,7 @@
 
 	if (pipe->buffer == NULL)
 	    {
-	    pipe->buffer = rt_pipe_alloc(CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ);
+           pipe->buffer = rt_pipe_alloc(pipe,CONFIG_XENO_OPT_NATIVE_PIPE_BUFSZ);
 
 	    if (pipe->buffer == NULL)
 		{
@@ -984,15 +1041,17 @@
 }
 
 /**
- * @fn RT_PIPE_MSG *rt_pipe_alloc(size_t size)
+ * @fn RT_PIPE_MSG *rt_pipe_alloc(RT_PIPE *pipe,size_t size)
  *
  * @brief Allocate a message pipe buffer.
  *
- * This service allocates a message buffer from the system heap which
+ * This service allocates a message buffer from the pipe's heap which
  * can be subsequently filled by the caller then passed to
  * rt_pipe_send() for sending. The beginning of the available data
  * area of @a size contiguous bytes is accessible from P_MSGPTR(msg).
  *
+ * @param pipe The descriptor address of the affected pipe.
+ *
  * @param size The requested size in bytes of the buffer. This value
  * should represent the size of the payload data.
  *
@@ -1010,10 +1069,10 @@
  * Rescheduling: never.
  */
 
-RT_PIPE_MSG *rt_pipe_alloc (size_t size)
-
+RT_PIPE_MSG *rt_pipe_alloc (RT_PIPE *pipe,
+                            size_t size)
 {
-    RT_PIPE_MSG *msg = (RT_PIPE_MSG *)xnheap_alloc(__pipe_heap,size + sizeof(RT_PIPE_MSG));
+    RT_PIPE_MSG *msg = (RT_PIPE_MSG *)xnheap_alloc(pipe->bufpool,size + sizeof(RT_PIPE_MSG));
 
     if (msg)
 	{
@@ -1025,13 +1084,15 @@
 }
 
 /**
- * @fn int rt_pipe_free(RT_PIPE_MSG *msg)
+ * @fn int rt_pipe_free(RT_PIPE *pipe,RT_PIPE_MSG *msg)
  *
  * @brief Free a message pipe buffer.
  *
  * This service releases a message buffer returned by
- * rt_pipe_receive() to the system heap.
+ * rt_pipe_receive() to the pipe's heap.
  *
+ * @param pipe The descriptor address of the affected pipe.
+ *
  * @param msg The address of the message buffer to free.
  *
  * @return 0 is returned upon success, or -EINVAL if @a msg is not a
@@ -1049,9 +1110,9 @@
  * Rescheduling: never.
  */
 
-int rt_pipe_free (RT_PIPE_MSG *msg)
+int rt_pipe_free (RT_PIPE *pipe,RT_PIPE_MSG *msg)
 {
-    return xnheap_free(__pipe_heap,msg);
+    return xnheap_free(pipe->bufpool,msg);
 }
 
 /*@}*/

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

* Re: [Xenomai-core] [PATCH] private heaps for native pipes
  2005-11-25 18:24 [Xenomai-core] [PATCH] private heaps for native pipes Jan Kiszka
@ 2005-11-25 18:34 ` Philippe Gerum
  2005-11-25 18:40   ` Jan Kiszka
  0 siblings, 1 reply; 3+ messages in thread
From: Philippe Gerum @ 2005-11-25 18:34 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

Jan Kiszka wrote:
> Hi,
> 
> this is basically the last version of my rt_pipe_create-ext patch to add
> private, user-resizeable heaps to native pipes. Joerg has tested this
> patch successfully under the 2.1 trunk, and I added a ChangeLog snippet.
> Attached both 2.0.x and 2.1.x patches - please apply at least the 2.1
> variant.
> 

Applied to 2.1, thanks. We need to keep the 2.0 branch 100% compatible 
with the former RTAI/fusion API-wise, so I won't merge this in 2.0 though.

-- 

Philippe.


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

* Re: [Xenomai-core] [PATCH] private heaps for native pipes
  2005-11-25 18:34 ` Philippe Gerum
@ 2005-11-25 18:40   ` Jan Kiszka
  0 siblings, 0 replies; 3+ messages in thread
From: Jan Kiszka @ 2005-11-25 18:40 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: xenomai-core

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

Philippe Gerum wrote:
> Jan Kiszka wrote:
>> Hi,
>>
>> this is basically the last version of my rt_pipe_create-ext patch to add
>> private, user-resizeable heaps to native pipes. Joerg has tested this
>> patch successfully under the 2.1 trunk, and I added a ChangeLog snippet.
>> Attached both 2.0.x and 2.1.x patches - please apply at least the 2.1
>> variant.
>>
> 
> Applied to 2.1, thanks. We need to keep the 2.0 branch 100% compatible
> with the former RTAI/fusion API-wise, so I won't merge this in 2.0 though.
> 

No problem. The patch was first developed on 2.0, so I just attached
that version. Now, as I returned from my short travel, Joerg told me
that he is already happily working over 2.1-trunk and had adapted my
patch. :)

BTW, RTnet also compiles against trunk now, I just have to get the patch
into SVN.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

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

end of thread, other threads:[~2005-11-25 18:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-25 18:24 [Xenomai-core] [PATCH] private heaps for native pipes Jan Kiszka
2005-11-25 18:34 ` Philippe Gerum
2005-11-25 18:40   ` Jan Kiszka

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.