20
20
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
21
// ------------------------------------------------------------------------
26
32
#include <stddef.h> /* ANSI-C: size_t */
27
33
#include <stdio.h> /* for AIX */
28
#include <stdlib.h> /* ANSI-C: atoi() */
29
34
#include <time.h> /* ANSI-C: clock() */
31
#include <unistd.h> /* POSIX: sleep() */
33
37
#include "kvu_locks.h"
34
38
#include "kvu_numtostr.h"
35
39
#include "kvu_rtcaps.h"
40
#include "kvu_timestamp.h"
36
41
#include "kvu_utils.h"
37
42
#include "kvu_value_queue.h"
43
#include "kvu_message_queue.h"
39
45
using namespace std;
52
#define ECA_TEST_ENTRY() do { printf("\n%s:%d - Test started\n", __FILE__, __LINE__); } while(0)
53
#define ECA_TEST_SUCCESS() do { printf("%s:%d - Test passed\n", __FILE__, __LINE__); return 0; } while(0)
54
#define ECA_TEST_FAIL(x,y) do { printf("\n%s:%d - Test failed: \"%s\"\n", __FILE__, __LINE__, y); return x; } while(0)
55
#define ECA_TEST_NOTE(x) do { printf("%s:%d - %s\n", __FILE__, __LINE__, x); fflush(stdout); } while(0)
58
#define ECA_TEST_ENTRY() do { printf("\n%s:%d - Test started\n", __KVU_FUNCTION, __LINE__); } while(0)
59
#define ECA_TEST_SUCCESS() do { printf("%s:%d - Test passed\n", __KVU_FUNCTION, __LINE__); return 0; } while(0)
60
#define ECA_TEST_FAIL(x,y) do { printf("\n%s:%d - Test failed: \"%s\"\n", __KVU_FUNCTION, __LINE__, y); return x; } while(0)
61
#define ECA_TEST_NOTE(x) do { printf("%s:%d - %s\n", __KVU_FUNCTION, __LINE__, x); fflush(stdout); } while(0)
57
63
#define ECA_TEST_ENTRY() ((void) 0)
58
64
#define ECA_TEST_SUCCESS() return 0
74
80
static int kvu_test_2(void);
75
81
static int kvu_test_3(void);
76
82
static int kvu_test_4(void);
77
static void* kvu_test_1_helper(void* ptr);
78
static void* kvu_test_4_helper(void* ptr);
83
static int kvu_test_5_timestamp(void);
84
static int kvu_test_6_msgqueue(void);
80
86
static kvu_test_t kvu_funcs[] = {
87
kvu_test_1, /* kvu_locks.h: ATOMIC_INTEGER */
88
kvu_test_2, /* kvu_utils.h: string handling */
89
kvu_test_3, /* kvu_utils.h: float2str */
90
kvu_test_4, /* kvu_value_queue.h */
91
kvu_test_5_timestamp, /* kvu_timestamp.h */
92
kvu_test_6_msgqueue, /* kvu_message_queue.h */
433
443
/* never reached */
448
* Tests the kvu_timestamp.h interface
450
static int kvu_test_5_timestamp(void)
454
struct timespec stamp;
457
kvu_clock_is_monotonic();
458
double start, now, prev, end;
460
res = kvu_clock_gettime(&stamp);
462
ECA_TEST_FAIL(1, "kvu_test_5-1 clock_gettime failed");
464
start = kvu_timespec_seconds(&stamp);
468
ECA_TEST_NOTE("3s timer loop starts");
473
kvu_sleep(0, 5000000);
475
res = kvu_clock_gettime(&stamp);
477
ECA_TEST_FAIL(1, "kvu_test_5-2 clock_gettime failed");
478
now = kvu_timespec_seconds(&stamp);
481
fprintf(stderr, "now=%.09f delta=%.09f end=%.03f\n",
482
now - start, now - prev, end - start);
487
ECA_TEST_FAIL(1, "kvu_test_5-3 clock goes backwards");
489
ECA_TEST_NOTE("kvu_test_5 - clock went backwards");
498
/* note: around 50ms per iteration */
499
static const int kvu_test_6_iterations_const = 100;
500
static int kvu_test_6_retval = 0;
502
static void* kvu_test_6_helper(void* ptr);
505
* Tests the MESSAGE_QUEUE_RT_C class implementation.
507
static int kvu_test_6_msgqueue(void)
511
std::srand(std::time(0));
513
/* guarantee bounded execution time only upto 16 items */
514
MESSAGE_QUEUE_RT_C<std::string> rqueue (16);
516
ECA_TEST_NOTE("start-test");
519
pthread_create(&thread, NULL, kvu_test_6_helper, (void*)&rqueue);
523
ECA_TEST_NOTE("start-item-push");
525
for(int iter = 0; iter < kvu_test_6_iterations_const; iter++) {
526
// fprintf(stderr, "%s:%d push.\n", __FUNCTION__, __LINE__);
527
std::string msg = kvu_numtostr(iter + 1);
528
//std::fprintf(stdout, "%s:%d pushed '%s'\n", __FUNCTION__, __LINE__, msg.c_str());
529
rqueue.push_back(msg);
530
int sleep_ns = std::rand() % 100;
532
kvu_sleep(0, sleep_ns * 1000000); /* [0,100]ms */
536
pthread_join(thread, (void**)&res_ptr);
537
if (*(int*)res_ptr != 0) {
538
ECA_TEST_FAIL(1, "kvu_test_6 slave-thread-failed");
541
ECA_TEST_NOTE("end-test.");
547
* The real-time consumer thread.
549
static void* kvu_test_6_helper(void* ptr)
551
MESSAGE_QUEUE_RT_C<std::string> *rqueue =
552
static_cast<MESSAGE_QUEUE_RT_C<std::string>*>(ptr);
554
kvu_test_6_retval = 0;
556
ECA_TEST_NOTE("start-thread.");
558
int res = kvu_set_thread_scheduling(SCHED_FIFO, 1);
560
ECA_TEST_NOTE("schedfifo-scheduling-enabled");
563
ECA_TEST_NOTE("schedfifo-scheduling-disabled");
566
std::string last_received_v;
567
for(int received = 0; received < kvu_test_6_iterations_const; ) {
568
int sleep_ns = std::rand() % 100;
570
kvu_sleep(0, sleep_ns * 1000000); /* [0,100]ms */
572
if (rqueue->is_empty() != true) {
574
int popres = rqueue->pop_front(&ref);
576
// std::fprintf(stdout, "%s:%d popped '%s'\n", __FUNCTION__, __LINE__, ref.c_str());
578
if (last_received_v == ref) {
579
ECA_TEST_NOTE("queue-sync-error");
580
kvu_test_6_retval = -1;
583
last_received_v = ref;
586
ECA_TEST_NOTE("corner-case-queue-busy");
591
if (std::atoi(last_received_v.c_str()) != kvu_test_6_iterations_const) {
592
// std::fprintf(stdout, "%s:%d last item '%s'\n", __FUNCTION__, __LINE__, last_received_v.c_str());
593
ECA_TEST_NOTE("end-of-queue-sync-error");
594
kvu_test_6_retval = -1;
597
ECA_TEST_NOTE("exit-thread");
599
pthread_exit(&kvu_test_6_retval);