165b390aaSDag-Erling Smørgrav /* 265b390aaSDag-Erling Smørgrav * util/shm_side/shm_main.c - SHM for statistics transport 365b390aaSDag-Erling Smørgrav * 465b390aaSDag-Erling Smørgrav * Copyright (c) 2017, NLnet Labs. All rights reserved. 565b390aaSDag-Erling Smørgrav * 665b390aaSDag-Erling Smørgrav * This software is open source. 765b390aaSDag-Erling Smørgrav * 865b390aaSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 965b390aaSDag-Erling Smørgrav * modification, are permitted provided that the following conditions 1065b390aaSDag-Erling Smørgrav * are met: 1165b390aaSDag-Erling Smørgrav * 1265b390aaSDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 1365b390aaSDag-Erling Smørgrav * this list of conditions and the following disclaimer. 1465b390aaSDag-Erling Smørgrav * 1565b390aaSDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 1665b390aaSDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 1765b390aaSDag-Erling Smørgrav * and/or other materials provided with the distribution. 1865b390aaSDag-Erling Smørgrav * 1965b390aaSDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 2065b390aaSDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 2165b390aaSDag-Erling Smørgrav * specific prior written permission. 2265b390aaSDag-Erling Smørgrav * 2365b390aaSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2465b390aaSDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2565b390aaSDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2665b390aaSDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2765b390aaSDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2865b390aaSDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2965b390aaSDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3065b390aaSDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3165b390aaSDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3265b390aaSDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3365b390aaSDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3465b390aaSDag-Erling Smørgrav */ 3565b390aaSDag-Erling Smørgrav 3665b390aaSDag-Erling Smørgrav /** 3765b390aaSDag-Erling Smørgrav * \file 3865b390aaSDag-Erling Smørgrav * 3965b390aaSDag-Erling Smørgrav * This file contains functions for the SHM implementation. 4065b390aaSDag-Erling Smørgrav */ 4165b390aaSDag-Erling Smørgrav 4265b390aaSDag-Erling Smørgrav #include "config.h" 4365b390aaSDag-Erling Smørgrav #include <ctype.h> 4465b390aaSDag-Erling Smørgrav #include <stdarg.h> 4565b390aaSDag-Erling Smørgrav #ifdef HAVE_SYS_IPC_H 4665b390aaSDag-Erling Smørgrav #include <sys/ipc.h> 4765b390aaSDag-Erling Smørgrav #endif 4865b390aaSDag-Erling Smørgrav #ifdef HAVE_SYS_SHM_H 4965b390aaSDag-Erling Smørgrav #include <sys/shm.h> 5065b390aaSDag-Erling Smørgrav #endif 5165b390aaSDag-Erling Smørgrav #include <sys/time.h> 5265b390aaSDag-Erling Smørgrav #include <errno.h> 5365b390aaSDag-Erling Smørgrav #include "shm_main.h" 5465b390aaSDag-Erling Smørgrav #include "daemon/daemon.h" 5565b390aaSDag-Erling Smørgrav #include "daemon/worker.h" 5665b390aaSDag-Erling Smørgrav #include "daemon/stats.h" 5765b390aaSDag-Erling Smørgrav #include "services/mesh.h" 5865b390aaSDag-Erling Smørgrav #include "services/cache/rrset.h" 5965b390aaSDag-Erling Smørgrav #include "services/cache/infra.h" 6065b390aaSDag-Erling Smørgrav #include "validator/validator.h" 6165b390aaSDag-Erling Smørgrav #include "util/config_file.h" 6265b390aaSDag-Erling Smørgrav #include "util/fptr_wlist.h" 6365b390aaSDag-Erling Smørgrav #include "util/log.h" 6465b390aaSDag-Erling Smørgrav 6565b390aaSDag-Erling Smørgrav #ifdef HAVE_SHMGET 6665b390aaSDag-Erling Smørgrav /** subtract timers and the values do not overflow or become negative */ 6765b390aaSDag-Erling Smørgrav static void 68c7f4d7adSDag-Erling Smørgrav stat_timeval_subtract(long long *d_sec, long long *d_usec, const struct timeval* end, 6965b390aaSDag-Erling Smørgrav const struct timeval* start) 7065b390aaSDag-Erling Smørgrav { 7165b390aaSDag-Erling Smørgrav #ifndef S_SPLINT_S 7265b390aaSDag-Erling Smørgrav time_t end_usec = end->tv_usec; 73c7f4d7adSDag-Erling Smørgrav *d_sec = end->tv_sec - start->tv_sec; 7465b390aaSDag-Erling Smørgrav if(end_usec < start->tv_usec) { 7565b390aaSDag-Erling Smørgrav end_usec += 1000000; 76c7f4d7adSDag-Erling Smørgrav (*d_sec)--; 7765b390aaSDag-Erling Smørgrav } 78c7f4d7adSDag-Erling Smørgrav *d_usec = end_usec - start->tv_usec; 7965b390aaSDag-Erling Smørgrav #endif 8065b390aaSDag-Erling Smørgrav } 8165b390aaSDag-Erling Smørgrav #endif /* HAVE_SHMGET */ 8265b390aaSDag-Erling Smørgrav 8365b390aaSDag-Erling Smørgrav int shm_main_init(struct daemon* daemon) 8465b390aaSDag-Erling Smørgrav { 8565b390aaSDag-Erling Smørgrav #ifdef HAVE_SHMGET 86c7f4d7adSDag-Erling Smørgrav struct ub_shm_stat_info *shm_stat; 8765b390aaSDag-Erling Smørgrav size_t shm_size; 8865b390aaSDag-Erling Smørgrav 8965b390aaSDag-Erling Smørgrav /* sanitize */ 9065b390aaSDag-Erling Smørgrav if(!daemon) 9165b390aaSDag-Erling Smørgrav return 0; 9265b390aaSDag-Erling Smørgrav if(!daemon->cfg->shm_enable) 9365b390aaSDag-Erling Smørgrav return 1; 9465b390aaSDag-Erling Smørgrav if(daemon->cfg->stat_interval == 0) 9565b390aaSDag-Erling Smørgrav log_warn("shm-enable is yes but statistics-interval is 0"); 9665b390aaSDag-Erling Smørgrav 9765b390aaSDag-Erling Smørgrav /* Statistics to maintain the number of thread + total */ 98c7f4d7adSDag-Erling Smørgrav shm_size = (sizeof(struct ub_stats_info) * (daemon->num + 1)); 9965b390aaSDag-Erling Smørgrav 10065b390aaSDag-Erling Smørgrav /* Allocation of needed memory */ 10165b390aaSDag-Erling Smørgrav daemon->shm_info = (struct shm_main_info*)calloc(1, shm_size); 10265b390aaSDag-Erling Smørgrav 10365b390aaSDag-Erling Smørgrav /* Sanitize */ 10465b390aaSDag-Erling Smørgrav if(!daemon->shm_info) { 10565b390aaSDag-Erling Smørgrav log_err("shm fail: malloc failure"); 10665b390aaSDag-Erling Smørgrav return 0; 10765b390aaSDag-Erling Smørgrav } 10865b390aaSDag-Erling Smørgrav 10965b390aaSDag-Erling Smørgrav daemon->shm_info->key = daemon->cfg->shm_key; 11065b390aaSDag-Erling Smørgrav 11165b390aaSDag-Erling Smørgrav /* Check for previous create SHM */ 11265b390aaSDag-Erling Smørgrav daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(int), SHM_R); 11365b390aaSDag-Erling Smørgrav daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, sizeof(int), SHM_R); 11465b390aaSDag-Erling Smørgrav 11565b390aaSDag-Erling Smørgrav /* Destroy previous SHM */ 11665b390aaSDag-Erling Smørgrav if (daemon->shm_info->id_ctl >= 0) 11765b390aaSDag-Erling Smørgrav shmctl(daemon->shm_info->id_ctl, IPC_RMID, NULL); 11865b390aaSDag-Erling Smørgrav 11965b390aaSDag-Erling Smørgrav /* Destroy previous SHM */ 12065b390aaSDag-Erling Smørgrav if (daemon->shm_info->id_arr >= 0) 12165b390aaSDag-Erling Smørgrav shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL); 12265b390aaSDag-Erling Smørgrav 12365b390aaSDag-Erling Smørgrav /* SHM: Create the segment */ 1240eefd307SCy Schubert daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0644); 12565b390aaSDag-Erling Smørgrav 12665b390aaSDag-Erling Smørgrav if (daemon->shm_info->id_ctl < 0) 12765b390aaSDag-Erling Smørgrav { 12865b390aaSDag-Erling Smørgrav log_err("SHM failed(id_ctl) cannot shmget(key %d) %s", 12965b390aaSDag-Erling Smørgrav daemon->shm_info->key, strerror(errno)); 13065b390aaSDag-Erling Smørgrav 13165b390aaSDag-Erling Smørgrav /* Just release memory unused */ 13265b390aaSDag-Erling Smørgrav free(daemon->shm_info); 13365b390aaSDag-Erling Smørgrav 13465b390aaSDag-Erling Smørgrav return 0; 13565b390aaSDag-Erling Smørgrav } 13665b390aaSDag-Erling Smørgrav 1370eefd307SCy Schubert daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0644); 13865b390aaSDag-Erling Smørgrav 13965b390aaSDag-Erling Smørgrav if (daemon->shm_info->id_arr < 0) 14065b390aaSDag-Erling Smørgrav { 14165b390aaSDag-Erling Smørgrav log_err("SHM failed(id_arr) cannot shmget(key %d + 1) %s", 14265b390aaSDag-Erling Smørgrav daemon->shm_info->key, strerror(errno)); 14365b390aaSDag-Erling Smørgrav 14465b390aaSDag-Erling Smørgrav /* Just release memory unused */ 14565b390aaSDag-Erling Smørgrav free(daemon->shm_info); 14665b390aaSDag-Erling Smørgrav 14765b390aaSDag-Erling Smørgrav return 0; 14865b390aaSDag-Erling Smørgrav } 14965b390aaSDag-Erling Smørgrav 15065b390aaSDag-Erling Smørgrav /* SHM: attach the segment */ 151c7f4d7adSDag-Erling Smørgrav daemon->shm_info->ptr_ctl = (struct ub_shm_stat_info*) 15265b390aaSDag-Erling Smørgrav shmat(daemon->shm_info->id_ctl, NULL, 0); 15365b390aaSDag-Erling Smørgrav if(daemon->shm_info->ptr_ctl == (void *) -1) { 15465b390aaSDag-Erling Smørgrav log_err("SHM failed(ctl) cannot shmat(%d) %s", 15565b390aaSDag-Erling Smørgrav daemon->shm_info->id_ctl, strerror(errno)); 15665b390aaSDag-Erling Smørgrav 15765b390aaSDag-Erling Smørgrav /* Just release memory unused */ 15865b390aaSDag-Erling Smørgrav free(daemon->shm_info); 15965b390aaSDag-Erling Smørgrav 16065b390aaSDag-Erling Smørgrav return 0; 16165b390aaSDag-Erling Smørgrav } 16265b390aaSDag-Erling Smørgrav 163c7f4d7adSDag-Erling Smørgrav daemon->shm_info->ptr_arr = (struct ub_stats_info*) 16465b390aaSDag-Erling Smørgrav shmat(daemon->shm_info->id_arr, NULL, 0); 16565b390aaSDag-Erling Smørgrav 16665b390aaSDag-Erling Smørgrav if (daemon->shm_info->ptr_arr == (void *) -1) 16765b390aaSDag-Erling Smørgrav { 16865b390aaSDag-Erling Smørgrav log_err("SHM failed(arr) cannot shmat(%d) %s", 16965b390aaSDag-Erling Smørgrav daemon->shm_info->id_arr, strerror(errno)); 17065b390aaSDag-Erling Smørgrav 17165b390aaSDag-Erling Smørgrav /* Just release memory unused */ 17265b390aaSDag-Erling Smørgrav free(daemon->shm_info); 17365b390aaSDag-Erling Smørgrav 17465b390aaSDag-Erling Smørgrav return 0; 17565b390aaSDag-Erling Smørgrav } 17665b390aaSDag-Erling Smørgrav 17765b390aaSDag-Erling Smørgrav /* Zero fill SHM to stand clean while is not filled by other events */ 178c7f4d7adSDag-Erling Smørgrav memset(daemon->shm_info->ptr_ctl, 0, sizeof(struct ub_shm_stat_info)); 17965b390aaSDag-Erling Smørgrav memset(daemon->shm_info->ptr_arr, 0, shm_size); 18065b390aaSDag-Erling Smørgrav 18165b390aaSDag-Erling Smørgrav shm_stat = daemon->shm_info->ptr_ctl; 18265b390aaSDag-Erling Smørgrav shm_stat->num_threads = daemon->num; 18365b390aaSDag-Erling Smørgrav 18465b390aaSDag-Erling Smørgrav #else 18565b390aaSDag-Erling Smørgrav (void)daemon; 18665b390aaSDag-Erling Smørgrav #endif /* HAVE_SHMGET */ 18765b390aaSDag-Erling Smørgrav return 1; 18865b390aaSDag-Erling Smørgrav } 18965b390aaSDag-Erling Smørgrav 19065b390aaSDag-Erling Smørgrav void shm_main_shutdown(struct daemon* daemon) 19165b390aaSDag-Erling Smørgrav { 19265b390aaSDag-Erling Smørgrav #ifdef HAVE_SHMGET 19365b390aaSDag-Erling Smørgrav /* web are OK, just disabled */ 19465b390aaSDag-Erling Smørgrav if(!daemon->cfg->shm_enable) 19565b390aaSDag-Erling Smørgrav return; 19665b390aaSDag-Erling Smørgrav 19765b390aaSDag-Erling Smørgrav verbose(VERB_DETAIL, "SHM shutdown - KEY [%d] - ID CTL [%d] ARR [%d] - PTR CTL [%p] ARR [%p]", 19865b390aaSDag-Erling Smørgrav daemon->shm_info->key, daemon->shm_info->id_ctl, daemon->shm_info->id_arr, daemon->shm_info->ptr_ctl, daemon->shm_info->ptr_arr); 19965b390aaSDag-Erling Smørgrav 20065b390aaSDag-Erling Smørgrav /* Destroy previous SHM */ 20165b390aaSDag-Erling Smørgrav if (daemon->shm_info->id_ctl >= 0) 20265b390aaSDag-Erling Smørgrav shmctl(daemon->shm_info->id_ctl, IPC_RMID, NULL); 20365b390aaSDag-Erling Smørgrav 20465b390aaSDag-Erling Smørgrav if (daemon->shm_info->id_arr >= 0) 20565b390aaSDag-Erling Smørgrav shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL); 20665b390aaSDag-Erling Smørgrav 20765b390aaSDag-Erling Smørgrav if (daemon->shm_info->ptr_ctl) 20865b390aaSDag-Erling Smørgrav shmdt(daemon->shm_info->ptr_ctl); 20965b390aaSDag-Erling Smørgrav 21065b390aaSDag-Erling Smørgrav if (daemon->shm_info->ptr_arr) 21165b390aaSDag-Erling Smørgrav shmdt(daemon->shm_info->ptr_arr); 21265b390aaSDag-Erling Smørgrav 21365b390aaSDag-Erling Smørgrav #else 21465b390aaSDag-Erling Smørgrav (void)daemon; 21565b390aaSDag-Erling Smørgrav #endif /* HAVE_SHMGET */ 21665b390aaSDag-Erling Smørgrav } 21765b390aaSDag-Erling Smørgrav 21865b390aaSDag-Erling Smørgrav void shm_main_run(struct worker *worker) 21965b390aaSDag-Erling Smørgrav { 22065b390aaSDag-Erling Smørgrav #ifdef HAVE_SHMGET 221c7f4d7adSDag-Erling Smørgrav struct ub_shm_stat_info *shm_stat; 222c7f4d7adSDag-Erling Smørgrav struct ub_stats_info *stat_total; 223c7f4d7adSDag-Erling Smørgrav struct ub_stats_info *stat_info; 22465b390aaSDag-Erling Smørgrav int offset; 22565b390aaSDag-Erling Smørgrav 2260eefd307SCy Schubert #ifndef S_SPLINT_S 22765b390aaSDag-Erling Smørgrav verbose(VERB_DETAIL, "SHM run - worker [%d] - daemon [%p] - timenow(%u) - timeboot(%u)", 22865b390aaSDag-Erling Smørgrav worker->thread_num, worker->daemon, (unsigned)worker->env.now_tv->tv_sec, (unsigned)worker->daemon->time_boot.tv_sec); 2290eefd307SCy Schubert #endif 23065b390aaSDag-Erling Smørgrav 23165b390aaSDag-Erling Smørgrav offset = worker->thread_num + 1; 23265b390aaSDag-Erling Smørgrav stat_total = worker->daemon->shm_info->ptr_arr; 23365b390aaSDag-Erling Smørgrav stat_info = worker->daemon->shm_info->ptr_arr + offset; 23465b390aaSDag-Erling Smørgrav 23565b390aaSDag-Erling Smørgrav /* Copy data to the current position */ 23665b390aaSDag-Erling Smørgrav server_stats_compile(worker, stat_info, 0); 23765b390aaSDag-Erling Smørgrav 23865b390aaSDag-Erling Smørgrav /* First thread, zero fill total, and copy general info */ 23965b390aaSDag-Erling Smørgrav if (worker->thread_num == 0) { 24065b390aaSDag-Erling Smørgrav 24165b390aaSDag-Erling Smørgrav /* Copy data to the current position */ 242c7f4d7adSDag-Erling Smørgrav memset(stat_total, 0, sizeof(struct ub_stats_info)); 24365b390aaSDag-Erling Smørgrav 24465b390aaSDag-Erling Smørgrav /* Point to data into SHM */ 2450eefd307SCy Schubert #ifndef S_SPLINT_S 24665b390aaSDag-Erling Smørgrav shm_stat = worker->daemon->shm_info->ptr_ctl; 247c7f4d7adSDag-Erling Smørgrav shm_stat->time.now_sec = (long long)worker->env.now_tv->tv_sec; 248c7f4d7adSDag-Erling Smørgrav shm_stat->time.now_usec = (long long)worker->env.now_tv->tv_usec; 2490eefd307SCy Schubert #endif 25065b390aaSDag-Erling Smørgrav 251c7f4d7adSDag-Erling Smørgrav stat_timeval_subtract(&shm_stat->time.up_sec, &shm_stat->time.up_usec, worker->env.now_tv, &worker->daemon->time_boot); 252c7f4d7adSDag-Erling Smørgrav stat_timeval_subtract(&shm_stat->time.elapsed_sec, &shm_stat->time.elapsed_usec, worker->env.now_tv, &worker->daemon->time_last_stat); 25365b390aaSDag-Erling Smørgrav 254c7f4d7adSDag-Erling Smørgrav shm_stat->mem.msg = (long long)slabhash_get_mem(worker->env.msg_cache); 255c7f4d7adSDag-Erling Smørgrav shm_stat->mem.rrset = (long long)slabhash_get_mem(&worker->env.rrset_cache->table); 256971980c3SDag-Erling Smørgrav shm_stat->mem.dnscrypt_shared_secret = 0; 257971980c3SDag-Erling Smørgrav #ifdef USE_DNSCRYPT 258971980c3SDag-Erling Smørgrav if(worker->daemon->dnscenv) { 259971980c3SDag-Erling Smørgrav shm_stat->mem.dnscrypt_shared_secret = (long long)slabhash_get_mem( 260971980c3SDag-Erling Smørgrav worker->daemon->dnscenv->shared_secrets_cache); 2618a384985SDag-Erling Smørgrav shm_stat->mem.dnscrypt_nonce = (long long)slabhash_get_mem( 2628a384985SDag-Erling Smørgrav worker->daemon->dnscenv->nonces_cache); 263971980c3SDag-Erling Smørgrav } 264971980c3SDag-Erling Smørgrav #endif 265c7f4d7adSDag-Erling Smørgrav shm_stat->mem.val = (long long)mod_get_mem(&worker->env, 266c7f4d7adSDag-Erling Smørgrav "validator"); 267c7f4d7adSDag-Erling Smørgrav shm_stat->mem.iter = (long long)mod_get_mem(&worker->env, 268c7f4d7adSDag-Erling Smørgrav "iterator"); 269c7f4d7adSDag-Erling Smørgrav shm_stat->mem.respip = (long long)mod_get_mem(&worker->env, 270c7f4d7adSDag-Erling Smørgrav "respip"); 27165b390aaSDag-Erling Smørgrav 27265b390aaSDag-Erling Smørgrav /* subnet mem value is available in shm, also when not enabled, 27365b390aaSDag-Erling Smørgrav * to make the struct easier to memmap by other applications, 27465b390aaSDag-Erling Smørgrav * independent of the configuration of unbound */ 27565b390aaSDag-Erling Smørgrav shm_stat->mem.subnet = 0; 27665b390aaSDag-Erling Smørgrav #ifdef CLIENT_SUBNET 277c7f4d7adSDag-Erling Smørgrav shm_stat->mem.subnet = (long long)mod_get_mem(&worker->env, 278c7f4d7adSDag-Erling Smørgrav "subnet"); 279c7f4d7adSDag-Erling Smørgrav #endif 280c7f4d7adSDag-Erling Smørgrav /* ipsecmod mem value is available in shm, also when not enabled, 281c7f4d7adSDag-Erling Smørgrav * to make the struct easier to memmap by other applications, 282c7f4d7adSDag-Erling Smørgrav * independent of the configuration of unbound */ 283c7f4d7adSDag-Erling Smørgrav shm_stat->mem.ipsecmod = 0; 284c7f4d7adSDag-Erling Smørgrav #ifdef USE_IPSECMOD 285c7f4d7adSDag-Erling Smørgrav shm_stat->mem.ipsecmod = (long long)mod_get_mem(&worker->env, 286c7f4d7adSDag-Erling Smørgrav "ipsecmod"); 28765b390aaSDag-Erling Smørgrav #endif 288*25039b37SCy Schubert #ifdef WITH_DYNLIBMODULE 289*25039b37SCy Schubert shm_stat->mem.dynlib = (long long)mod_get_mem(&worker->env, 290*25039b37SCy Schubert "dynlib"); 291*25039b37SCy Schubert #endif 29265b390aaSDag-Erling Smørgrav } 29365b390aaSDag-Erling Smørgrav 29465b390aaSDag-Erling Smørgrav server_stats_add(stat_total, stat_info); 29565b390aaSDag-Erling Smørgrav 29665b390aaSDag-Erling Smørgrav /* print the thread statistics */ 29765b390aaSDag-Erling Smørgrav stat_total->mesh_time_median /= (double)worker->daemon->num; 29865b390aaSDag-Erling Smørgrav 29965b390aaSDag-Erling Smørgrav #else 30065b390aaSDag-Erling Smørgrav (void)worker; 30165b390aaSDag-Erling Smørgrav #endif /* HAVE_SHMGET */ 30265b390aaSDag-Erling Smørgrav } 303