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 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 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