<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>change log for rtems (2010-08-16)</title>
</head>
<body text='#000000' bgcolor='#ffffff'>
<a name='cs1'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
 <font color='#bb2222'><strong>ralf</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2010-08-16 Alin Rus <alin.codejunkie@gmail.com>

        * posix/include/aio.h: Extend struct aiocb.
        * posix/include/rtems/posix/aio_misc.h: New.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/ChangeLog.diff?r1=text&tr1=1.2566&r2=text&tr2=1.2567&diff_format=h">M</a></td><td width='1%'>1.2567</td><td width='100%'>cpukit/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/ChangeLog.diff?r1=text&tr1=1.2565&r2=text&tr2=1.2566&diff_format=h">M</a></td><td width='1%'>1.2566</td><td width='100%'>cpukit/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/Makefile.am.diff?r1=text&tr1=1.82&r2=text&tr2=1.83&diff_format=h">M</a></td><td width='1%'>1.83</td><td width='100%'>cpukit/posix/Makefile.am</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/include/aio.h.diff?r1=text&tr1=1.13&r2=text&tr2=1.14&diff_format=h">M</a></td><td width='1%'>1.14</td><td width='100%'>cpukit/posix/include/aio.h</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/include/rtems/posix/aio_misc.h?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">cpukit/posix/include/rtems/posix/aio_misc.h</font></td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/cpukit/ChangeLog:1.2566 rtems/cpukit/ChangeLog:1.2567
--- rtems/cpukit/ChangeLog:1.2566       Mon Aug 16 00:39:18 2010
+++ rtems/cpukit/ChangeLog      Mon Aug 16 00:39:58 2010
</font><font color='#997700'>@@ -1,3 +1,7 @@
</font><font color='#000088'>+2010-08-16    Ralf Corsépius <ralf.corsepius@rtems.org>
+
+       * posix/Makefile.am: Add include/rtems/posix/aio_misc.h.
+
</font> 2010-08-16        Alin Rus <alin.codejunkie@gmail.com>
 
        * posix/include/aio.h: Extend struct aiocb.

<font color='#006600'>diff -u rtems/cpukit/ChangeLog:1.2565 rtems/cpukit/ChangeLog:1.2566
--- rtems/cpukit/ChangeLog:1.2565       Fri Aug 13 07:50:55 2010
+++ rtems/cpukit/ChangeLog      Mon Aug 16 00:39:18 2010
</font><font color='#997700'>@@ -1,3 +1,8 @@
</font><font color='#000088'>+2010-08-16    Alin Rus <alin.codejunkie@gmail.com>
+
+       * posix/include/aio.h: Extend struct aiocb.
+       * posix/include/rtems/posix/aio_misc.h: New.
+
</font> 2010-08-13        Sebastian Huber <sebastian.huber@embedded-brains.de>
 
        * libblock/src/media.c: Use unprotected chain extract.

<font color='#006600'>diff -u rtems/cpukit/posix/Makefile.am:1.82 rtems/cpukit/posix/Makefile.am:1.83
--- rtems/cpukit/posix/Makefile.am:1.82 Mon Jul 26 17:03:17 2010
+++ rtems/cpukit/posix/Makefile.am      Mon Aug 16 00:39:59 2010
</font><font color='#997700'>@@ -24,12 +24,11 @@
</font> 
 if HAS_PTHREADS
 # include
<font color='#880000'>-
</font> include_HEADERS = include/aio.h include/mqueue.h \
     include/semaphore.h include/devctl.h
 
 # include/rtems/posix
<font color='#880000'>-
</font><font color='#000088'>+include_rtems_posix_HEADERS += include/rtems/posix/aio_misc.h
</font> 
 include_rtems_posix_HEADERS += include/rtems/posix/cancel.h \
     include/rtems/posix/cond.h include/rtems/posix/config.h \

<font color='#006600'>diff -u rtems/cpukit/posix/include/aio.h:1.13 rtems/cpukit/posix/include/aio.h:1.14
--- rtems/cpukit/posix/include/aio.h:1.13       Mon Aug  9 02:33:58 2010
+++ rtems/cpukit/posix/include/aio.h    Mon Aug 16 00:39:18 2010
</font><font color='#997700'>@@ -60,6 +60,7 @@
</font>  */
 
 struct aiocb {
<font color='#000088'>+  /* public */
</font>   int             aio_fildes;     /* File descriptor */
   off_t           aio_offset;     /* File offset */
   volatile void  *aio_buf;        /* Location of buffer */
<font color='#997700'>@@ -67,6 +68,9 @@
</font>   int             aio_reqprio;    /* Request priority offset */
   struct sigevent aio_sigevent;   /* Signal number and value */
   int             aio_lio_opcode; /* Operation to be performed */
<font color='#000088'>+  /* private */
+  int            error_code;      /* Used for aio_error() */
+  ssize_t        return_value;     /* Used for aio_return() */
</font> };
 
 /*

<font color='#006600'>diff -u /dev/null rtems/cpukit/posix/include/rtems/posix/aio_misc.h:1.1
--- /dev/null   Mon Aug 16 01:11:20 2010
+++ rtems/cpukit/posix/include/rtems/posix/aio_misc.h   Mon Aug 16 00:39:18 2010
</font><font color='#997700'>@@ -0,0 +1,101 @@
</font><font color='#000088'>+/*
+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com><span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+
+#ifndef _AIO_MISC_H
+#define _AIO_MISC_H
+
+#include <stdio.h>
+#include <string.h>
+#include <aio.h>
+#include <pthread.h>
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtems/system.h>
+#include <rtems/seterr.h>
+<span style="background-color: #FF0000">  </span>
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+  /* Actual request being processed */
+  typedef struct rtems_aio_request_s
+  {
+    int policy;                 /* If _POSIX_PRIORITIZED_IO and<span style="background-color: #FF0000"> </span>
+                                  _POSIX_PRIORITY_SCHEDULING are defined */<span style="background-color: #FF0000"> </span>
+    int priority;               /* see above */
+    rtems_chain_node next_prio; /* chain requests in order of priority */
+    pthread_t caller_thread;    /* used for notification */
+    struct aiocb *aiocbp;       /* aio control block */
+  } rtems_aio_request;
+
+  typedef struct rtems_aio_request_chain_s
+  {
+    int fildes;                 /* file descriptor to be processed */<span style="background-color: #FF0000">  </span>
+    int new_fd;                 /* if this is a newly created chain */
+    rtems_chain_node next_fd;   /* order fd chains in queue */
+    rtems_chain_control perfd;  /* chain of requests for this fd */
+    pthread_mutex_t mutex;<span style="background-color: #FF0000">      </span>
+    pthread_cond_t cond;
+
+  } rtems_aio_request_chain;
+
+  typedef struct rtems_aio_queue_s
+  {
+    pthread_mutex_t mutex;
+    pthread_cond_t new_req;
+    pthread_attr_t attr;
+
+    rtems_chain_control work_req; /* chains being worked by active threads */
+    rtems_chain_control idle_req; /* fd chains waiting to be processed */
+    unsigned int initialized;     /* specific value if queue is initialized */
+    int size;
+    int active_threads;           /* the number of active threads */
+    int idle_threads;             /* number of idle threads */
+
+  } rtems_aio_queue;
+
+#define AIO_QUEUE_INITIALIZED 0xB00B
+
+#ifndef AIO_MAX_THREADS
+#define AIO_MAX_THREADS 5
+#endif
+
+#ifndef AIO_MAX_QUEUE_SIZE
+#define AIO_MAX_QUEUE_SIZE 30
+#endif
+
+extern int rtems_aio_init (void);
+extern int rtems_aio_enqueue (rtems_aio_request * req);
+extern rtems_aio_request_chain *rtems_aio_search_fd (rtems_chain_control *
+                                                       chain, int fildes,
+                                                       int create);
+
+#ifdef RTEMS_DEBUG
+#include <assert.h>
+
+#define AIO_assert(_x) assert(_x)
+#define AIO_printf(_x) printf(_x)
+#else
+#define AIO_assert(_x)
+#define AIO_printf(_x)
+#endif
+
+#define rtems_aio_set_errno_return_minus_one( _error, _aiocbp ) \
+  do { (_aiocbp)->error_code = (_error);                    \
+    (_aiocbp)->return_value = -1;                           \
+    rtems_set_errno_and_return_minus_one (_error);} while(0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
</font></pre>
<p> </p>
<a name='cs2'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
 <font color='#bb2222'><strong>ralf</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>Regenerate.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/preinstall.am.diff?r1=text&tr1=1.27&r2=text&tr2=1.28&diff_format=h">M</a></td><td width='1%'>1.28</td><td width='100%'>cpukit/posix/preinstall.am</td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/cpukit/posix/preinstall.am:1.27 rtems/cpukit/posix/preinstall.am:1.28
--- rtems/cpukit/posix/preinstall.am:1.27       Sat Apr  3 00:58:17 2010
+++ rtems/cpukit/posix/preinstall.am    Mon Aug 16 00:40:29 2010
</font><font color='#997700'>@@ -44,6 +44,10 @@
</font>   $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/devctl.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/devctl.h
 
<font color='#000088'>+$(PROJECT_INCLUDE)/rtems/posix/aio_misc.h: include/rtems/posix/aio_misc.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+       $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h
+
</font> $(PROJECT_INCLUDE)/rtems/posix/cancel.h: include/rtems/posix/cancel.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cancel.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cancel.h
</pre>
<p> </p>
<a name='cs3'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
 <font color='#bb2222'><strong>ralf</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2010-08-16 Alin Rus <alin.codejunkie@gmail.com>

        * posix/src/aio_misc.c: New.
        * posix/src/aio_error.c, posix/src/aio_read.c,
        * posix/src/aio_return.c, posix/src/aio_write.c:
        New implementation.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/ChangeLog.diff?r1=text&tr1=1.2567&r2=text&tr2=1.2568&diff_format=h">M</a></td><td width='1%'>1.2568</td><td width='100%'>cpukit/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/src/aio_error.c.diff?r1=text&tr1=1.2&r2=text&tr2=1.3&diff_format=h">M</a></td><td width='1%'>1.3</td><td width='100%'>cpukit/posix/src/aio_error.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/src/aio_misc.c?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">cpukit/posix/src/aio_misc.c</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/src/aio_read.c.diff?r1=text&tr1=1.2&r2=text&tr2=1.3&diff_format=h">M</a></td><td width='1%'>1.3</td><td width='100%'>cpukit/posix/src/aio_read.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/src/aio_return.c.diff?r1=text&tr1=1.3&r2=text&tr2=1.4&diff_format=h">M</a></td><td width='1%'>1.4</td><td width='100%'>cpukit/posix/src/aio_return.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/src/aio_write.c.diff?r1=text&tr1=1.2&r2=text&tr2=1.3&diff_format=h">M</a></td><td width='1%'>1.3</td><td width='100%'>cpukit/posix/src/aio_write.c</td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/cpukit/ChangeLog:1.2567 rtems/cpukit/ChangeLog:1.2568
--- rtems/cpukit/ChangeLog:1.2567       Mon Aug 16 00:39:58 2010
+++ rtems/cpukit/ChangeLog      Mon Aug 16 00:46:09 2010
</font><font color='#997700'>@@ -1,3 +1,10 @@
</font><font color='#000088'>+2010-08-16    Alin Rus <alin.codejunkie@gmail.com>
+
+       * posix/src/aio_misc.c: New.
+       * posix/src/aio_error.c, posix/src/aio_read.c,
+       * posix/src/aio_return.c, posix/src/aio_write.c:
+       New implementation.
+
</font> 2010-08-16        Ralf Corsépius <ralf.corsepius@rtems.org>
 
        * posix/Makefile.am: Add include/rtems/posix/aio_misc.h.

<font color='#006600'>diff -u rtems/cpukit/posix/src/aio_error.c:1.2 rtems/cpukit/posix/src/aio_error.c:1.3
--- rtems/cpukit/posix/src/aio_error.c:1.2      Fri Jan  2 04:04:23 2009
+++ rtems/cpukit/posix/src/aio_error.c  Mon Aug 16 00:46:09 2010
</font><font color='#997700'>@@ -1,14 +1,11 @@
</font> /*
<font color='#880000'>- *  6.7.5 Retrieve Error of Asynchronous I/O Operation, P1003.1b-1993, p. 161
</font><font color='#000088'>+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com><span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
</font>  *
<font color='#880000'>- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- *
- *  $Id$
</font><font color='#000088'>+ * $Id$
</font>  */
 
 #if HAVE_CONFIG_H
<font color='#997700'>@@ -21,9 +18,21 @@
</font> #include <rtems/system.h>
 #include <rtems/seterr.h>
 
<font color='#880000'>-int aio_error(
-  const struct aiocb  *aiocbp __attribute__((unused))
-)
</font><font color='#000088'>+/*
+ *  aio_error
+ *
+ * Retrieve errors status for an asynchronous I/O operation
+ *
+ *  Input parameters:
+ *        aiocbp - asynchronous I/O control block
+ *
+ *  Output parameters:
+ *        aiocbp->error_code
+ */
+
+
+int
+aio_error (const struct aiocb *aiocbp)
</font> {
<font color='#880000'>-  rtems_set_errno_and_return_minus_one( ENOSYS );
</font><font color='#000088'>+  return aiocbp->error_code;
</font> }

<font color='#006600'>diff -u /dev/null rtems/cpukit/posix/src/aio_misc.c:1.1
--- /dev/null   Mon Aug 16 01:11:20 2010
+++ rtems/cpukit/posix/src/aio_misc.c   Mon Aug 16 00:46:09 2010
</font><font color='#997700'>@@ -0,0 +1,521 @@
</font><font color='#000088'>+/*
+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com><span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <time.h>
+#include <rtems/posix/aio_misc.h>
+
+
+
+rtems_aio_queue aio_request_queue;
+
+static void *rtems_aio_handle (void *arg);
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_init
+ *
+ * Initialize the request queue for aio
+ *
+ *  Input parameters:
+ *        NONE
+ *
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *        0    -    if initialization succeded
+ */
+
+int
+rtems_aio_init (void)
+{
+  int result = 0;
+
+  result = pthread_attr_init (&aio_request_queue.attr);
+  if (result != 0)
+    return result;
+
+  result =
+    pthread_attr_setdetachstate (&aio_request_queue.attr,
+                                 PTHREAD_CREATE_DETACHED);
+  if (result != 0)
+    pthread_attr_destroy (&aio_request_queue.attr);
+
+
+  result = pthread_mutex_init (&aio_request_queue.mutex, NULL);
+  if (result != 0)
+    pthread_attr_destroy (&aio_request_queue.attr);
+
+
+  result = pthread_cond_init (&aio_request_queue.new_req, NULL);
+  if (result != 0) {
+    pthread_mutex_destroy (&aio_request_queue.mutex);
+    pthread_attr_destroy (&aio_request_queue.attr);
+  }
+
+  rtems_chain_initialize_empty (&aio_request_queue.work_req);
+  rtems_chain_initialize_empty (&aio_request_queue.idle_req);
+
+  aio_request_queue.active_threads = 0;
+  aio_request_queue.idle_threads = 0;
+  aio_request_queue.size = 0;
+  aio_request_queue.initialized = AIO_QUEUE_INITIALIZED;
+
+  return result;
+
+}
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_search_fd
+ *
+ * Search and create chain of requests for given FD<span style="background-color: #FF0000"> </span>
+ *
+ *  Input parameters:
+ *        chain        - chain of FD chains
+ *        fildes       - file descriptor to search
+ *        create       - if 1 search and create
+ *                     - if 0 just search
+ *
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *        r_chain      - NULL if create == 0 and there is
+ *                       no chain for given fildes
+ *                     - pointer to chain is there exists
+ *                       a chain for given fildes
+ *                     - pointer to newly create chain if
+ *                       create == 1
+ *
+ */
+
+rtems_aio_request_chain *
+rtems_aio_search_fd (rtems_chain_control * chain, int fildes, int create)
+{
+  rtems_aio_request_chain *r_chain;
+  rtems_chain_node *node;
+
+  node = chain->first;
+  r_chain = (rtems_aio_request_chain *) node;
+
+  while (r_chain->fildes < fildes && !rtems_chain_is_tail (chain, node)) {
+    node = node->next;
+    r_chain = (rtems_aio_request_chain *) node;
+  }
+
+  if (r_chain->fildes == fildes)
+    r_chain->new_fd = 0;
+  else {
+    if (create == 0)
+      r_chain = NULL;
+    else {
+      r_chain = malloc (sizeof (rtems_aio_request_chain));
+      rtems_chain_initialize_empty (&r_chain->perfd);
+
+      if (rtems_chain_is_empty (chain))
+        rtems_chain_prepend (chain, &r_chain->next_fd);
+      else
+        rtems_chain_insert (node->previous, &r_chain->next_fd);
+
+      r_chain->new_fd = 1;
+    }
+  }
+  return r_chain;
+}
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_insert_prio
+ *
+ * Add request to given FD chain. The chain is ordered
+ * by priority
+ *
+ *  Input parameters:
+ *        chain        - chain of requests for a given FD
+ *        req          - request (see aio_misc.h)
+ *
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *        NONE
+ */
+
+void
+rtems_aio_insert_prio (rtems_chain_control * chain, rtems_aio_request * req)
+{
+  rtems_chain_node *node;
+
+  AIO_printf ("FD exists \n");
+  node = chain->first;
+
+  if (rtems_chain_is_empty (chain)) {
+    AIO_printf ("First in chain \n");
+    rtems_chain_prepend (chain, &req->next_prio);
+  } else {
+    AIO_printf ("Add by priority \n");
+    int prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio;
+
+    while (req->aiocbp->aio_reqprio > prio &&
+           !rtems_chain_is_tail (chain, node)) {
+      node = node->next;
+      prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio;
+    }
+
+    rtems_chain_insert (node->previous, &req->next_prio);
+
+  }
+}
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_remove_fd
+ *
+ * Removes all the requests in a fd chain<span style="background-color: #FF0000"> </span>
+ *
+ *  Input parameters:
+ *        r_chain        - pointer to the fd chain request
+ *<span style="background-color: #FF0000"> </span>
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *        NONE
+ */
+
+void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain)
+{
+  rtems_chain_control *chain;
+  rtems_chain_node *node;
+
+  chain = &r_chain->perfd;
+  node = chain->first;
+<span style="background-color: #FF0000">  </span>
+  while (!rtems_chain_is_tail (chain, node))
+    {
+      rtems_chain_extract (node);
+      rtems_aio_request *req = (rtems_aio_request *) node;
+      req->aiocbp->error_code = ECANCELED;
+      req->aiocbp->return_value = -1;
+      free (req);
+    }
+}
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_remove_req
+ *
+ * Removes request from given chain<span style="background-color: #FF0000"> </span>
+ *
+ *  Input parameters:
+ *        chain      - pointer to fd chain which may contain
+ *                     the request
+ *        aiocbp     - pointer to request that needs to be
+ *                     canceled
+ *<span style="background-color: #FF0000"> </span>
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *         AIO_NOTCANCELED   - if request was not canceled
+ *         AIO_CANCELED      - if request was canceled
+ */
+
+int rtems_aio_remove_req (rtems_chain_control *chain, struct aiocb *aiocbp)
+{
+  rtems_chain_node *node = chain->first;
+  rtems_aio_request *current;
+<span style="background-color: #FF0000">  </span>
+  current = (rtems_aio_request *) node;
+
+  while (!rtems_chain_is_tail (chain, node) && current->aiocbp != aiocbp) {
+    node = node->next;
+    current = (rtems_aio_request *) node;
+  }
+<span style="background-color: #FF0000">  </span>
+  if (rtems_chain_is_tail (chain, node))
+    return AIO_NOTCANCELED;
+  else
+    {
+      rtems_chain_extract (node);
+      current->aiocbp->error_code = ECANCELED;
+      current->aiocbp->return_value = -1;
+      free (current);<span style="background-color: #FF0000"> </span>
+    }
+<span style="background-color: #FF0000">    </span>
+  return AIO_CANCELED;
+}
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_enqueue
+ *
+ * Enqueue requests, and creates threads to process them<span style="background-color: #FF0000"> </span>
+ *
+ *  Input parameters:
+ *        req        - see aio_misc.h
+ *<span style="background-color: #FF0000"> </span>
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *         0         - if request was added to queue
+ *         errno     - otherwise
+ */
+
+int
+rtems_aio_enqueue (rtems_aio_request * req)
+{
+
+  rtems_aio_request_chain *r_chain;
+  rtems_chain_control *chain;
+  pthread_t thid;
+  int result, policy;
+  struct sched_param param;
+
+  /* The queue should be initialized */
+  AIO_assert (aio_request_queue.initialized != AIO_QUEUE_INITIALIZED);
+
+  result = pthread_mutex_lock (&aio_request_queue.mutex);
+  if (result != 0) {
+    free (req);
+    return result;
+  }
+
+  /* used to check if we can create more threads */
+  int chain_type;
+
+  /* _POSIX_PRIORITIZED_IO and _POSIX_PRIORITY_SCHEDULING are defined,<span style="background-color: #FF0000"> </span>
+     we can use aio_reqprio to lower the priority of the request */
+  pthread_getschedparam (pthread_self(), &policy, &param);
+
+  req->caller_thread = pthread_self ();
+  req->priority = param.sched_priority - req->aiocbp->aio_reqprio;
+  req->policy = policy;
+  req->aiocbp->error_code = EINPROGRESS;
+  req->aiocbp->return_value = 0;
+
+  if (AIO_MAX_THREADS >
+      (aio_request_queue.active_threads + aio_request_queue.idle_threads)) {
+    chain_type = 0;
+    chain = &aio_request_queue.work_req;
+  } else {
+    chain = &aio_request_queue.idle_req;
+    chain_type = 1;
+  }
+
+  /* we still have empty places on the active_threads chain */
+  if (chain_type == 0) {
+    r_chain = rtems_aio_search_fd (chain, req->aiocbp->aio_fildes, 1);
+
+    if (r_chain->new_fd == 1) {
+      rtems_chain_prepend (&r_chain->perfd, &req->next_prio);
+      r_chain->new_fd = 0;
+      pthread_mutex_init (&r_chain->mutex, NULL);
+      pthread_cond_init (&r_chain->cond, NULL);
+
+      /* if there are idle threads and this is a new fd chain
+         there's no need to create another thread */<span style="background-color: #FF0000"><span style="background-color: #FF0000"> </span>      </span>
+      if (aio_request_queue.idle_threads > 0) {
+        result = pthread_cond_signal (&aio_request_queue.new_req);
+        if (result != 0) {
+          pthread_mutex_unlock (&aio_request_queue.mutex);
+          return result;
+        }
+      } else {
+
+       /* if this is a new fd chain and no threads are idle create
+          new thread */
+        AIO_printf ("New thread");
+        result = pthread_create (&thid, &aio_request_queue.attr,
+                                 rtems_aio_handle, (void *) r_chain);
+        if (result != 0) {
+          pthread_mutex_unlock (&aio_request_queue.mutex);
+          return result;
+        }
+        ++aio_request_queue.active_threads;
+      }
+    } else {
+      /* put request in the fd chain it belongs to */
+      pthread_mutex_lock (&r_chain->mutex);
+      rtems_aio_insert_prio (&r_chain->perfd, req);
+      pthread_cond_signal (&r_chain->cond);
+      pthread_mutex_unlock (&r_chain->mutex);
+    }
+  } else {
+    /* the maximum number of threads has been already created
+       even though some of them might be idle.
+       The request belongs to one of the active fd chain */
+    r_chain = rtems_aio_search_fd (&aio_request_queue.work_req,
+                                   req->aiocbp->aio_fildes, 0);
+    if (r_chain != NULL)
+      {
+       pthread_mutex_lock (&r_chain->mutex);
+       rtems_aio_insert_prio (&r_chain->perfd, req);
+       pthread_cond_signal (&r_chain->cond);
+       pthread_mutex_unlock (&r_chain->mutex);
+<span style="background-color: #FF0000">      </span>
+      } else {
+<span style="background-color: #FF0000">      </span>
+      /* or to the idle chain */
+      r_chain = rtems_aio_search_fd (chain, req->aiocbp->aio_fildes, 1);
+<span style="background-color: #FF0000">      </span>
+      if (r_chain->new_fd == 1) {
+       /* If this is a new fd chain we signal the idle threads that
+          might be waiting for requests */
+        rtems_chain_prepend (&r_chain->perfd, &req->next_prio);
+       pthread_cond_signal (&aio_request_queue.new_req);
+      } else
+       /* just insert the request in the existing fd chain */
+        rtems_aio_insert_prio (&r_chain->perfd, req);
+    }
+  }
+
+  pthread_mutex_unlock (&aio_request_queue.mutex);
+  return 0;
+}
+
+/*<span style="background-color: #FF0000"> </span>
+ *  rtems_aio_handle
+ *
+ * Thread processing requests<span style="background-color: #FF0000"> </span>
+ *
+ *  Input parameters:
+ *        arg        - the chain for the fd to be worked on
+ *<span style="background-color: #FF0000"> </span>
+ *  Output parameters:<span style="background-color: #FF0000"> </span>
+ *        NULL       - if error
+ */
+
+static void *
+rtems_aio_handle (void *arg)
+{
+
+  rtems_aio_request_chain *r_chain = arg;
+  rtems_aio_request *req;
+  rtems_chain_control *chain;
+  rtems_chain_node *node;
+  int result, policy;
+  struct sched_param param;
+
+  AIO_printf ("Thread started\n");
+<span style="background-color: #FF0000"> </span>
+  while (1) {
+<span style="background-color: #FF0000">    </span>
+    /* acquire the mutex of the current fd chain.
+       we don't need to lock the queue mutex since we can
+       add requests to idle fd chains or even active ones
+       if the working request has been extracted from the
+       chain */
+    result = pthread_mutex_lock (&r_chain->mutex);
+    if (result != 0)
+      return NULL;
+<span style="background-color: #FF0000">    </span>
+    chain = &r_chain->perfd;
+
+    /* If the locked chain is not empty, take the first
+       request extract it, unlock the chain and process<span style="background-color: #FF0000"> </span>
+       the request, in this way the user can supply more
+       requests to this fd chain */
+    if (!rtems_chain_is_empty (chain)) {
+
+      node = chain->first;
+      req = (rtems_aio_request *) node;
+<span style="background-color: #FF0000">      </span>
+      /* See _POSIX_PRIORITIZE_IO and _POSIX_PRIORITY_SCHEDULING
+        discussion in rtems_aio_enqueue () */
+      pthread_getschedparam (pthread_self(), &policy, &param);
+      param.sched_priority = req->priority;
+      pthread_setschedparam (pthread_self(), req->policy, &param);
+
+      rtems_chain_extract (node);
+
+      pthread_mutex_unlock (&r_chain->mutex);
+
+      switch (req->aiocbp->aio_lio_opcode) {
+      case LIO_READ:
+        result = pread (req->aiocbp->aio_fildes,
+                        (void *) req->aiocbp->aio_buf,
+                        req->aiocbp->aio_nbytes, req->aiocbp->aio_offset);
+        break;
+
+      case LIO_WRITE:
+        result = pwrite (req->aiocbp->aio_fildes,
+                         (void *) req->aiocbp->aio_buf,
+                         req->aiocbp->aio_nbytes, req->aiocbp->aio_offset);
+        break;
+
+      default:
+        result = -1;
+      }
+      if (result == -1) {
+        req->aiocbp->return_value = -1;
+       req->aiocbp->error_code = errno;
+      } else {
+        req->aiocbp->return_value = result;
+        req->aiocbp->error_code = 0;
+      }
+
+      // notification needed for lio
+
+    } else {
+      /* If the fd chain is empty we unlock the fd chain
+        and we lock the queue chain, this will ensure that
+        we have at most one request comming to our fd chain
+        when we check.<span style="background-color: #FF0000"> </span>
+<span style="background-color: #FF0000">        </span>
+        If there was no request added sleep for 3 seconds and
+        wait for a signal on chain, this will unlock the queue.
+        The fd chain is already unlocked */
+<span style="background-color: #FF0000">      </span>
+      struct timespec timeout;
+<span style="background-color: #FF0000">     </span>
+      pthread_mutex_unlock (&r_chain->mutex);
+      pthread_mutex_lock (&aio_request_queue.mutex);
+      if (rtems_chain_is_empty (chain))
+       {
+         clock_gettime (CLOCK_REALTIME, &timeout);
+         timeout.tv_sec += 3;
+         timeout.tv_nsec = 0;
+         result = pthread_cond_timedwait (&r_chain->cond,
+                                          &aio_request_queue.mutex, &timeout);
+<span style="background-color: #FF0000">         </span>
+         /* If no requests were added to the chain we delete the fd chain from<span style="background-color: #FF0000"> </span>
+            the queue and start working with idle fd chains */
+         if (result == ETIMEDOUT) {
+           rtems_chain_extract (&r_chain->next_fd);
+           pthread_mutex_destroy (&r_chain->mutex);
+           pthread_cond_destroy (&r_chain->cond);
+           free (r_chain);
+<span style="background-color: #FF0000">           </span>
+           /* If the idle chain is empty sleep for 3 seconds and wait for a<span style="background-color: #FF0000"> </span>
+              signal. The thread now becomes idle. */
+           if (rtems_chain_is_empty (&aio_request_queue.idle_req)) {
+             ++aio_request_queue.idle_threads;
+             clock_gettime (CLOCK_REALTIME, &timeout);
+             timeout.tv_sec += 3;
+             timeout.tv_nsec = 0;
+             result = pthread_cond_timedwait (&aio_request_queue.new_req,
+                                              &aio_request_queue.mutex,
+                                              &timeout);
+<span style="background-color: #FF0000">             </span>
+             /* If no new fd chain was added in the idle requests
+                then this thread is finished */
+             if (result == ETIMEDOUT) {
+               pthread_mutex_unlock (&aio_request_queue.mutex);
+               return NULL;
+             }
+<span style="background-color: #FF0000">             </span>
+             /* Otherwise move this chain to the working chain and<span style="background-color: #FF0000"> </span>
+                start the loop all over again */
+             --aio_request_queue.idle_threads;
+             node = aio_request_queue.idle_req.first;
+             rtems_chain_extract (node);
+             r_chain = rtems_aio_search_fd (&aio_request_queue.work_req,
+                                            ((rtems_aio_request_chain *)node)->fildes,
+                                            1);
+             r_chain->new_fd = 0;
+             pthread_mutex_init (&r_chain->mutex, NULL);
+             pthread_cond_init (&r_chain->cond, NULL);
+<span style="background-color: #FF0000">             </span>
+             r_chain->perfd = ((rtems_aio_request_chain *)node)->perfd;
+           }
+           else
+             /* If there was a request added in the initial fd chain then release
+                the mutex and process it */
+             pthread_mutex_unlock (&aio_request_queue.mutex);
+         }
+       }
+    }
+  }
+<span style="background-color: #FF0000">  </span>
+
+  AIO_printf ("Thread finished\n");
+  return NULL;
+}
</font>
<font color='#006600'>diff -u rtems/cpukit/posix/src/aio_read.c:1.2 rtems/cpukit/posix/src/aio_read.c:1.3
--- rtems/cpukit/posix/src/aio_read.c:1.2       Fri Jan  2 04:04:23 2009
+++ rtems/cpukit/posix/src/aio_read.c   Mon Aug 16 00:46:09 2010
</font><font color='#997700'>@@ -1,29 +1,65 @@
</font> /*
<font color='#880000'>- *  6.7.2 Asynchronous Read, P1003.1b-1993, p. 154
</font><font color='#000088'>+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com><span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
</font>  *
<font color='#880000'>- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- *
- *  $Id$
</font><font color='#000088'>+ * $Id$
</font>  */
 
<font color='#000088'>+
</font> #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <aio.h>
 #include <errno.h>
<font color='#880000'>-
</font><font color='#000088'>+#include <fcntl.h>
+#include <rtems/posix/aio_misc.h>
</font> #include <rtems/system.h>
 #include <rtems/seterr.h>
<font color='#000088'>+#include <stdlib.h>
+
+/*
+ *  aio_read
+ *
+ * Asynchronous write to a file
+ *
+ *  Input parameters:
+ *        aiocbp - asynchronous I/O control block
+ *
+ *  Output parameters:
+ *        -1 - request could not pe enqueued
+ *           - FD not opened for write
+ *           - invalid aio_reqprio or aio_offset or
+ *             aio_nbytes
+ *           - not enough memory
+ *         0 - otherwise
+ */
</font> 
<font color='#880000'>-int aio_read(
-  struct aiocb  *aiocbp __attribute__((unused))
-)
</font><font color='#000088'>+int
+aio_read (struct aiocb *aiocbp)
</font> {
<font color='#880000'>-  rtems_set_errno_and_return_minus_one( ENOSYS );
</font><font color='#000088'>+  rtems_aio_request *req;
+  int mode;
+
+  mode = fcntl (aiocbp->aio_fildes, F_GETFL);
+  if (!(((mode & O_ACCMODE) == O_RDONLY) || ((mode & O_ACCMODE) == O_RDWR)))
+    rtems_aio_set_errno_return_minus_one (EBADF, aiocbp);
+
+  if (aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX)
+    rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp);
+<span style="background-color: #FF0000">  </span>
+  if (aiocbp->aio_offset < 0 || aiocbp->aio_nbytes < 0)
+    rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp);
+
+  req = malloc (sizeof (rtems_aio_request));
+  if (req == NULL)
+    rtems_aio_set_errno_return_minus_one (EAGAIN, aiocbp);
+
+  req->aiocbp = aiocbp;
+  req->aiocbp->aio_lio_opcode = LIO_READ;
+
+  return rtems_aio_enqueue (req);
</font> }

<font color='#006600'>diff -u rtems/cpukit/posix/src/aio_return.c:1.3 rtems/cpukit/posix/src/aio_return.c:1.4
--- rtems/cpukit/posix/src/aio_return.c:1.3     Mon Aug  9 02:33:58 2010
+++ rtems/cpukit/posix/src/aio_return.c Mon Aug 16 00:46:09 2010
</font><font color='#997700'>@@ -1,15 +1,11 @@
</font> /*
<font color='#880000'>- *  6.7.6 Retrieve Return Status of Asynchronous I/O Operation,
- *        P1003.1b-1993, p. 162
</font><font color='#000088'>+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com><span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
</font>  *
<font color='#880000'>- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- *
- *  $Id$
</font><font color='#000088'>+ * $Id$
</font>  */
 
 #if HAVE_CONFIG_H
<font color='#997700'>@@ -22,9 +18,20 @@
</font> #include <rtems/system.h>
 #include <rtems/seterr.h>
 
<font color='#880000'>-ssize_t aio_return(
-  const struct aiocb  *aiocbp __attribute__((unused))
-)
</font><font color='#000088'>+/*
+ *  aio_return
+ *
+ * Retrieve return status of an asynchronous I/O operation
+ *
+ *  Input parameters:
+ *        aiocbp - asynchronous I/O control block
+ *
+ *  Output parameters:
+ *        aiocbp->return_value
+ */
+
+ssize_t
+aio_return (const struct aiocb *aiocbp)
</font> {
<font color='#880000'>-  rtems_set_errno_and_return_minus_one( ENOSYS );
</font><font color='#000088'>+  return aiocbp->return_value;
</font> }

<font color='#006600'>diff -u rtems/cpukit/posix/src/aio_write.c:1.2 rtems/cpukit/posix/src/aio_write.c:1.3
--- rtems/cpukit/posix/src/aio_write.c:1.2      Fri Jan  2 04:04:23 2009
+++ rtems/cpukit/posix/src/aio_write.c  Mon Aug 16 00:46:09 2010
</font><font color='#997700'>@@ -1,29 +1,65 @@
</font> /*
<font color='#880000'>- *  6.7.3 Asynchronous Write, P1003.1b-1993, p. 155
</font><font color='#000088'>+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com><span style="background-color: #FF0000"> </span>
+ *<span style="background-color: #FF0000"> </span>
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
</font>  *
<font color='#880000'>- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- *
- *  $Id$
</font><font color='#000088'>+ * $Id$
</font>  */
 
<font color='#000088'>+
</font> #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <aio.h>
 #include <errno.h>
<font color='#880000'>-
</font><font color='#000088'>+#include <fcntl.h>
+#include <rtems/posix/aio_misc.h>
</font> #include <rtems/system.h>
 #include <rtems/seterr.h>
<font color='#000088'>+#include <stdlib.h>
</font> 
<font color='#880000'>-int aio_write(
-  struct aiocb  *aiocbp __attribute__((unused))
-)
</font><font color='#000088'>+/*
+ *  aio_write
+ *
+ * Asynchronous write to a file
+ *
+ *  Input parameters:
+ *        aiocbp - asynchronous I/O control block
+ *
+ *  Output parameters:
+ *        -1 - request could not pe enqueued
+ *           - FD not opened for write
+ *           - invalid aio_reqprio or aio_offset or
+ *             aio_nbytes
+ *           - not enough memory
+ *         0 - otherwise
+ */
+
+int
+aio_write (struct aiocb *aiocbp)
</font> {
<font color='#880000'>-  rtems_set_errno_and_return_minus_one( ENOSYS );
</font><font color='#000088'>+  rtems_aio_request *req;
+  int mode;
+
+  mode = fcntl (aiocbp->aio_fildes, F_GETFL);
+  if (!(((mode & O_ACCMODE) == O_WRONLY) || ((mode & O_ACCMODE) == O_RDWR)))
+    rtems_aio_set_errno_return_minus_one (EBADF, aiocbp);
+
+  if (aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX)
+    rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp);
+
+  if (aiocbp->aio_offset < 0 || aiocbp->aio_nbytes < 0)
+    rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp);
+
+  req = malloc (sizeof (rtems_aio_request));
+  if (req == NULL)
+    rtems_aio_set_errno_return_minus_one (EAGAIN, aiocbp);
+
+  req->aiocbp = aiocbp;
+  req->aiocbp->aio_lio_opcode = LIO_WRITE;
+
+  return rtems_aio_enqueue (req);
</font> }
</pre>
<p> </p>
<a name='cs4'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
 <font color='#bb2222'><strong>ralf</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2010-08-16 Ralf Corsépius <ralf.corsepius@rtems.org>

        * posix/Makefile.am: Reflect aio-changes.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/posix/Makefile.am.diff?r1=text&tr1=1.83&r2=text&tr2=1.84&diff_format=h">M</a></td><td width='1%'>1.84</td><td width='100%'>cpukit/posix/Makefile.am</td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/cpukit/posix/Makefile.am:1.83 rtems/cpukit/posix/Makefile.am:1.84
--- rtems/cpukit/posix/Makefile.am:1.83 Mon Aug 16 00:39:59 2010
+++ rtems/cpukit/posix/Makefile.am      Mon Aug 16 00:47:30 2010
</font><font color='#997700'>@@ -49,12 +49,12 @@
</font>     inline/rtems/posix/rwlock.inl inline/rtems/posix/spinlock.inl
 
 ## src
<font color='#880000'>-
-# These are really in the stand but not really functional
-## BUILD_FOR_NOW_C_FILES
</font> libposix_a_SOURCES += src/aio_cancel.c src/aio_error.c src/aio_fsync.c \
     src/aio_read.c src/aio_return.c src/aio_suspend.c src/aio_write.c \
<font color='#880000'>-    src/lio_listio.c src/devctl.c
</font><font color='#000088'>+    src/lio_listio.c src/aio_misc.c
+
+# These are really in the stand but not really functional
+libposix_a_SOURCES += src/devctl.c
</font> 
 ## ENOSYS_C_FILES
 libposix_a_SOURCES += src/_execve.c src/execl.c src/execle.c src/execlp.c \
</pre>
<p> </p>

<p>--<br />
<small>Generated by <a href="http://www.codewiz.org/projects/index.html#loginfo">Deluxe Loginfo</a> 2.122 by Bernardo Innocenti <bernie@develer.com></small></p>
</body>
</html>