mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-20 20:05:17 +08:00
cpukit/posix/aio*: Added support for lio_listio()
This commit adds support for lio_listio(). psxaio05 has been added to test the new method. To avoid code duplication, the body of aio_read and aio_write has been moved in two helper methods. In this way i can use it also in lio_listio(). In addition to that, a limit on the number of total aio operation enqueued has been added. Updates rtems/programs/gsoc#29
This commit is contained in:
+40
-12
@@ -139,13 +139,16 @@ struct aiocb {
|
||||
* @param[in,out] aiocbp is a pointer to the asynchronous I/O control block
|
||||
*
|
||||
* @retval 0 The request has been successfuly enqueued.
|
||||
* @retval -1 The request has not been enqueued due to an error. The error is indicated in errno:
|
||||
* - EBADF FD not opened for read
|
||||
* - EINVAL invalid aio_reqprio or aio_offset or aio_nbytes
|
||||
* - EAGAIN not enough memory
|
||||
* - EINVAL the starting position of the file is past the maximum offset
|
||||
* @retval -1 The request has not been enqueued due to an error.
|
||||
* The error is indicated in errno:
|
||||
* - EBADF FD not opened for read.
|
||||
* - EINVAL invalid aio_reqprio or aio_offset or aio_nbytes.
|
||||
* - EAGAIN not enough memory.
|
||||
* - EAGAIN the addition of a new request to the queue would
|
||||
* violate the RTEMS_AIO_MAX limit.
|
||||
* - EINVAL the starting position of the file is past the maximum offset.
|
||||
* for this file.
|
||||
* - EINVAL aiocbp is a NULL pointer
|
||||
* - EINVAL aiocbp is a NULL pointer.
|
||||
* - EINVAL aiocbp->sigevent is not valid.
|
||||
*/
|
||||
int aio_read(
|
||||
@@ -160,11 +163,14 @@ int aio_read(
|
||||
* @param[in,out] aiocbp is a pointer to the asynchronous I/O control block
|
||||
*
|
||||
* @retval 0 The request has been successfuly enqueued.
|
||||
* @retval -1 The request has not been enqueued due to an error. The error is indicated in errno:
|
||||
* - EBADF FD not opened for write
|
||||
* - EINVAL invalid aio_reqprio or aio_offset or aio_nbytes
|
||||
* - EAGAIN not enough memory
|
||||
* - EINVAL aiocbp is a NULL pointer
|
||||
* @retval -1 The request has not been enqueued due to an error.
|
||||
* The error is indicated in errno:
|
||||
* - EBADF FD not opened for write.
|
||||
* - EINVAL invalid aio_reqprio or aio_offset or aio_nbytes.
|
||||
* - EAGAIN not enough memory.
|
||||
* - EAGAIN the addition of a new request to the queue would
|
||||
* violate the RTEMS_AIO_MAX limit.
|
||||
* - EINVAL aiocbp is a NULL pointer.
|
||||
* - EINVAL aiocbp->sigevent is not valid.
|
||||
*/
|
||||
int aio_write(
|
||||
@@ -172,9 +178,29 @@ int aio_write(
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief List Directed I/O - NOT IMPLEMENTED
|
||||
* @brief List Directed I/O
|
||||
*
|
||||
* 6.7.4 List Directed I/O, P1003.1b-1993, p. 158
|
||||
*
|
||||
* @param[in] mode can be LIO_WAIT or LIO_NOWAIT
|
||||
* @param[in,out] list is a pointer to the array of aiocb
|
||||
* @param[in] nent is the number of element in list
|
||||
* @param[in] sig if mode is LIO_NOWAIT, specifies how to notify list completion.
|
||||
*
|
||||
* @retval 0 the call to lio_listio() has completed successfuly.
|
||||
* @retval -1 The call did not complete successfully.
|
||||
* The error is indicated in errno:
|
||||
* - EAGAIN the call failed due to resources limitations.
|
||||
* - EAGAIN the number of entries indicated by nent value would cause
|
||||
* the RTEMS_AIO_MAX limit to be excedeed.
|
||||
* - EINVAL list is a NULL pointer.
|
||||
* - EINVAL mode is not a valid value.
|
||||
* - EINVAL the value of nent is not valid or higher than AIO_LISTIO_MAX.
|
||||
* - EINVAL list is a NULL pointer.
|
||||
* - EINVAL the sigevent struct pointed by sig is not valid.
|
||||
* - EINTR the wait for list completion during a LIO_WAIT operation was
|
||||
* interrupted by an external event.
|
||||
* - EIO One or more of the individual I/O operations failed.
|
||||
*/
|
||||
int lio_listio(
|
||||
int mode,
|
||||
@@ -266,6 +292,8 @@ int aio_suspend(
|
||||
* @retval -1 An error occured. errno indicated the error:
|
||||
* - EAGAIN The requested asynchronous operation was not queued
|
||||
* due to temporary resource limitations.
|
||||
* - EAGAIN the addition of a new request to the queue would
|
||||
* violate the RTEMS_AIO_MAX limit.
|
||||
* - EBADF The aio_fildes member of the aiocb structure referenced
|
||||
* by the aiocbp argument is not a valid file descriptor.
|
||||
* - EINVAL A value of op other than O_SYNC or O_DSYNC was specified.
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <signal.h>
|
||||
#include <aio.h>
|
||||
#include <pthread.h>
|
||||
#include <stdatomic.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/chain.h>
|
||||
#include <rtems/seterr.h>
|
||||
@@ -66,7 +67,7 @@ extern "C" {
|
||||
#define AIO_OP_WRITE 1
|
||||
|
||||
/** Needed by aio_fsync() */
|
||||
#define AIO_OP_SYNC 2
|
||||
#define AIO_OP_SYNC 2
|
||||
|
||||
/** Needed by aio_fsync() */
|
||||
#define AIO_OP_DSYNC 3
|
||||
@@ -81,6 +82,49 @@ extern "C" {
|
||||
/** The aio operation return value has not been retrieved */
|
||||
#define AIO_NOTRETURNED 1
|
||||
|
||||
/** Constants to identify list completion notification */
|
||||
|
||||
/** No notification required */
|
||||
#define AIO_LIO_NO_NOTIFY 0
|
||||
|
||||
/** Notification via sigevent */
|
||||
#define AIO_LIO_SIGEV 1
|
||||
|
||||
/** Notification via event delivery */
|
||||
#define AIO_LIO_EVENT 2
|
||||
|
||||
/**
|
||||
* @brief holds a pointer to a sigevent struct or a thread id
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/** @brief pointer to the sigevent for notification */
|
||||
struct sigevent *sigp;
|
||||
|
||||
/** @brief id of the thread that called lio_listio() */
|
||||
int task_id;
|
||||
|
||||
} lio_notification_union;
|
||||
|
||||
/**
|
||||
* @brief Control block for every list enqueued with lio_listio()
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/** @brief number of requests left to complete the list */
|
||||
int requests_left;
|
||||
|
||||
/** @brief type of notification */
|
||||
int notification_type;
|
||||
|
||||
/** @brief event to do at list completion*/
|
||||
lio_notification_union lio_notification;
|
||||
|
||||
} listcb;
|
||||
|
||||
/**
|
||||
* @brief The request being processed
|
||||
*/
|
||||
@@ -98,6 +142,9 @@ typedef struct
|
||||
/** @brief Used for notification */
|
||||
pthread_t caller_thread;
|
||||
|
||||
/** @brief pointer to list control block */
|
||||
listcb *listcbp;
|
||||
|
||||
/** @brief Aio control block */
|
||||
struct aiocb *aiocbp;
|
||||
|
||||
@@ -152,6 +199,9 @@ typedef struct
|
||||
/** @brief The number of idle threads */
|
||||
int idle_threads;
|
||||
|
||||
/** @brief The number of queued requests*/
|
||||
atomic_int queued_requests;
|
||||
|
||||
} rtems_aio_queue;
|
||||
|
||||
extern rtems_aio_queue aio_request_queue;
|
||||
@@ -162,8 +212,12 @@ extern rtems_aio_queue aio_request_queue;
|
||||
#define AIO_MAX_THREADS 5
|
||||
#endif
|
||||
|
||||
#ifndef AIO_MAX_QUEUE_SIZE
|
||||
#define AIO_MAX_QUEUE_SIZE 30
|
||||
#ifndef AIO_LISTIO_MAX
|
||||
#define AIO_LISTIO_MAX 20
|
||||
#endif
|
||||
|
||||
#ifndef RTEMS_AIO_MAX
|
||||
#define RTEMS_AIO_MAX 100
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -233,6 +287,39 @@ int rtems_aio_remove_req(
|
||||
*/
|
||||
int rtems_aio_check_sigevent( struct sigevent *sigp );
|
||||
|
||||
/**
|
||||
* @brief initializes a read rtems_aio_request
|
||||
*
|
||||
* @param aiocb pointer to the aiocb describing the request
|
||||
* @retval NULL the aiocb passed was invalid, errno indicates the error:
|
||||
* -
|
||||
* @return rtems_aio_request* a pointer to the newly created request.
|
||||
*/
|
||||
rtems_aio_request *init_write_req( struct aiocb* aiocbp );
|
||||
|
||||
/**
|
||||
* @brief initializes a write rtems_aio_request
|
||||
*
|
||||
* @param aiocb pointer to the aiocb describing the request
|
||||
* @retval NULL the aiocb passed was invalid, errno indicates the error:
|
||||
* -
|
||||
* @return rtems_aio_request* a pointer to the newly created request.
|
||||
*/
|
||||
rtems_aio_request *init_read_req( struct aiocb* aiocbp );
|
||||
|
||||
/**
|
||||
* @brief updates listcb after op completion
|
||||
*
|
||||
* @param listcbp
|
||||
*/
|
||||
void rtems_aio_completed_list_op( listcb *listcbp );
|
||||
|
||||
/**
|
||||
* @brief generates event at list completion to end wait in lio_listio().
|
||||
*
|
||||
*/
|
||||
void lio_notify_end_wait( union sigval attr );
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
@@ -536,6 +536,12 @@ rtems_status_code rtems_event_system_send(
|
||||
*/
|
||||
#define RTEMS_EVENT_SYSTEM_SERVER RTEMS_EVENT_30
|
||||
|
||||
/**
|
||||
* @brief This event set constant represents the reserved system event for
|
||||
* aio list completion, used when lio_listio is called using LIO_WAIT.
|
||||
*/
|
||||
#define RTEMS_EVENT_SYSTEM_AIO_LIST RTEMS_EVENT_28
|
||||
|
||||
/* Generated from spec:/rtems/event/if/system-server-resume */
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011, 2024.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
@@ -64,6 +65,11 @@ int aio_fsync(
|
||||
rtems_aio_request *req;
|
||||
int mode;
|
||||
|
||||
|
||||
if ( 1 + atomic_load( &aio_request_queue.queued_requests ) > RTEMS_AIO_MAX ) {
|
||||
rtems_set_errno_and_return_minus_one( EAGAIN );
|
||||
}
|
||||
|
||||
if ( aiocbp == NULL )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
@@ -94,6 +100,7 @@ int aio_fsync(
|
||||
*/
|
||||
req->aiocbp = aiocbp;
|
||||
req->op_type = AIO_OP_SYNC;
|
||||
req->listcbp = NULL;
|
||||
|
||||
return rtems_aio_enqueue( req );
|
||||
}
|
||||
|
||||
+151
-5
@@ -12,6 +12,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010-2011, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
@@ -46,6 +47,7 @@
|
||||
#include <rtems/posix/aio_misc.h>
|
||||
#include <rtems/score/assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
/**
|
||||
* @brief Thread processing AIO requests.
|
||||
@@ -143,11 +145,133 @@ int rtems_aio_init( void )
|
||||
|
||||
aio_request_queue.active_threads = 0;
|
||||
aio_request_queue.idle_threads = 0;
|
||||
atomic_init( &aio_request_queue.queued_requests, 0 );
|
||||
aio_request_queue.initialized = AIO_QUEUE_INITIALIZED;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
rtems_aio_request *init_write_req( struct aiocb* aiocbp )
|
||||
{
|
||||
rtems_aio_request *req;
|
||||
int mode;
|
||||
|
||||
if ( aiocbp == NULL ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = fcntl( aiocbp->aio_fildes, F_GETFL );
|
||||
if (
|
||||
( mode&O_ACCMODE ) != O_WRONLY &&
|
||||
( mode&O_ACCMODE ) != O_RDWR
|
||||
) {
|
||||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( aiocbp->aio_offset < 0 ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req = malloc( sizeof( rtems_aio_request ) );
|
||||
if ( req == NULL ) {
|
||||
errno = EAGAIN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req->aiocbp = aiocbp;
|
||||
req->op_type = AIO_OP_WRITE;
|
||||
req->listcbp = NULL;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
rtems_aio_request *init_read_req( struct aiocb* aiocbp )
|
||||
{
|
||||
rtems_aio_request *req;
|
||||
int mode;
|
||||
|
||||
if ( aiocbp == NULL ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = fcntl( aiocbp->aio_fildes, F_GETFL );
|
||||
if (
|
||||
( mode&O_ACCMODE ) != O_RDONLY &&
|
||||
( mode&O_ACCMODE ) != O_RDWR
|
||||
) {
|
||||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( aiocbp->aio_offset < 0 ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 ) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req = malloc( sizeof( rtems_aio_request ) );
|
||||
if ( req == NULL ) {
|
||||
errno = EAGAIN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
req->aiocbp = aiocbp;
|
||||
req->op_type = AIO_OP_READ;
|
||||
req->listcbp = NULL;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
void rtems_aio_completed_list_op( listcb *listcbp )
|
||||
{
|
||||
if (listcbp == NULL)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock( &listcbp->mutex );
|
||||
|
||||
if( --listcbp->requests_left == 0 ){
|
||||
switch ( listcbp->notification_type ) {
|
||||
case AIO_LIO_NO_NOTIFY:
|
||||
break;
|
||||
case AIO_LIO_SIGEV:
|
||||
rtems_aio_notify( listcbp->lio_notification.sigp );
|
||||
break;
|
||||
case AIO_LIO_EVENT:
|
||||
rtems_event_system_send(
|
||||
listcbp->lio_notification.task_id,
|
||||
RTEMS_EVENT_SYSTEM_AIO_LIST
|
||||
);
|
||||
break;
|
||||
}
|
||||
free( listcbp );
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &listcbp->mutex );
|
||||
}
|
||||
|
||||
rtems_aio_request_chain *rtems_aio_search_fd(
|
||||
rtems_chain_control *chain,
|
||||
int fildes,
|
||||
@@ -249,6 +373,8 @@ void rtems_aio_remove_fd( rtems_aio_request_chain *r_chain )
|
||||
rtems_chain_extract( &req->next_prio );
|
||||
req->aiocbp->error_code = ECANCELED;
|
||||
req->aiocbp->return_value = -1;
|
||||
atomic_fetch_sub( &aio_request_queue.queued_requests, 1 );
|
||||
rtems_aio_completed_list_op( req->listcbp );
|
||||
free( req );
|
||||
}
|
||||
}
|
||||
@@ -274,6 +400,8 @@ int rtems_aio_remove_req( rtems_chain_control *chain, struct aiocb *aiocbp )
|
||||
rtems_chain_extract( node );
|
||||
current->aiocbp->error_code = ECANCELED;
|
||||
current->aiocbp->return_value = -1;
|
||||
rtems_aio_completed_list_op( current->listcbp );
|
||||
atomic_fetch_sub( &aio_request_queue.queued_requests, 1 );
|
||||
free( current );
|
||||
}
|
||||
|
||||
@@ -308,6 +436,7 @@ int rtems_aio_enqueue( rtems_aio_request *req )
|
||||
req->aiocbp->error_code = EINPROGRESS;
|
||||
req->aiocbp->return_value = 0;
|
||||
req->aiocbp->return_status = AIO_NOTRETURNED;
|
||||
atomic_fetch_add( &aio_request_queue.queued_requests, 1 );
|
||||
|
||||
if (
|
||||
aio_request_queue.idle_threads == 0 &&
|
||||
@@ -510,8 +639,12 @@ static void *rtems_aio_handle( void *arg )
|
||||
req = (rtems_aio_request *) node;
|
||||
|
||||
/* See _POSIX_PRIORITIZE_IO and _POSIX_PRIORITY_SCHEDULING
|
||||
discussion in rtems_aio_enqueue () */
|
||||
pthread_getschedparam( pthread_self(), &policy, ¶m );
|
||||
discussion in rtems_aio_enqueue() */
|
||||
pthread_getschedparam(
|
||||
pthread_self(),
|
||||
&policy,
|
||||
¶m
|
||||
);
|
||||
param.sched_priority = req->priority;
|
||||
pthread_setschedparam( pthread_self(), req->policy, ¶m );
|
||||
|
||||
@@ -522,7 +655,15 @@ static void *rtems_aio_handle( void *arg )
|
||||
/* perform the requested operation*/
|
||||
rtems_aio_handle_helper( req );
|
||||
|
||||
/* notification needed for lio after final op is complete */
|
||||
/* update queued_requests */
|
||||
atomic_fetch_sub( &aio_request_queue.queued_requests, 1 );
|
||||
|
||||
/* notification for request completion */
|
||||
rtems_aio_notify( &req->aiocbp->aio_sigevent );
|
||||
|
||||
/* notification for list completion */
|
||||
rtems_aio_completed_list_op( req->listcbp );
|
||||
req->listcbp = NULL;
|
||||
|
||||
} else {
|
||||
/* If the fd chain is empty we unlock the fd chain and we lock
|
||||
@@ -646,8 +787,6 @@ static void rtems_aio_handle_helper( rtems_aio_request *req )
|
||||
result = -1;
|
||||
}
|
||||
|
||||
rtems_aio_notify( &req->aiocbp->aio_sigevent );
|
||||
|
||||
if ( result < 0 ) {
|
||||
req->aiocbp->return_value = -1;
|
||||
req->aiocbp->error_code = errno;
|
||||
@@ -657,3 +796,10 @@ static void rtems_aio_handle_helper( rtems_aio_request *req )
|
||||
}
|
||||
}
|
||||
|
||||
void lio_notify_end_wait( union sigval attr ){
|
||||
rtems_id id = attr.sival_int;
|
||||
rtems_event_set event_in = RTEMS_EVENT_SYSTEM_AIO_LIST;
|
||||
|
||||
rtems_event_system_send( id, event_in );
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
@@ -51,36 +52,17 @@
|
||||
int aio_read( struct aiocb *aiocbp )
|
||||
{
|
||||
rtems_aio_request *req;
|
||||
int mode;
|
||||
|
||||
if ( aiocbp == NULL )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
mode = fcntl( aiocbp->aio_fildes, F_GETFL );
|
||||
if (
|
||||
!(
|
||||
(( mode&O_ACCMODE ) == O_RDONLY ) ||
|
||||
(( mode&O_ACCMODE ) == O_RDWR )
|
||||
)
|
||||
)
|
||||
rtems_set_errno_and_return_minus_one( EBADF );
|
||||
|
||||
if ( aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( aiocbp->aio_offset < 0 )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
req = malloc( sizeof( rtems_aio_request ) );
|
||||
if ( req == NULL )
|
||||
if ( 1 + atomic_load( &aio_request_queue.queued_requests ) > RTEMS_AIO_MAX ) {
|
||||
rtems_set_errno_and_return_minus_one( EAGAIN );
|
||||
}
|
||||
|
||||
req->aiocbp = aiocbp;
|
||||
req->op_type = AIO_OP_READ;
|
||||
req = init_read_req( aiocbp );
|
||||
|
||||
return rtems_aio_enqueue( req );
|
||||
if ( req != NULL ) {
|
||||
return rtems_aio_enqueue( req );
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -48,36 +49,17 @@
|
||||
int aio_write( struct aiocb *aiocbp )
|
||||
{
|
||||
rtems_aio_request *req;
|
||||
int mode;
|
||||
|
||||
if ( aiocbp == NULL )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
mode = fcntl( aiocbp->aio_fildes, F_GETFL );
|
||||
if (
|
||||
!(
|
||||
( ( mode&O_ACCMODE ) == O_WRONLY ) ||
|
||||
( ( mode&O_ACCMODE ) == O_RDWR )
|
||||
)
|
||||
)
|
||||
rtems_set_errno_and_return_minus_one( EBADF );
|
||||
|
||||
if ( aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( aiocbp->aio_offset < 0 )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
req = malloc( sizeof( rtems_aio_request ) );
|
||||
if ( req == NULL )
|
||||
if ( 1 + atomic_load( &aio_request_queue.queued_requests ) > RTEMS_AIO_MAX ) {
|
||||
rtems_set_errno_and_return_minus_one( EAGAIN );
|
||||
}
|
||||
|
||||
req->aiocbp = aiocbp;
|
||||
req->op_type = AIO_OP_WRITE;
|
||||
req = init_write_req( aiocbp );
|
||||
|
||||
return rtems_aio_enqueue( req );
|
||||
if ( req != NULL ) {
|
||||
return rtems_aio_enqueue( req );
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,16 +42,167 @@
|
||||
|
||||
#include <aio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <rtems/posix/aio_misc.h>
|
||||
#include <rtems/seterr.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <rtems/score/basedefs.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
int lio_listio(
|
||||
int mode RTEMS_UNUSED,
|
||||
struct aiocb *__restrict const list[__restrict] RTEMS_UNUSED,
|
||||
int nent RTEMS_UNUSED,
|
||||
struct sigevent *__restrict sig RTEMS_UNUSED
|
||||
int mode,
|
||||
struct aiocb *__restrict const list[__restrict],
|
||||
int nent,
|
||||
struct sigevent *__restrict sig
|
||||
)
|
||||
{
|
||||
rtems_set_errno_and_return_minus_one( ENOSYS );
|
||||
int result, error;
|
||||
listcb *listcbp;
|
||||
rtems_aio_request *req;
|
||||
|
||||
/* Errors on parameters */
|
||||
if ( list == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
if ( mode != LIO_WAIT && mode != LIO_NOWAIT ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
if ( nent < 1 || nent > AIO_LISTIO_MAX ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
if ( nent + atomic_load( &aio_request_queue.queued_requests ) > RTEMS_AIO_MAX ) {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
/* Initialize list control block */
|
||||
listcbp = malloc( sizeof( listcb ) );
|
||||
if ( listcbp == NULL ) {
|
||||
rtems_set_errno_and_return_minus_one( EAGAIN );
|
||||
}
|
||||
|
||||
result = pthread_mutex_init( &listcbp->mutex, NULL );
|
||||
if ( result != 0 ) {
|
||||
free( listcbp );
|
||||
rtems_set_errno_and_return_minus_one( EAGAIN );
|
||||
}
|
||||
|
||||
listcbp->requests_left = 1;
|
||||
|
||||
/* Set up notification for list completion (wait or no wait) */
|
||||
if ( mode == LIO_WAIT ) {
|
||||
listcbp->notification_type = AIO_LIO_EVENT;
|
||||
listcbp->lio_notification.task_id = rtems_task_self();
|
||||
|
||||
} else if ( mode == LIO_NOWAIT ) {
|
||||
|
||||
if ( sig == NULL ) {
|
||||
listcbp->notification_type = AIO_LIO_NO_NOTIFY;
|
||||
} else {
|
||||
if ( rtems_aio_check_sigevent( sig ) == 0 ) {
|
||||
free( listcbp );
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
listcbp->notification_type = AIO_LIO_SIGEV;
|
||||
listcbp->lio_notification.sigp = sig;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize and enqueue each request */
|
||||
error = 0;
|
||||
|
||||
for( int i = 0; i < nent; i++ ) {
|
||||
if ( list[i] == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( list[i]->aio_lio_opcode ) {
|
||||
case LIO_READ:
|
||||
req = init_read_req( list[i] );
|
||||
if ( req == NULL ) {
|
||||
error = 1;
|
||||
list[i]->return_value = -1;
|
||||
list[i]->error_code = errno;
|
||||
list[i]->return_status = AIO_NOTRETURNED;
|
||||
break;
|
||||
}
|
||||
|
||||
req->listcbp = listcbp;
|
||||
result = rtems_aio_enqueue( req );
|
||||
if ( result != 0 ) {
|
||||
error = 1;
|
||||
list[i]->return_value = -1;
|
||||
list[i]->error_code = EAGAIN;
|
||||
list[i]->return_status = AIO_NOTRETURNED;
|
||||
break;
|
||||
}
|
||||
|
||||
listcbp->requests_left++;
|
||||
break;
|
||||
|
||||
case LIO_WRITE:
|
||||
req = init_write_req( list[i] );
|
||||
if ( req == NULL ) {
|
||||
error = 1;
|
||||
list[i]->error_code = errno;
|
||||
list[i]->return_value = -1;
|
||||
list[i]->return_status = AIO_NOTRETURNED;
|
||||
break;
|
||||
}
|
||||
|
||||
req->listcbp = listcbp;
|
||||
result = rtems_aio_enqueue( req );
|
||||
if ( result != 0 ) {
|
||||
error = 1;
|
||||
list[i]->return_value = -1;
|
||||
list[i]->error_code = EAGAIN;
|
||||
list[i]->return_status = AIO_NOTRETURNED;
|
||||
break;
|
||||
}
|
||||
|
||||
listcbp->requests_left++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rtems_aio_completed_list_op( listcbp );
|
||||
|
||||
if ( mode == LIO_NOWAIT ) {
|
||||
if ( error == 1 ) {
|
||||
rtems_set_errno_and_return_minus_one( EIO );
|
||||
}
|
||||
} else if ( mode == LIO_WAIT ) {
|
||||
rtems_event_set event_out;
|
||||
rtems_event_system_receive(
|
||||
RTEMS_EVENT_SYSTEM_AIO_LIST,
|
||||
RTEMS_DEFAULT_OPTIONS,
|
||||
RTEMS_NO_TIMEOUT,
|
||||
&event_out
|
||||
);
|
||||
|
||||
for ( int i = 0; i < nent; i++ ) {
|
||||
if ( list[i] != NULL ) {
|
||||
if (
|
||||
list[i]->aio_lio_opcode == LIO_READ ||
|
||||
list[i]->aio_lio_opcode == LIO_WRITE
|
||||
) {
|
||||
switch ( list[i]->error_code ) {
|
||||
case 0:
|
||||
break;
|
||||
case EINPROGRESS:
|
||||
rtems_set_errno_and_return_minus_one( EINTR );
|
||||
break;
|
||||
default:
|
||||
rtems_set_errno_and_return_minus_one( EIO );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ links:
|
||||
uid: psxaio03
|
||||
- role: build-dependency
|
||||
uid: psxaio04
|
||||
- role: build-dependency
|
||||
uid: psxaio05
|
||||
- role: build-dependency
|
||||
uid: psxalarm01
|
||||
- role: build-dependency
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
|
||||
build-type: test-program
|
||||
cflags: []
|
||||
copyrights:
|
||||
- Copyright (C) 2024 Alessandro Nardin <ale.daluch@gmail.com>
|
||||
cppflags: []
|
||||
cxxflags: []
|
||||
enabled-by:
|
||||
- RTEMS_POSIX_API
|
||||
features: c cprogram
|
||||
includes: []
|
||||
ldflags: []
|
||||
links: []
|
||||
source:
|
||||
- testsuites/psxtests/psxaio05/init.c
|
||||
stlib: []
|
||||
target: testsuites/psxtests/psxaio05.exe
|
||||
type: build
|
||||
use-after: []
|
||||
use-before: []
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -46,10 +47,10 @@ const char rtems_test_name[] = "PSXAIO 1";
|
||||
#define WRONG_FD 404
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
struct aiocb *create_aiocb( int fd );
|
||||
void free_aiocb( struct aiocb *aiocbp );
|
||||
static struct aiocb *create_aiocb( int fd );
|
||||
static void free_aiocb( struct aiocb *aiocbp );
|
||||
|
||||
struct aiocb *create_aiocb( int fd )
|
||||
static struct aiocb *create_aiocb( int fd )
|
||||
{
|
||||
struct aiocb *aiocbp;
|
||||
|
||||
@@ -64,7 +65,7 @@ struct aiocb *create_aiocb( int fd )
|
||||
return aiocbp;
|
||||
}
|
||||
|
||||
void free_aiocb( struct aiocb *aiocbp )
|
||||
static void free_aiocb( struct aiocb *aiocbp )
|
||||
{
|
||||
free( (void*) aiocbp->aio_buf );
|
||||
free( aiocbp );
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -44,14 +45,14 @@
|
||||
const char rtems_test_name[] = "PSXAIO 2";
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
struct aiocb *create_aiocb( int fd );
|
||||
void free_aiocb( struct aiocb *aiocbp );
|
||||
static struct aiocb *create_aiocb( int fd );
|
||||
static void free_aiocb( struct aiocb *aiocbp );
|
||||
|
||||
#define BUFSIZE 32
|
||||
#define FD_COUNT 10
|
||||
#define WRONG_FD 666
|
||||
|
||||
struct aiocb *create_aiocb( int fd )
|
||||
static struct aiocb *create_aiocb( int fd )
|
||||
{
|
||||
struct aiocb *aiocbp;
|
||||
|
||||
@@ -66,7 +67,7 @@ struct aiocb *create_aiocb( int fd )
|
||||
return aiocbp;
|
||||
}
|
||||
|
||||
void free_aiocb( struct aiocb *aiocbp )
|
||||
static void free_aiocb( struct aiocb *aiocbp )
|
||||
{
|
||||
free( (void*) aiocbp->aio_buf );
|
||||
free( aiocbp );
|
||||
@@ -94,8 +95,6 @@ void *POSIX_Init( void *argument )
|
||||
rtems_test_assert( !status );
|
||||
|
||||
TEST_BEGIN();
|
||||
|
||||
puts( "Init: Open files" );
|
||||
|
||||
for( i=0; i<FD_COUNT; i++ )
|
||||
{
|
||||
|
||||
@@ -50,13 +50,13 @@
|
||||
const char rtems_test_name[] = "PSXAIO 3";
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
struct aiocb *create_aiocb( int fd );
|
||||
void free_aiocb( struct aiocb *aiocbp );
|
||||
static struct aiocb *create_aiocb( int fd );
|
||||
static void free_aiocb( struct aiocb *aiocbp );
|
||||
|
||||
#define FD_COUNT 6
|
||||
#define BUFSIZE 128
|
||||
|
||||
struct aiocb *create_aiocb( int fd )
|
||||
static struct aiocb *create_aiocb( int fd )
|
||||
{
|
||||
struct aiocb *aiocbp;
|
||||
|
||||
@@ -71,7 +71,7 @@ struct aiocb *create_aiocb( int fd )
|
||||
return aiocbp;
|
||||
}
|
||||
|
||||
void free_aiocb( struct aiocb *aiocbp )
|
||||
static void free_aiocb( struct aiocb *aiocbp )
|
||||
{
|
||||
free( (void*) aiocbp->aio_buf );
|
||||
free( aiocbp );
|
||||
|
||||
@@ -47,11 +47,11 @@ const char rtems_test_name[] = "PSXAIO 4";
|
||||
#define WRONG_FD 404
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
struct aiocb *create_aiocb( int fd );
|
||||
void free_aiocb( struct aiocb *aiocbp );
|
||||
void notify( union sigval sig );
|
||||
static struct aiocb *create_aiocb( int fd );
|
||||
static void free_aiocb( struct aiocb *aiocbp );
|
||||
static void notify( union sigval sig );
|
||||
|
||||
struct aiocb *create_aiocb( int fd )
|
||||
static struct aiocb *create_aiocb( int fd )
|
||||
{
|
||||
struct aiocb *aiocbp;
|
||||
|
||||
@@ -66,13 +66,13 @@ struct aiocb *create_aiocb( int fd )
|
||||
return aiocbp;
|
||||
}
|
||||
|
||||
void free_aiocb( struct aiocb *aiocbp )
|
||||
static void free_aiocb( struct aiocb *aiocbp )
|
||||
{
|
||||
free( (void*) aiocbp->aio_buf );
|
||||
free( aiocbp );
|
||||
}
|
||||
|
||||
void notify( union sigval sig )
|
||||
static void notify( union sigval sig )
|
||||
{
|
||||
kill( getpid(), sig.sival_int );
|
||||
}
|
||||
@@ -144,6 +144,7 @@ void *POSIX_Init( void *argument )
|
||||
|
||||
TEST_END();
|
||||
|
||||
free_aiocb( aiocbp );
|
||||
close( fd );
|
||||
rtems_test_exit( 0 );
|
||||
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/*
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
#include "system.h"
|
||||
#include <rtems.h>
|
||||
#include "tmacros.h"
|
||||
#include <rtems/posix/aio_misc.h>
|
||||
#include <aio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
const char rtems_test_name[] = "PSXAIO 5";
|
||||
|
||||
#define BUFSIZE 512
|
||||
#define WRONG_FD 404
|
||||
#define BAD_MODE 38576
|
||||
|
||||
/* forward declarations to avoid warnings */
|
||||
static struct aiocb *create_aiocb( int fd );
|
||||
static void free_aiocb( struct aiocb *aiocbp );
|
||||
static void test_einval( struct aiocb** aiocbp );
|
||||
static void test_eio( struct aiocb** aiocbp );
|
||||
static void test_no_wait( struct aiocb** aiocbp );
|
||||
static void test_wait( struct aiocb** aiocbp );
|
||||
|
||||
static struct aiocb *create_aiocb( int fd )
|
||||
{
|
||||
struct aiocb *aiocbp;
|
||||
|
||||
aiocbp = malloc( sizeof( struct aiocb ) );
|
||||
memset( aiocbp, 0, sizeof( struct aiocb ) );
|
||||
aiocbp->aio_buf = malloc( BUFSIZE * sizeof( char ) );
|
||||
aiocbp->aio_nbytes = BUFSIZE;
|
||||
aiocbp->aio_offset = 0;
|
||||
aiocbp->aio_reqprio = 0;
|
||||
aiocbp->aio_fildes = fd;
|
||||
aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE;
|
||||
aiocbp->aio_lio_opcode = LIO_READ;
|
||||
return aiocbp;
|
||||
}
|
||||
|
||||
static void free_aiocb( struct aiocb *aiocbp )
|
||||
{
|
||||
free( (void*) aiocbp->aio_buf );
|
||||
free( aiocbp );
|
||||
}
|
||||
|
||||
static void test_einval( struct aiocb** aiocbp )
|
||||
{
|
||||
int status;
|
||||
|
||||
status = lio_listio( LIO_WAIT, NULL, 1, NULL);
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
errno = 0;
|
||||
|
||||
status = lio_listio( BAD_MODE, aiocbp, 1, NULL);
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
errno = 0;
|
||||
|
||||
status = lio_listio( LIO_WAIT, aiocbp, -9, NULL);
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
errno = 0;
|
||||
|
||||
status = lio_listio( LIO_WAIT, aiocbp, 547, NULL);
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == EINVAL );
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
static void test_eio( struct aiocb** aiocbp )
|
||||
{
|
||||
int status;
|
||||
|
||||
status = lio_listio( LIO_NOWAIT, &aiocbp[4], 1, NULL);
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == EIO );
|
||||
errno = 0;
|
||||
|
||||
status = lio_listio( LIO_WAIT, &aiocbp[4], 1, NULL);
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == EIO );
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
static void test_no_wait( struct aiocb** aiocbp )
|
||||
{
|
||||
int status, received_signal, sig;
|
||||
struct sigevent sigev;
|
||||
sigset_t sig_set;
|
||||
|
||||
sig = SIGUSR1;
|
||||
sigev.sigev_notify = SIGEV_SIGNAL;
|
||||
sigev.sigev_signo = sig;
|
||||
sigev.sigev_value.sival_ptr = NULL;
|
||||
|
||||
status = sigemptyset( &sig_set );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = sigaddset( &sig_set, sig );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = sigprocmask( SIG_BLOCK, &sig_set, NULL );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = lio_listio( LIO_NOWAIT, aiocbp, 4, &sigev);
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = sigwait( &sig_set, &received_signal );
|
||||
rtems_test_assert( status == 0 );
|
||||
rtems_test_assert( received_signal == sig );
|
||||
|
||||
status = sigprocmask( SIG_UNBLOCK, &sig_set, NULL );
|
||||
rtems_test_assert( status == 0 );
|
||||
}
|
||||
|
||||
static void test_wait( struct aiocb** aiocbp )
|
||||
{
|
||||
int status;
|
||||
|
||||
status = lio_listio( LIO_WAIT, aiocbp, 4, NULL);
|
||||
rtems_test_assert( status == 0 );
|
||||
}
|
||||
|
||||
void *POSIX_Init( void *argument )
|
||||
{
|
||||
struct aiocb *aiocbp[] = { NULL, NULL, NULL, NULL, NULL };
|
||||
int fd, result;
|
||||
|
||||
rtems_aio_init();
|
||||
|
||||
result = mkdir( "/tmp", S_IRWXU );
|
||||
rtems_test_assert( result == 0 );
|
||||
|
||||
fd = open(
|
||||
"/tmp/aio_fildes",
|
||||
O_RDWR|O_CREAT,
|
||||
S_IRWXU|S_IRWXG|S_IRWXO
|
||||
);
|
||||
rtems_test_assert( fd != -1 );
|
||||
|
||||
TEST_BEGIN();
|
||||
|
||||
for (int i = 0; i<4; i++ ) {
|
||||
aiocbp[i] = create_aiocb( fd );
|
||||
}
|
||||
aiocbp[4] = create_aiocb( WRONG_FD );
|
||||
|
||||
test_einval( aiocbp );
|
||||
|
||||
test_eio( aiocbp );
|
||||
|
||||
test_no_wait( aiocbp );
|
||||
|
||||
test_wait( aiocbp );
|
||||
|
||||
TEST_END();
|
||||
|
||||
for (int i = 0; i<5; i++ ) {
|
||||
free_aiocb(aiocbp[i]);
|
||||
}
|
||||
|
||||
close( fd );
|
||||
rtems_test_exit( 0 );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
*** BEGIN OF TEST PSXAIO 5 ***
|
||||
*** END OF TEST PSXAIO 5 ***
|
||||
@@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/*
|
||||
* Copyright 2024, Alessandro Nardin <ale.daluch@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* functions */
|
||||
|
||||
#include <pmacros.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
|
||||
void *POSIX_Init( void *argument );
|
||||
|
||||
/* configuration information */
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS 20
|
||||
#define CONFIGURE_MAXIMUM_SEMAPHORES 20
|
||||
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20
|
||||
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20
|
||||
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 10
|
||||
#define CONFIGURE_MAXIMUM_POSIX_KEYS 10
|
||||
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
#define CONFIGURE_EXTRA_TASK_STACKS ( 10 * RTEMS_MINIMUM_STACK_SIZE )
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE ( 10 * RTEMS_MINIMUM_STACK_SIZE )
|
||||
|
||||
#include <rtems/confdefs.h>
|
||||
|
||||
/* global variables */
|
||||
TEST_EXTERN pthread_t Init_id;
|
||||
|
||||
/* end of include file */
|
||||
Reference in New Issue
Block a user