change log for rtems (2010-08-16)

rtems-vc at rtems.org rtems-vc at rtems.org
Mon Aug 16 06:11:21 UTC 2010


 *ralf*:
2010-08-16	Alin Rus <alin.codejunkie at gmail.com>

	* posix/include/aio.h: Extend struct aiocb.
	* posix/include/rtems/posix/aio_misc.h: New.

M 1.2567  cpukit/ChangeLog
M 1.2566  cpukit/ChangeLog
M   1.83  cpukit/posix/Makefile.am
M   1.14  cpukit/posix/include/aio.h
A    1.1  cpukit/posix/include/rtems/posix/aio_misc.h

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
@@ -1,3 +1,7 @@
+2010-08-16	Ralf Corsépius <ralf.corsepius at rtems.org>
+
+	* posix/Makefile.am: Add include/rtems/posix/aio_misc.h.
+
 2010-08-16	Alin Rus <alin.codejunkie at gmail.com>
 
 	* posix/include/aio.h: Extend struct aiocb.

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
@@ -1,3 +1,8 @@
+2010-08-16	Alin Rus <alin.codejunkie at gmail.com>
+
+	* posix/include/aio.h: Extend struct aiocb.
+	* posix/include/rtems/posix/aio_misc.h: New.
+
 2010-08-13	Sebastian Huber <sebastian.huber at embedded-brains.de>
 
 	* libblock/src/media.c: Use unprotected chain extract.

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
@@ -24,12 +24,11 @@
 
 if HAS_PTHREADS
 # include
-
 include_HEADERS = include/aio.h include/mqueue.h \
     include/semaphore.h include/devctl.h
 
 # include/rtems/posix
-
+include_rtems_posix_HEADERS += include/rtems/posix/aio_misc.h
 
 include_rtems_posix_HEADERS += include/rtems/posix/cancel.h \
     include/rtems/posix/cond.h include/rtems/posix/config.h \

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
@@ -60,6 +60,7 @@
  */
 
 struct aiocb {
+  /* public */
   int             aio_fildes;     /* File descriptor */
   off_t           aio_offset;     /* File offset */
   volatile void  *aio_buf;        /* Location of buffer */
@@ -67,6 +68,9 @@
   int             aio_reqprio;    /* Request priority offset */
   struct sigevent aio_sigevent;   /* Signal number and value */
   int             aio_lio_opcode; /* Operation to be performed */
+  /* private */
+  int		  error_code;      /* Used for aio_error() */
+  ssize_t	  return_value;     /* Used for aio_return() */
 };
 
 /*

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
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010, Alin Rus <alin.codejunkie at gmail.com> 
+ * 
+ * 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>
+  
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+  /* Actual request being processed */
+  typedef struct rtems_aio_request_s
+  {
+    int policy;                 /* If _POSIX_PRIORITIZED_IO and 
+		                   _POSIX_PRIORITY_SCHEDULING are defined */ 
+    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 */  
+    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;      
+    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


 *ralf*:
Regenerate.

M   1.28  cpukit/posix/preinstall.am

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
@@ -44,6 +44,10 @@
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/devctl.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/devctl.h
 
+$(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
+
 $(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


 *ralf*:
2010-08-16	Alin Rus <alin.codejunkie at 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.

M 1.2568  cpukit/ChangeLog
M    1.3  cpukit/posix/src/aio_error.c
A    1.1  cpukit/posix/src/aio_misc.c
M    1.3  cpukit/posix/src/aio_read.c
M    1.4  cpukit/posix/src/aio_return.c
M    1.3  cpukit/posix/src/aio_write.c

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
@@ -1,3 +1,10 @@
+2010-08-16	Alin Rus <alin.codejunkie at 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.
+
 2010-08-16	Ralf Corsépius <ralf.corsepius at rtems.org>
 
 	* posix/Makefile.am: Add include/rtems/posix/aio_misc.h.

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
@@ -1,14 +1,11 @@
 /*
- *  6.7.5 Retrieve Error of Asynchronous I/O Operation, P1003.1b-1993, p. 161
+ * Copyright 2010, Alin Rus <alin.codejunkie at gmail.com> 
+ * 
+ * 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.
  *
- *  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$
+ * $Id$
  */
 
 #if HAVE_CONFIG_H
@@ -21,9 +18,21 @@
 #include <rtems/system.h>
 #include <rtems/seterr.h>
 
-int aio_error(
-  const struct aiocb  *aiocbp __attribute__((unused))
-)
+/*
+ *  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)
 {
-  rtems_set_errno_and_return_minus_one( ENOSYS );
+  return aiocbp->error_code;
 }

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
@@ -0,0 +1,521 @@
+/*
+ * Copyright 2010, Alin Rus <alin.codejunkie at gmail.com> 
+ * 
+ * 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);
+
+/* 
+ *  rtems_aio_init
+ *
+ * Initialize the request queue for aio
+ *
+ *  Input parameters:
+ *        NONE
+ *
+ *  Output parameters: 
+ *        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;
+
+}
+
+/* 
+ *  rtems_aio_search_fd
+ *
+ * Search and create chain of requests for given FD 
+ *
+ *  Input parameters:
+ *        chain        - chain of FD chains
+ *        fildes       - file descriptor to search
+ *        create       - if 1 search and create
+ *                     - if 0 just search
+ *
+ *  Output parameters: 
+ *        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;
+}
+
+/* 
+ *  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: 
+ *        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);
+
+  }
+}
+
+/* 
+ *  rtems_aio_remove_fd
+ *
+ * Removes all the requests in a fd chain 
+ *
+ *  Input parameters:
+ *        r_chain        - pointer to the fd chain request
+ * 
+ *  Output parameters: 
+ *        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;
+  
+  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);
+    }
+}
+
+/* 
+ *  rtems_aio_remove_req
+ *
+ * Removes request from given chain 
+ *
+ *  Input parameters:
+ *        chain      - pointer to fd chain which may contain
+ *                     the request
+ *        aiocbp     - pointer to request that needs to be
+ *                     canceled
+ * 
+ *  Output parameters: 
+ *         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;
+  
+  current = (rtems_aio_request *) node;
+
+  while (!rtems_chain_is_tail (chain, node) && current->aiocbp != aiocbp) {
+    node = node->next;
+    current = (rtems_aio_request *) node;
+  }
+  
+  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); 
+    }
+    
+  return AIO_CANCELED;
+}
+
+/* 
+ *  rtems_aio_enqueue
+ *
+ * Enqueue requests, and creates threads to process them 
+ *
+ *  Input parameters:
+ *        req        - see aio_misc.h
+ * 
+ *  Output parameters: 
+ *         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, 
+     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 */ 	 
+      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);
+      
+      } else {
+      
+      /* or to the idle chain */
+      r_chain = rtems_aio_search_fd (chain, req->aiocbp->aio_fildes, 1);
+      
+      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;
+}
+
+/* 
+ *  rtems_aio_handle
+ *
+ * Thread processing requests 
+ *
+ *  Input parameters:
+ *        arg        - the chain for the fd to be worked on
+ * 
+ *  Output parameters: 
+ *        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");
+ 
+  while (1) {
+    
+    /* 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;
+    
+    chain = &r_chain->perfd;
+
+    /* If the locked chain is not empty, take the first
+       request extract it, unlock the chain and process 
+       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;
+      
+      /* 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. 
+	 
+	 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 */
+      
+      struct timespec timeout;
+     
+      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);
+	  
+	  /* If no requests were added to the chain we delete the fd chain from 
+	     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);
+	    
+	    /* If the idle chain is empty sleep for 3 seconds and wait for a 
+	       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);
+	      
+	      /* 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;
+	      }
+	      
+	      /* Otherwise move this chain to the working chain and 
+		 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);
+	      
+	      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);
+	  }
+	}
+    }
+  }
+  
+
+  AIO_printf ("Thread finished\n");
+  return NULL;
+}

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
@@ -1,29 +1,65 @@
 /*
- *  6.7.2 Asynchronous Read, P1003.1b-1993, p. 154
+ * Copyright 2010, Alin Rus <alin.codejunkie at gmail.com> 
+ * 
+ * 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.
  *
- *  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$
+ * $Id$
  */
 
+
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <aio.h>
 #include <errno.h>
-
+#include <fcntl.h>
+#include <rtems/posix/aio_misc.h>
 #include <rtems/system.h>
 #include <rtems/seterr.h>
+#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
+ */
 
-int aio_read(
-  struct aiocb  *aiocbp __attribute__((unused))
-)
+int
+aio_read (struct aiocb *aiocbp)
 {
-  rtems_set_errno_and_return_minus_one( ENOSYS );
+  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);
+  
+  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);
 }

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
@@ -1,15 +1,11 @@
 /*
- *  6.7.6 Retrieve Return Status of Asynchronous I/O Operation,
- *        P1003.1b-1993, p. 162
+ * Copyright 2010, Alin Rus <alin.codejunkie at gmail.com> 
+ * 
+ * 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.
  *
- *  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$
+ * $Id$
  */
 
 #if HAVE_CONFIG_H
@@ -22,9 +18,20 @@
 #include <rtems/system.h>
 #include <rtems/seterr.h>
 
-ssize_t aio_return(
-  const struct aiocb  *aiocbp __attribute__((unused))
-)
+/*
+ *  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)
 {
-  rtems_set_errno_and_return_minus_one( ENOSYS );
+  return aiocbp->return_value;
 }

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
@@ -1,29 +1,65 @@
 /*
- *  6.7.3 Asynchronous Write, P1003.1b-1993, p. 155
+ * Copyright 2010, Alin Rus <alin.codejunkie at gmail.com> 
+ * 
+ * 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.
  *
- *  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$
+ * $Id$
  */
 
+
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <aio.h>
 #include <errno.h>
-
+#include <fcntl.h>
+#include <rtems/posix/aio_misc.h>
 #include <rtems/system.h>
 #include <rtems/seterr.h>
+#include <stdlib.h>
 
-int aio_write(
-  struct aiocb  *aiocbp __attribute__((unused))
-)
+/*
+ *  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)
 {
-  rtems_set_errno_and_return_minus_one( ENOSYS );
+  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);
 }


 *ralf*:
2010-08-16	Ralf Corsépius <ralf.corsepius at rtems.org>

	* posix/Makefile.am: Reflect aio-changes.

M   1.84  cpukit/posix/Makefile.am

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
@@ -49,12 +49,12 @@
     inline/rtems/posix/rwlock.inl inline/rtems/posix/spinlock.inl
 
 ## src
-
-# These are really in the stand but not really functional
-## BUILD_FOR_NOW_C_FILES
 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 \
-    src/lio_listio.c src/devctl.c
+    src/lio_listio.c src/aio_misc.c
+
+# These are really in the stand but not really functional
+libposix_a_SOURCES += src/devctl.c
 
 ## ENOSYS_C_FILES
 libposix_a_SOURCES += src/_execve.c src/execl.c src/execle.c src/execlp.c \



--

Generated by Deluxe Loginfo [http://www.codewiz.org/projects/index.html#loginfo] 2.122 by Bernardo Innocenti <bernie at develer.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/vc/attachments/20100816/8ba4fe0c/attachment.html>


More information about the vc mailing list