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, ¶m);
+
+ 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, ¶m);
+ param.sched_priority = req->priority;
+ pthread_setschedparam (pthread_self(), req->policy, ¶m);
+
+ 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