blob: b002363a41807f4682f40607d093b287dfaf057a [file] [log] [blame]
//------------------------------------------------------------------
//
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include "seabed/fserr.h"
#include "seabed/ms.h"
#include "seabed/pctl.h"
#include "seabed/pevents.h"
#include "seabed/thread.h"
#include "tchkfe.h"
#include "tmsfsutil.h"
#include "tutil.h"
int pin;
long t_elapsed;
long t_elapsed2;
struct timeval t_start;
struct timeval t_start2;
struct timeval t_start3;
struct timeval t_stop;
enum { TOLERANCE = 50000 };
#define check_min(min) { \
assert(t_elapsed >= min); \
assert(t_elapsed <= (min + TOLERANCE)); \
}
#define check_max(max) { \
assert(t_elapsed < max); \
}
void *thr(void *arg) {
arg = arg; // touch
usleep(20000);
XAWAKE(pin, LSEM);
return NULL;
}
void telapsed(struct timeval *start, struct timeval *stop) {
t_elapsed = stop->tv_sec * 1000000 + stop->tv_usec -
start->tv_sec * 1000000 - start->tv_usec;
printf("elapsed=%ld\n", t_elapsed);
}
void tstart() {
gettimeofday(&t_start, NULL);
// printf("start=%ld.%ld\n", t_start.tv_sec, t_start.tv_usec);
}
void tstop() {
gettimeofday(&t_stop, NULL);
// printf("stop=%ld.%ld\n", t_stop.tv_sec, t_stop.tv_usec);
telapsed(&t_start, &t_stop);
}
//
// Check XWAIT*(... -1)
//
void test_wait_neg1(bool zero) {
short event;
printf("XWAIT%s0(..., -1)\n", zero ? "" : "NO");
XAWAKE(pin, LSEM);
tstart();
if (zero)
event = XWAIT0(LSEM, -1);
else
event = XWAITNO0(LSEM, -1);
assert(event == LSEM);
tstop();
check_max(TOLERANCE);
}
//
// Check XWAIT*(... -2)
//
void test_wait_neg2(bool zero) {
short event;
printf("XWAIT%s0(..., -2)\n", zero ? "" : "NO");
tstart();
if (zero)
event = XWAIT0(0, -2);
else
event = XWAITNO0(0, -2);
assert(event == 0);
tstop();
check_max(TOLERANCE);
}
//
// Check XWAITNO0(... 100)
// Check XWAITNO0(... 10)
// With first no timeout
//
void test_wait_pos() {
short event;
printf("XWAITNO0(..., 100); XWAITNO0(..., 10)\n");
tstart();
t_start2.tv_sec = t_start.tv_sec;
t_start2.tv_usec = t_start.tv_usec;
SB_Thread::Sthr::Id_Ptr lthr =
SB_Thread::Sthr::create((char *) "th", thr, (void *) (long) pin);
event = XWAITNO0(LSEM, 100);
assert(event == LSEM);
tstop();
check_min(20000);
tstart();
event = XWAITNO0(LSEM, 10);
assert(event == 0);
tstop();
check_min(100000);
void *value;
int status = SB_Thread::Sthr::join(lthr, &value);
assert(status == 0);
SB_Thread::Sthr::delete_id(lthr);
}
//
// Check XWAIT0(... 100)
// Check XWAIT0(... 0)
// With first no timeout
//
void test_wait_pos_no_timeout() {
short event;
printf("XWAIT0(..., 100); XWAIT0(..., 0)\n");
tstart();
t_start2.tv_sec = t_start.tv_sec;
t_start2.tv_usec = t_start.tv_usec;
SB_Thread::Sthr::Id_Ptr lthr =
SB_Thread::Sthr::create((char *) "th", thr, (void *) (long) pin);
gettimeofday(&t_start3, NULL);
event = XWAIT0(LSEM, 100);
assert(event == LSEM);
tstop();
check_min(20000);
telapsed(&t_start3, &t_stop);
t_elapsed2 = t_elapsed;
tstart();
event = XWAIT0(LSEM, 0);
assert(event == 0);
tstop();
check_min(1000000 - t_elapsed2);
telapsed(&t_start2, &t_stop);
check_min(1000000);
void *value;
int status = SB_Thread::Sthr::join(lthr, &value);
assert(status == 0);
SB_Thread::Sthr::delete_id(lthr);
}
//
// Check XWAIT0(... 50)
// Check XWAIT0(... 0)
// With first timedout
//
void test_wait_pos_timeout() {
short event;
printf("XWAIT0(..., 50); XWAIT0(..., 0)\n");
tstart();
event = XWAIT0(LSEM, 50);
assert(event == 0);
tstop();
check_min(500000);
tstart();
event = XWAIT0(LSEM, 0);
assert(event == 0);
tstop();
check_max(TOLERANCE);
}
int main(int argc, char *argv[]) {
SB_Thread::CV cv;
short event;
int ferr;
int ret;
msfs_util_init(&argc, &argv, msg_debug_hook);
util_test_start(true);
ferr = msg_mon_process_startup(false); // system messages?
TEST_CHK_FEOK(ferr);
//
// Check that cv_wait gets ETIMEDOUT
//
for (;;) {
tstart();
if ((t_start.tv_usec / 100000) == 8)
break;
usleep(10000);
}
ret = cv.wait(true, 0, 900000);
assert(ret == ETIMEDOUT);
tstop();
printf("elapsed=%ld\n", t_elapsed);
check_min(900000);
pin = 1;
proc_register_group_pin(-1, pin);
//
// Remove LREQ
//
event = XWAIT0(LREQ, -2);
assert(event == LREQ);
//
// Test XWAIT0
//
test_wait_neg2(true);
test_wait_neg1(true);
test_wait_pos_timeout();
test_wait_pos_no_timeout();
//
// Test XWAITNO0
//
test_wait_neg2(false);
test_wait_neg1(false);
test_wait_pos();
ferr = msg_mon_process_shutdown();
TEST_CHK_FEOK(ferr);
util_test_finish(true);
printf("if there were no asserts, all is well\n");
return 0;
}