2021-02-10 21:33:03 +03:00
|
|
|
#ifndef _XOPEN_SOURCE
|
2021-04-07 00:28:50 +03:00
|
|
|
#define _XOPEN_SOURCE 700
|
2021-02-10 21:33:03 +03:00
|
|
|
#endif
|
2021-02-05 16:35:10 +03:00
|
|
|
|
2020-11-11 01:19:49 +03:00
|
|
|
#include "sc_timer.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#if defined(_WIN32) || defined(_WIN64)
|
2021-04-07 00:28:50 +03:00
|
|
|
#include <windows.h>
|
2020-11-11 01:19:49 +03:00
|
|
|
#else
|
2021-04-07 00:28:50 +03:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
2020-11-11 01:19:49 +03:00
|
|
|
#endif
|
|
|
|
|
2022-08-20 18:56:21 +03:00
|
|
|
uint64_t time_ms(void)
|
2020-11-11 01:19:49 +03:00
|
|
|
{
|
|
|
|
#if defined(_WIN32) || defined(_WIN64)
|
2021-04-07 00:28:50 +03:00
|
|
|
// System frequency does not change at run-time, cache it
|
|
|
|
static int64_t frequency = 0;
|
|
|
|
if (frequency == 0) {
|
|
|
|
LARGE_INTEGER freq;
|
|
|
|
QueryPerformanceFrequency(&freq);
|
|
|
|
assert(freq.QuadPart != 0);
|
|
|
|
frequency = freq.QuadPart;
|
|
|
|
}
|
|
|
|
LARGE_INTEGER count;
|
|
|
|
QueryPerformanceCounter(&count);
|
2021-04-15 01:30:58 +03:00
|
|
|
return (int64_t) (count.QuadPart * 1000) / frequency;
|
2020-11-11 01:19:49 +03:00
|
|
|
#else
|
2021-04-07 00:28:50 +03:00
|
|
|
int rc;
|
|
|
|
struct timespec ts;
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
rc = clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
|
assert(rc == 0);
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-15 01:30:58 +03:00
|
|
|
return (int64_t) ((int64_t) ts.tv_sec * 1000 +
|
|
|
|
(int64_t) ts.tv_nsec / 1000000);
|
2020-11-11 01:19:49 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void sleep_ms(uint64_t milliseconds)
|
|
|
|
{
|
|
|
|
#if defined(_WIN32) || defined(_WIN64)
|
2021-04-07 00:28:50 +03:00
|
|
|
Sleep(milliseconds);
|
2020-11-11 01:19:49 +03:00
|
|
|
#else
|
2021-04-07 00:28:50 +03:00
|
|
|
int rc;
|
|
|
|
struct timespec t;
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
t.tv_sec = milliseconds / 1000;
|
|
|
|
t.tv_nsec = (milliseconds % 1000) * 1000000;
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
do {
|
|
|
|
rc = nanosleep(&t, NULL);
|
|
|
|
} while (rc != 0 && errno != EINTR);
|
2020-11-11 01:19:49 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-05-09 12:09:09 +03:00
|
|
|
int count;
|
2020-11-11 01:19:49 +03:00
|
|
|
uint64_t ids[1000];
|
|
|
|
|
2020-11-17 04:58:36 +03:00
|
|
|
void callback(void *arg, uint64_t timeout, uint64_t type, void *data)
|
2020-11-11 01:19:49 +03:00
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
(void) timeout;
|
|
|
|
(void) type;
|
2021-02-07 22:31:04 +03:00
|
|
|
|
2021-05-09 12:09:09 +03:00
|
|
|
count--;
|
2021-04-07 00:28:50 +03:00
|
|
|
uint64_t id = (uintptr_t) data;
|
|
|
|
assert(ids[id] != SC_TIMER_INVALID);
|
|
|
|
ids[id] = SC_TIMER_INVALID;
|
|
|
|
assert((int) (uintptr_t) arg == 333);
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void test1(void)
|
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
struct sc_timer timer;
|
|
|
|
|
2021-04-13 22:16:30 +03:00
|
|
|
sc_timer_init(&timer, time_ms());
|
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
ids[i] = sc_timer_add(&timer, rand() % 100, i,
|
|
|
|
(void *) (uintptr_t) i);
|
2021-05-09 12:09:09 +03:00
|
|
|
count++;
|
2021-04-07 00:28:50 +03:00
|
|
|
assert(ids[i] != SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
int t = 10000;
|
|
|
|
uint32_t n;
|
|
|
|
while (t > 0) {
|
|
|
|
n = sc_timer_timeout(&timer, time_ms(),
|
|
|
|
(void *) (uintptr_t) 333, callback);
|
2021-05-09 12:09:09 +03:00
|
|
|
if (count == 0) {
|
2021-04-07 00:28:50 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
t -= n;
|
|
|
|
sleep_ms(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
assert(ids[i] == SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_timer_term(&timer);
|
2021-04-13 22:16:30 +03:00
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
ids[i] = sc_timer_add(&timer, rand() % 100, i,
|
|
|
|
(void *) (uintptr_t) i);
|
2021-05-09 12:09:09 +03:00
|
|
|
count++;
|
2021-04-13 22:16:30 +03:00
|
|
|
assert(ids[i] != SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
t = 10000;
|
|
|
|
while (t > 0) {
|
|
|
|
n = sc_timer_timeout(&timer, time_ms(),
|
|
|
|
(void *) (uintptr_t) 333, callback);
|
2021-05-09 12:09:09 +03:00
|
|
|
if (count == 0) {
|
2021-04-13 22:16:30 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
t -= n;
|
|
|
|
sleep_ms(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
assert(ids[i] == SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_timer_term(&timer);
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void test2(void)
|
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
struct sc_timer timer;
|
|
|
|
|
2021-04-13 22:16:30 +03:00
|
|
|
sc_timer_init(&timer, time_ms());
|
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
ids[i] = SC_TIMER_INVALID;
|
|
|
|
sc_timer_add(&timer, rand() % 100, i, (void *) (uintptr_t) i);
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_timer_clear(&timer);
|
|
|
|
|
|
|
|
int t = 10000;
|
|
|
|
uint32_t n;
|
|
|
|
while (t > 0) {
|
|
|
|
n = sc_timer_timeout(&timer, time_ms(),
|
|
|
|
(void *) (uintptr_t) 333, callback);
|
2021-05-09 12:09:09 +03:00
|
|
|
if (count == 0) {
|
2021-04-07 00:28:50 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
t -= n;
|
|
|
|
sleep_ms(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
assert(ids[i] == SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
ids[i] = sc_timer_add(&timer, rand() % 100, i,
|
|
|
|
(void *) (uintptr_t) i);
|
|
|
|
assert(ids[i] != SC_TIMER_INVALID);
|
2021-05-09 12:09:09 +03:00
|
|
|
count++;
|
2021-04-07 00:28:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
t = 10000;
|
|
|
|
while (t > 0) {
|
|
|
|
n = sc_timer_timeout(&timer, time_ms(),
|
|
|
|
(void *) (uintptr_t) 333, callback);
|
2021-05-09 12:09:09 +03:00
|
|
|
if (count == 0) {
|
2021-04-07 00:28:50 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
t -= n;
|
|
|
|
sleep_ms(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
assert(ids[i] == SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_timer_term(&timer);
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void test3(void)
|
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
struct sc_timer timer;
|
|
|
|
|
2021-04-13 22:16:30 +03:00
|
|
|
sc_timer_init(&timer, time_ms());
|
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
ids[i] = sc_timer_add(&timer, rand() % 20, i,
|
|
|
|
(void *) (uintptr_t) i);
|
|
|
|
assert(ids[i] != SC_TIMER_INVALID);
|
2021-05-09 12:09:09 +03:00
|
|
|
count++;
|
2021-04-07 00:28:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i += 2) {
|
|
|
|
sc_timer_cancel(&timer, &ids[i]);
|
2021-05-09 12:09:09 +03:00
|
|
|
count--;
|
2021-04-07 00:28:50 +03:00
|
|
|
}
|
|
|
|
|
2021-05-09 12:09:09 +03:00
|
|
|
assert(count == 500);
|
2021-04-07 00:28:50 +03:00
|
|
|
sc_timer_cancel(&timer, &ids[0]);
|
2021-05-09 12:09:09 +03:00
|
|
|
assert(count == 500);
|
2021-04-07 00:28:50 +03:00
|
|
|
|
|
|
|
int t = 10000;
|
|
|
|
uint32_t n;
|
|
|
|
while (t > 0) {
|
|
|
|
n = sc_timer_timeout(&timer, time_ms(),
|
|
|
|
(void *) (uintptr_t) 333, callback);
|
2021-05-09 12:09:09 +03:00
|
|
|
if (count == 0) {
|
2021-04-07 00:28:50 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
t -= n;
|
|
|
|
sleep_ms(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 500; i++) {
|
|
|
|
assert(ids[i] == SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_timer_term(&timer);
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|
|
|
|
|
2021-02-01 04:56:06 +03:00
|
|
|
void test4(void)
|
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
struct sc_timer timer;
|
|
|
|
|
2021-04-13 22:16:30 +03:00
|
|
|
sc_timer_init(&timer, 0);
|
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
ids[i] = sc_timer_add(&timer, rand() % 20, i,
|
|
|
|
(void *) (uintptr_t) i);
|
|
|
|
assert(ids[i] != SC_TIMER_INVALID);
|
2021-05-09 12:09:09 +03:00
|
|
|
count++;
|
2021-04-07 00:28:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000; i += 2) {
|
|
|
|
sc_timer_cancel(&timer, &ids[i]);
|
2021-05-09 12:09:09 +03:00
|
|
|
count--;
|
2021-04-07 00:28:50 +03:00
|
|
|
}
|
|
|
|
|
2021-05-09 12:09:09 +03:00
|
|
|
assert(count == 500);
|
2021-04-07 00:28:50 +03:00
|
|
|
sc_timer_cancel(&timer, &ids[0]);
|
2021-05-09 12:09:09 +03:00
|
|
|
assert(count == 500);
|
2021-04-07 00:28:50 +03:00
|
|
|
|
|
|
|
int t = 10000;
|
|
|
|
uint32_t n;
|
|
|
|
int x = 0;
|
|
|
|
while (t > 0) {
|
|
|
|
x += 500;
|
|
|
|
n = sc_timer_timeout(&timer, x, (void *) (uintptr_t) 333,
|
|
|
|
callback);
|
2021-05-09 12:09:09 +03:00
|
|
|
if (count == 0) {
|
2021-04-07 00:28:50 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
t -= n;
|
|
|
|
sleep_ms(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 500; i++) {
|
|
|
|
assert(ids[i] == SC_TIMER_INVALID);
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_timer_term(&timer);
|
2021-02-01 04:56:06 +03:00
|
|
|
}
|
|
|
|
|
2020-11-11 01:19:49 +03:00
|
|
|
#ifdef SC_HAVE_WRAP
|
|
|
|
|
|
|
|
bool fail_malloc = false;
|
|
|
|
void *__real_malloc(size_t n);
|
|
|
|
void *__wrap_malloc(size_t n)
|
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
if (fail_malloc) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
return __real_malloc(n);
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void fail_test(void)
|
|
|
|
{
|
2021-04-07 04:55:05 +03:00
|
|
|
size_t max = 50000;
|
2021-04-07 00:28:50 +03:00
|
|
|
struct sc_timer timer;
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-13 22:16:30 +03:00
|
|
|
sc_timer_init(&timer, time_ms());
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
uint64_t id;
|
|
|
|
for (size_t i = 0; i < max + 100; i++) {
|
|
|
|
id = sc_timer_add(&timer, i, i, 0);
|
|
|
|
if (id == SC_TIMER_INVALID) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
assert(id == SC_TIMER_INVALID);
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
sc_timer_term(&timer);
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
sc_timer_init(&timer, time_ms());
|
|
|
|
fail_malloc = true;
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
for (size_t i = 0; i < 65; i++) {
|
|
|
|
id = sc_timer_add(&timer, i, i, 0);
|
|
|
|
if (id == SC_TIMER_INVALID) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
assert(id == SC_TIMER_INVALID);
|
|
|
|
fail_malloc = false;
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
sc_timer_term(&timer);
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
void fail_test(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-08-20 18:56:21 +03:00
|
|
|
int main(void)
|
2020-11-11 01:19:49 +03:00
|
|
|
{
|
2021-04-07 00:28:50 +03:00
|
|
|
fail_test();
|
|
|
|
test1();
|
|
|
|
test2();
|
|
|
|
test3();
|
|
|
|
test4();
|
2020-11-11 01:19:49 +03:00
|
|
|
|
2021-04-07 00:28:50 +03:00
|
|
|
return 0;
|
2020-11-11 01:19:49 +03:00
|
|
|
}
|