Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:12

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  * 
0006  * @ingroup POSIX_AIO
0007  *
0008  * @brief POSIX Asynchronous I/O Private Support
0009  *
0010  * This defines private information for the AIO implementation.
0011  */
0012 
0013 /*
0014  *  Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
0015  * 
0016  *  COPYRIGHT (c) 1989-2011.
0017  *  On-Line Applications Research Corporation (OAR).
0018  *
0019  * Redistribution and use in source and binary forms, with or without
0020  * modification, are permitted provided that the following conditions
0021  * are met:
0022  * 1. Redistributions of source code must retain the above copyright
0023  *    notice, this list of conditions and the following disclaimer.
0024  * 2. Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the distribution.
0027  *
0028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0029  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0031  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0032  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0033  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0034  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0036  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0037  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0038  * POSSIBILITY OF SUCH DAMAGE.
0039  */
0040 
0041 #ifndef _AIO_MISC_H
0042 #define _AIO_MISC_H
0043 
0044 #include <string.h>
0045 #include <signal.h> 
0046 #include <aio.h>
0047 #include <pthread.h>
0048 #include <stdatomic.h>
0049 #include <rtems.h>
0050 #include <rtems/chain.h>
0051 #include <rtems/seterr.h>
0052 
0053 #ifdef RTEMS_DEBUG
0054 #include <stdio.h>
0055 #endif
0056 
0057 #ifdef __cplusplus
0058 extern "C" {
0059 #endif
0060 
0061 /** Constants to identify op type */
0062 
0063 /** Needed by aio_fsync() */
0064 #define AIO_OP_READ        0
0065 
0066 /** Needed by aio_fsync() */
0067 #define AIO_OP_WRITE       1
0068 
0069 /** Needed by aio_fsync() */
0070 #define AIO_OP_SYNC        2
0071 
0072 /** Needed by aio_fsync() */
0073 #define AIO_OP_DSYNC       3
0074 
0075 /*
0076  * Constants to track return status
0077  */
0078 
0079 /** The aio operation return value has been retrieved */
0080 #define AIO_RETURNED    0
0081 
0082 /** The aio operation return value has not been retrieved */
0083 #define AIO_NOTRETURNED 1
0084 
0085 /** Constants to identify list completion notification */
0086 
0087 /** No notification required */
0088 #define AIO_LIO_NO_NOTIFY  0
0089 
0090 /** Notification via sigevent */
0091 #define AIO_LIO_SIGEV      1
0092 
0093 /** Notification via event delivery */
0094 #define AIO_LIO_EVENT      2
0095 
0096 /**
0097  * @brief holds a pointer to a sigevent struct or a thread id 
0098  *  
0099  */
0100 typedef union
0101 {
0102   /** @brief pointer to the sigevent for notification */
0103   struct sigevent *sigp;
0104 
0105   /** @brief id of the thread that called lio_listio() */
0106   int task_id;
0107 
0108 } lio_notification_union;
0109 
0110 /**
0111  * @brief Control block for every list enqueued with lio_listio()
0112  */
0113 typedef struct
0114 {
0115   pthread_mutex_t mutex;
0116 
0117   /** @brief number of requests left to complete the list */
0118   int requests_left;
0119 
0120   /** @brief type of notification */
0121   int notification_type;
0122 
0123   /** @brief event to do at list completion*/
0124   lio_notification_union lio_notification;
0125 
0126 } listcb;
0127 
0128 /**
0129  * @brief The request being processed
0130  */
0131 typedef struct
0132 {
0133   /** @brief Chain requests in order of priority */
0134   rtems_chain_node next_prio;
0135 
0136   /** @brief If _POSIX_PRIORITIZED_IO and _POSIX_PRIORITY_SCHEDULING are defined */ 
0137   int policy;
0138 
0139   /** @brief see above */
0140   int priority;
0141 
0142   /** @brief Used for notification */
0143   pthread_t caller_thread;
0144 
0145   /** @brief pointer to list control block */
0146   listcb *listcbp;
0147 
0148   /** @brief Aio control block */
0149   struct aiocb *aiocbp;
0150 
0151   /** @brief Operation type */
0152   int op_type;
0153 
0154 } rtems_aio_request;
0155 
0156 /**
0157  * @brief A chain of requests for the same FD
0158  */
0159 typedef struct
0160 {
0161   /** @brief Order fd chains in queue */
0162   rtems_chain_node next_fd;
0163 
0164   /** @brief Chain of requests for this fd */
0165   rtems_chain_control perfd;
0166 
0167   /** @brief File descriptor to be processed */
0168   int fildes;
0169 
0170   /** @brief Indicates if this is a newly created chain */
0171   int new_fd;
0172 
0173   pthread_mutex_t mutex;
0174   pthread_cond_t cond;
0175 
0176 } rtems_aio_request_chain;
0177 
0178 /**
0179  * @brief The queue of all the requests in progress and waiting to be processed
0180  */
0181 typedef struct
0182 {
0183   pthread_mutex_t mutex;
0184   pthread_cond_t new_req;
0185   pthread_attr_t attr;
0186 
0187   /** @brief Chains being worked by active threads */
0188   rtems_chain_control work_req;
0189 
0190   /** @brief Chains waiting to be processed */
0191   rtems_chain_control idle_req;
0192   
0193   /** @brief Specific value if queue is initialized */
0194   unsigned int initialized;
0195 
0196   /** @brief The number of active threads */
0197   int active_threads;
0198 
0199   /** @brief The number of idle threads */
0200   int idle_threads;
0201 
0202   /** @brief The number of queued requests*/
0203   atomic_int queued_requests;
0204 
0205 } rtems_aio_queue;
0206 
0207 extern rtems_aio_queue aio_request_queue;
0208 
0209 #define AIO_QUEUE_INITIALIZED 0xB00B
0210 
0211 #ifndef AIO_MAX_THREADS
0212 #define AIO_MAX_THREADS 5
0213 #endif
0214 
0215 #ifndef AIO_LISTIO_MAX
0216 #define AIO_LISTIO_MAX 20
0217 #endif
0218 
0219 #ifndef RTEMS_AIO_MAX
0220 #define RTEMS_AIO_MAX 100
0221 #endif
0222 
0223 /**
0224  * @brief Initialize the request queue for AIO Operations.
0225  * 
0226  * @retval 0 The queue has bees succesfully initialized.
0227  * @retval -1 An error occured while initializing the queue.
0228  */
0229 int rtems_aio_init( void );
0230 
0231 /**
0232  * @brief Enqueue requests, and creates threads to process them.
0233  * 
0234  * @param[in,out] req A pointer to the request.
0235  * 
0236  * @retval 0 if the request was added to the queue, errno otherwise.
0237  */
0238 int rtems_aio_enqueue( rtems_aio_request *req );
0239 
0240 /**
0241  * @brief Search for and create a chain of requests for a given file descriptor.
0242  * 
0243  * @param[in,out] chain   A pointer to a chain of FD chains.
0244  * @param[in] fildes The file descriptor to search for.
0245  * @param[in] create  If create == 0, the function just searches for the given FD.
0246  *                    If create == 1, the function creates a new chain if none is found.
0247  * 
0248  * @retval NULL If create == 0 and no chain is found for the given FD.
0249  * @return A pointer to the chain if a chain for the given FD exists.
0250  * @return A pointer to a newly created chain if create == 1 and no chain
0251  *         is found for the given FD.
0252  */
0253 rtems_aio_request_chain *rtems_aio_search_fd(
0254   rtems_chain_control *chain,
0255   int fildes,
0256   int create
0257 );
0258 
0259 /**
0260  * @brief Removes all the requests in a FD chain.
0261  * 
0262  * @param[in,out] r_chain A pointer to a chain of requests for a given FD
0263  */
0264 void rtems_aio_remove_fd( rtems_aio_request_chain *r_chain );
0265 
0266 /**
0267  * @brief Remove request from given chain
0268  * 
0269  * @param[in,out] chain  A pointer to the FD chain that may contain the request
0270  * @param[in,out] aiocbp A pointer to the AIO control block of the request.
0271  * 
0272  * @retval AIO_CANCELED The request was canceled.
0273  * @retval AIO_NOTCANCELED The request was not canceled.
0274  */
0275 int rtems_aio_remove_req(
0276   rtems_chain_control *chain,
0277     struct aiocb *aiocbp
0278 );
0279 
0280 /**
0281  * @brief Checks the validity of a sigevent struct
0282  *
0283  * Checks if the pointer passed as parameter points to a valid sigevent struct.
0284  * 
0285  * @param sigp Is a pointer to the sigevent struct to check.
0286  * @retval 0 The struct is not valid.
0287  * @retval 1 The struct is valid.
0288  */
0289 int rtems_aio_check_sigevent( struct sigevent *sigp );
0290 
0291 /**
0292  * @brief initializes a read rtems_aio_request
0293  * 
0294  * @param aiocb pointer to the aiocb describing the request
0295  * @retval NULL the aiocb passed was invalid, errno indicates the error:
0296  *          - 
0297  * @return rtems_aio_request* a pointer to the newly created request.
0298  */
0299 rtems_aio_request *init_write_req( struct aiocb* aiocbp );
0300 
0301 /**
0302  * @brief initializes a write rtems_aio_request
0303  * 
0304  * @param aiocb pointer to the aiocb describing the request
0305  * @retval NULL the aiocb passed was invalid, errno indicates the error:
0306  *          - 
0307  * @return rtems_aio_request* a pointer to the newly created request.
0308  */
0309 rtems_aio_request *init_read_req( struct aiocb* aiocbp );
0310 
0311 /**
0312  * @brief updates listcb after op completion
0313  * 
0314  * @param listcbp 
0315  */
0316 void rtems_aio_completed_list_op( listcb *listcbp );
0317 
0318 #ifdef RTEMS_DEBUG
0319 #include <assert.h>
0320 
0321 #define AIO_assert(_x) assert(_x)
0322 #define AIO_printf(_x) printf(_x)
0323 #else
0324 #define AIO_assert(_x)
0325 #define AIO_printf(_x)
0326 #endif
0327 
0328 #ifdef __cplusplus
0329 }
0330 #endif
0331 
0332 #endif
0333