Skip to content

Instantly share code, notes, and snippets.

@joycemaferko
Created October 15, 2021 09:32
Show Gist options
  • Save joycemaferko/0ecfd6789307e3fe231a082a76951bef to your computer and use it in GitHub Desktop.
Save joycemaferko/0ecfd6789307e3fe231a082a76951bef to your computer and use it in GitHub Desktop.
RTEMS Test for pthread_wrlock_clockrdlock and pthread_wrlock_clockwrlock
/*
* Copyright (C) 2021 Matthew Joyce
* COPYRIGHT (c) 1989-2008
* On-Line Applications Research Corporation (OAR)
*
* 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.
*/
/* Defining to have access to function prototype in libc/include/pthread.h */
#define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/test-info.h>
#include <bsp.h>
#include <pmacros.h>
#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "tmacros.h"
#define BAD_CLOCK 0xdeadbeef
const char rtems_test_name[] = "PSXRWLOCK 2";
pthread_rwlock_t RWLock;
static void test_rwlock_auto_initialization( void )
{
struct timespec to;
int eno;
{
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw, BAD_CLOCK, &to );
rtems_test_assert( eno == EINVAL );
}
{
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw, BAD_CLOCK, &to );
rtems_test_assert( eno == EINVAL );
}
{
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == 0 );
}
{
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_REALTIME, &to );
rtems_test_assert( eno == 0 );
}
{
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == 0 );
}
{
static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_REALTIME, &to );
rtems_test_assert( eno == 0 );
}
}
static void test_rwlock_null( void )
{
struct timespec to;
int eno;
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( NULL, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( NULL, CLOCK_REALTIME, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( NULL, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( NULL, CLOCK_REALTIME, &to );
rtems_test_assert( eno == EINVAL );
}
static void test_invalid_clock( void )
{
pthread_rwlock_t rw;
struct timespec to;
int eno;
eno = pthread_rwlock_init( &rw, NULL );
rtems_test_assert( eno == 0 );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw, BAD_CLOCK, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw, BAD_CLOCK, &to );
rtems_test_assert( eno == EINVAL );
}
static void test_invalid_abstime( void )
{
pthread_rwlock_t rw;
struct timespec to;
int eno;
eno = pthread_rwlock_init( &rw, NULL );
rtems_test_assert( eno == 0 );
to.tv_sec = 1;
to.tv_nsec = -1;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1000000000;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1100000000;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = -1;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1000000000;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1100000000;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
}
static void test_rwlock_invalid_copy( void )
{
pthread_rwlock_t rw;
pthread_rwlock_t rw2;
struct timespec to;
int eno;
eno = pthread_rwlock_init( &rw, NULL );
rtems_test_assert( eno == 0 );
memcpy( &rw2, &rw, sizeof( rw2 ) );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw2, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw2, CLOCK_REALTIME, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw2, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw2, CLOCK_REALTIME, &to );
rtems_test_assert( eno == EINVAL );
}
static void test_rwlock_not_initialized( void )
{
pthread_rwlock_t rw;
struct timespec to;
int eno;
memset( &rw, 0xff, sizeof( rw ) );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockrdlock( &rw, CLOCK_REALTIME, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
rtems_test_assert( eno == EINVAL );
to.tv_sec = 1;
to.tv_nsec = 1;
eno = pthread_rwlock_clockwrlock( &rw, CLOCK_REALTIME, &to );
rtems_test_assert( eno == EINVAL );
}
static void *POSIX_Init(
void *argument
)
{
int status;
struct timespec abstime;
TEST_BEGIN();
test_rwlock_auto_initialization();
test_rwlock_null();
test_invalid_clock();
test_invalid_abstime();
test_rwlock_invalid_copy();
test_rwlock_not_initialized();
/*************** TIMEOUT ON RWLOCK MONOTONIC ***************/
status = pthread_rwlock_init( &RWLock, NULL );
rtems_test_assert( status == 0 );
status = clock_gettime( CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == 0 );
abstime.tv_sec += 1;
status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == 0 );
abstime.tv_sec += 1;
status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == ETIMEDOUT );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == ETIMEDOUT );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == ETIMEDOUT );
/*************** OBTAIN RWLOCK FOR READ WITH ABSTIME IN PAST ***************/
status = pthread_rwlock_unlock( &RWLock );
rtems_test_assert( status == 0 );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == 0 );
/*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
status = pthread_rwlock_unlock( &RWLock );
rtems_test_assert( status == 0 );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime );
rtems_test_assert( status == 0 );
/*************** DESTROY RWLOCK ***************/
status = pthread_rwlock_destroy( &RWLock );
rtems_test_assert( status == 0 );
/*************** TIMEOUT ON RWLOCK REALTIME ***************/
status = pthread_rwlock_init( &RWLock, NULL );
rtems_test_assert( status == 0 );
status = clock_gettime( CLOCK_REALTIME, &abstime );
rtems_test_assert( status == 0 );
abstime.tv_sec += 1;
status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_REALTIME, &abstime );
rtems_test_assert( status == 0 );
abstime.tv_sec += 1;
status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_REALTIME, &abstime );
rtems_test_assert( status == ETIMEDOUT );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_REALTIME, &abstime );
rtems_test_assert( status == ETIMEDOUT );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_REALTIME, &abstime );
rtems_test_assert( status == ETIMEDOUT );
/*************** OBTAIN RWLOCK FOR READ WITH ABSTIME IN PAST ***************/
status = pthread_rwlock_unlock( &RWLock );
rtems_test_assert( status == 0 );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_REALTIME, &abstime );
rtems_test_assert( status == 0 );
/*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
status = pthread_rwlock_unlock( &RWLock );
rtems_test_assert( status == 0 );
abstime.tv_sec -= 1;
status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_REALTIME, &abstime );
rtems_test_assert( status == 0 );
/*************** DESTROY RWLOCK ***************/
status = pthread_rwlock_destroy( &RWLock );
rtems_test_assert( status == 0 );
/*************** END OF TEST *****************/
TEST_END();
rtems_test_exit( 0 );
return NULL; /* just so the compiler thinks we returned something */
}
/* configuration information */
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
#define CONFIGURE_INIT_TASK_PRIORITY 2
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_PREEMPT
#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
/* end of file */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment