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:
alessandronardin
2024-09-02 18:16:30 +02:00
parent ad51286e2b
commit 1b6684ee2b
20 changed files with 781 additions and 101 deletions
+40 -12
View File
@@ -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.
+90 -3
View File
@@ -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>
+6
View File
@@ -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 */
/**
+1
View File
@@ -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).
+1
View File
@@ -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).
+7
View File
@@ -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
View File
@@ -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, &param );
discussion in rtems_aio_enqueue() */
pthread_getschedparam(
pthread_self(),
&policy,
&param
);
param.sched_priority = req->priority;
pthread_setschedparam( pthread_self(), req->policy, &param );
@@ -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 );
}
+9 -27
View File
@@ -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;
}
}
+1
View File
@@ -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 -28
View File
@@ -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;
}
}
+157 -6
View File
@@ -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;
}
+2
View File
@@ -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: []
+5 -4
View File
@@ -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 );
+5 -6
View File
@@ -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++ )
{
+4 -4
View File
@@ -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 );
+7 -6
View File
@@ -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 );
+202
View File
@@ -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 ***
+61
View File
@@ -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 */