1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2016 Joyent, Inc.
14  */
15 
16 #include <assert.h>
17 #include <err.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <signal.h>
22 #include <time.h>
23 #include <limits.h>
24 #include <sys/sysconfig.h>
25 #include <sys/sysmacros.h>
26 
27 /* Need direct access to _sysconfig to query NCPU */
28 extern long _sysconfig(int);
29 
30 
31 static int
mktimer(timer_t * timer)32 mktimer(timer_t *timer)
33 {
34 	struct sigevent sev;
35 	sev.sigev_notify = SIGEV_SIGNAL;
36 	sev.sigev_signo = SIGRTMIN;
37 	sev.sigev_value.sival_ptr = timer;
38 
39 	return (timer_create(CLOCK_MONOTONIC, &sev, timer));
40 }
41 
42 int
main(void)43 main(void)
44 {
45 	long ncpu;
46 	size_t limit;
47 	timer_t *timers, timer_overage;
48 
49 	/* Query NCPU with private sysconfig param */
50 	ncpu = _sysconfig(_CONFIG_NPROC_NCPU);
51 	assert(ncpu > 0 && ncpu < INT32_MAX);
52 
53 	/* Current specified limit is 4 * NCPU */
54 	limit = 4 * ncpu;
55 	timers = calloc(limit + 1, sizeof (timer_t));
56 	if (timers == NULL)
57 		err(EXIT_FAILURE, "failed to allocate %zu timers", limit + 1);
58 
59 	/* Slowly walk up to the limit doing creations/deletions */
60 	for (int i = 1; i <= limit; i = MIN(limit, i*2)) {
61 		for (int j = 0; j < i; j++) {
62 			assert(mktimer(&timers[j]) == 0);
63 		}
64 
65 		/*
66 		 * Attempt to allocate one additional timer if we've reached
67 		 * the assumed limit.
68 		 */
69 		if (i == limit) {
70 			assert(mktimer(&timer_overage) == -1);
71 		}
72 
73 		for (int j = 0; j < i; j++) {
74 			assert(timer_delete(timers[j]) == 0);
75 		}
76 
77 		/* Bail out if we've finished at the limit */
78 		if (i == limit)
79 			break;
80 	}
81 
82 
83 	return (0);
84 }
85