mailing list of musl libc
 help / color / mirror / code / Atom feed
071000a8c00cd8d0af60e8465b5407187f6834d2 blob 3911 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
 
/*
 * clock_nanosleep unit test
 */

#include "test.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <time.h>

#define MAX_NSEC 1000000000
#define SLEEP_NANO 500000
#define TEST(c, ...) ((c) || (t_error(#c " failed: " __VA_ARGS__), 0))

static void dummy_signal_handler(int signum) {}

static void test_time_elapsed(void)
{
	// get start time
	struct timespec time1;
	if (clock_gettime(CLOCK_MONOTONIC, &time1) == -1) {
		t_error("clock_gettime() failed. Errno: %s\n", strerror(errno));
		return;
	}

	struct timespec ts = {0, SLEEP_NANO};
	TEST(clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts) == 0,
	     "clock_nanosleep failed with clock id %d\n", CLOCK_MONOTONIC);

	// get finish time
	struct timespec time2;
	if (clock_gettime(CLOCK_MONOTONIC, &time2) == -1) {
		t_error("clock_gettime() failed. Errno: %s\n", strerror(errno));
		return;
	}

	// calculate elapsed time
	time_t elapsed = time2.tv_sec > time1.tv_sec
	                     ? time2.tv_nsec + (MAX_NSEC - time1.tv_nsec)
	                     : time2.tv_nsec - time1.tv_nsec;

	TEST(elapsed >= SLEEP_NANO,
	     "Elapsed time test failed: expected >= %d "
	     "nanoseconds, got %ld nanoseconds.\n",
	     SLEEP_NANO, elapsed);
}

static void test_invalid_inputs(void)
{
	struct timespec ts = {1, 0};

	// check EINVAL is returned when tv_nsec is too big
	ts.tv_nsec = MAX_NSEC;
	int retval = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
	TEST(retval == EINVAL,
	     "Oversized tv_nsec test failed: Expected %s, got %s\n",
	     strerror(EINVAL), strerror(retval));

	// check EINVAL is returned when tv_nsec is too small
	ts.tv_nsec = -1;
	retval = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
	TEST(retval == EINVAL,
	     "Undersized tv_nsec test failed: Expected %s, got %s\n",
	     strerror(EINVAL), strerror(retval));

	// check EINVAL is returned when given CPU_time clock of calling thread
	retval = clock_nanosleep(CLOCK_THREAD_CPUTIME_ID, 0, &ts, NULL);
	TEST(retval == EINVAL,
	     "Calling threads cpu clock id test failed: Expected %s, got %s\n",
	     strerror(EINVAL), strerror(retval));

	const int unknown_clock = 123;

	// check EINVAL is returned when given unknown clock
	retval = clock_nanosleep(unknown_clock, 0, &ts, NULL);
	TEST(retval == EINVAL,
	     "Unknown clock id test failed: Expected %s, got %s\n",
	     strerror(EINVAL), strerror(retval));

	// check ENOTSUP is returned when given an unsupported clock
	retval = clock_nanosleep(CLOCK_MONOTONIC_COARSE, 0, &ts, NULL);
	TEST(retval == ENOTSUP,
	     "Unsupported clock test failed. Expected %s, got %s\n",
	     strerror(ENOTSUP), strerror(retval));
}

static void test_interupted_sleep()
{
	// check EINTR is returned when sleep is interupted by a signal handler
	struct sigaction sa;
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = dummy_signal_handler;
	sigaction(SIGALRM, &sa, NULL);

	timer_t timerid = NULL;
	if (timer_create(CLOCK_MONOTONIC, NULL, &timerid) == -1) {
		t_error("timer_create() failed. Errno: %s\n", strerror(errno));
		return;
	}

	struct itimerspec its = {
	    .it_value.tv_sec = 0,
	    .it_value.tv_nsec = SLEEP_NANO,
	};
	if (timer_settime(timerid, 0, &its, NULL) == -1) {
		t_error("timer_settime() failed. Errno: %s\n", strerror(errno));
		timer_delete(timerid);
		return;
	}

	struct timespec ts = {2, 0};
	struct timespec rmtp = {0, 0};
	int retval = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &rmtp);

	TEST(retval == EINTR, "Interupted sleep test failed: Expected %s, got %s\n",
	     strerror(EINTR), strerror(retval));

	// check that the remaining unslept time is returned into rmtp
	TEST(rmtp.tv_sec > 0 || rmtp.tv_nsec > 0,
	     "rmtp test failed: Expected value > 0, got rmpt.tv_sec = %lu, "
	     "rmtp.tv_nsec = %lu\n",
	     rmtp.tv_sec, rmtp.tv_nsec);

	timer_delete(timerid);
}

int main(void)
{
	test_time_elapsed();
	test_invalid_inputs();
	test_interupted_sleep();
	return t_status;
}
debug log:

solving 071000a ...
found 071000a in https://inbox.vuxu.org/musl/20241105224437.67-1-ryan.p.gardner@boeing.com/

applying [1/1] https://inbox.vuxu.org/musl/20241105224437.67-1-ryan.p.gardner@boeing.com/
diff --git a/src/functional/clock_nanosleep.c b/src/functional/clock_nanosleep.c
new file mode 100644
index 0000000..071000a

Checking patch src/functional/clock_nanosleep.c...
Applied patch src/functional/clock_nanosleep.c cleanly.

index at:
100644 071000a8c00cd8d0af60e8465b5407187f6834d2	src/functional/clock_nanosleep.c

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).