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