1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) Wipro Technologies Ltd, 2003.  All Rights Reserved.
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci * Author:	Aniruddha Marathe <aniruddha.marathe@wipro.com>
6f08c3bdfSopenharmony_ci *
7f08c3bdfSopenharmony_ci * Ported to new library:
8f08c3bdfSopenharmony_ci * 07/2019	Christian Amann <camann@suse.com>
9f08c3bdfSopenharmony_ci */
10f08c3bdfSopenharmony_ci/*
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * Basic test for timer_create(2):
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci *	Creates a timer for each available clock using the
15f08c3bdfSopenharmony_ci *	following notification types:
16f08c3bdfSopenharmony_ci *	1) SIGEV_NONE
17f08c3bdfSopenharmony_ci *	2) SIGEV_SIGNAL
18f08c3bdfSopenharmony_ci *	3) SIGEV_THREAD
19f08c3bdfSopenharmony_ci *	4) SIGEV_THREAD_ID
20f08c3bdfSopenharmony_ci *	5) NULL
21f08c3bdfSopenharmony_ci *
22f08c3bdfSopenharmony_ci * This is also regression test for commit:
23f08c3bdfSopenharmony_ci * f18ddc13af98 ("alarmtimer: Use EOPNOTSUPP instead of ENOTSUPP")
24f08c3bdfSopenharmony_ci */
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci#include <signal.h>
27f08c3bdfSopenharmony_ci#include <time.h>
28f08c3bdfSopenharmony_ci#include "tst_test.h"
29f08c3bdfSopenharmony_ci#include "tst_safe_macros.h"
30f08c3bdfSopenharmony_ci#include "lapi/common_timers.h"
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_cistatic struct notif_type {
33f08c3bdfSopenharmony_ci	int		sigev_signo;
34f08c3bdfSopenharmony_ci	int		sigev_notify;
35f08c3bdfSopenharmony_ci	char		*message;
36f08c3bdfSopenharmony_ci} types[] = {
37f08c3bdfSopenharmony_ci	{SIGALRM, SIGEV_NONE, "SIGEV_NONE"},
38f08c3bdfSopenharmony_ci	{SIGALRM, SIGEV_SIGNAL, "SIGEV_SIGNAL"},
39f08c3bdfSopenharmony_ci	{SIGALRM, SIGEV_THREAD, "SIGEV_THREAD"},
40f08c3bdfSopenharmony_ci	{SIGALRM, SIGEV_THREAD_ID, "SIGEV_THREAD_ID"},
41f08c3bdfSopenharmony_ci	{0, 0, "NULL"},
42f08c3bdfSopenharmony_ci};
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_cistatic void run(unsigned int n)
45f08c3bdfSopenharmony_ci{
46f08c3bdfSopenharmony_ci	unsigned int i;
47f08c3bdfSopenharmony_ci	struct sigevent evp;
48f08c3bdfSopenharmony_ci	struct notif_type *nt = &types[n];
49f08c3bdfSopenharmony_ci	kernel_timer_t created_timer_id;
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ci	tst_res(TINFO, "Testing notification type: %s", nt->message);
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	memset(&evp, 0, sizeof(evp));
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci	for (i = 0; i < CLOCKS_DEFINED; ++i) {
56f08c3bdfSopenharmony_ci		clock_t clock = clock_list[i];
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci		evp.sigev_value  = (union sigval) 0;
59f08c3bdfSopenharmony_ci		evp.sigev_signo  = nt->sigev_signo;
60f08c3bdfSopenharmony_ci		evp.sigev_notify = nt->sigev_notify;
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci		if (clock == CLOCK_MONOTONIC_RAW)
63f08c3bdfSopenharmony_ci			continue;
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci		if (nt->sigev_notify == SIGEV_THREAD_ID)
66f08c3bdfSopenharmony_ci			evp._sigev_un._tid = getpid();
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci		TEST(tst_syscall(__NR_timer_create, clock,
69f08c3bdfSopenharmony_ci				nt->sigev_notify ? &evp : NULL,
70f08c3bdfSopenharmony_ci				&created_timer_id));
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci		if (TST_RET != 0) {
73f08c3bdfSopenharmony_ci			if (possibly_unsupported(clock) &&
74f08c3bdfSopenharmony_ci			    (TST_ERR == EINVAL || TST_ERR == ENOTSUP)) {
75f08c3bdfSopenharmony_ci				tst_res(TCONF | TTERRNO, "%s unsupported",
76f08c3bdfSopenharmony_ci					get_clock_str(clock));
77f08c3bdfSopenharmony_ci			} else {
78f08c3bdfSopenharmony_ci				tst_res(TFAIL | TTERRNO,
79f08c3bdfSopenharmony_ci					"Failed to create timer for %s",
80f08c3bdfSopenharmony_ci					get_clock_str(clock));
81f08c3bdfSopenharmony_ci			}
82f08c3bdfSopenharmony_ci			continue;
83f08c3bdfSopenharmony_ci		}
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ci		tst_res(TPASS, "Timer successfully created for %s",
86f08c3bdfSopenharmony_ci					get_clock_str(clock));
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ci		TEST(tst_syscall(__NR_timer_delete, created_timer_id));
89f08c3bdfSopenharmony_ci		if (TST_RET != 0) {
90f08c3bdfSopenharmony_ci			tst_res(TFAIL | TTERRNO, "Failed to delete timer %s",
91f08c3bdfSopenharmony_ci				get_clock_str(clock));
92f08c3bdfSopenharmony_ci		}
93f08c3bdfSopenharmony_ci	}
94f08c3bdfSopenharmony_ci}
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_cistatic struct tst_test test = {
97f08c3bdfSopenharmony_ci	.test = run,
98f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(types),
99f08c3bdfSopenharmony_ci	.needs_root = 1,
100f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
101f08c3bdfSopenharmony_ci		{"linux-git", "f18ddc13af98"},
102f08c3bdfSopenharmony_ci		{}
103f08c3bdfSopenharmony_ci	}
104f08c3bdfSopenharmony_ci};
105