/* * Open connection to xenstore. * * @pollfds defines of signal-handling descriptors to be watched * if has to wait. * * Will not touch pollfds[NPFD_XS]. */ static void open_xs_connection(struct pollfd *pollfds) { struct timespec ts0; int64_t wsec; bool displayed_msg = false; int k; /* * If we are running as a daemon during system startup, there * can be a race condition with continuing Xen initialization * (/proc/xen including /proc/xen/privcmd may be unavailable yet, * still to be created even though Xen service startup completion * has already been signalled), so wait for a while if necessary. */ for (ts0 = getnow();;) { if (!xs) xs = xs_open(0); if (xs) break; /* time since the start */ wsec = timespec_diff_ms(getnow(), ts0) / MSEC_PER_SEC; if (run_as_daemon && wsec < max_xen_init_retries) { if (wsec >= xen_init_retry_msg && !displayed_msg) { notice_msg("waiting for Xen to initialize"); displayed_msg = true; } if (pollfds != NULL) { int npollfds = NPFD_COUNT - 1; for (k = 0; k < npollfds; k++) pollfds[k].revents = 0; if (poll(pollfds, npollfds, 1 * MSEC_PER_SEC) < 0) fatal_perror("poll"); handle_signals(pollfds, NULL); } else { sleep(1); } } else { fatal_perror("unable to open connection to xenstore"); } } }
int main(int argc, char **argv) { unsigned int exp_universe, big, exp_n, n, n_1, i, j, m, repeats, alpha; struct priority_queue *pq, *pq1, *pq2; unsigned int *elems; unsigned int idx; struct timespec before, after; if (argc < 6) { printf("Usage : run_once exp_universe exp_n percentage filename repetitions big\n"); printf("Example : run_once 11 5 16 test_file 2 1 will run a test with:\n \t2^16 integers in the range [0,...2^11 - 1]\n\tOne of the structures will hold approximately 16 percent of the elements; the remaining amount will be in the other.\n\tThe test will be repeated (without any change in the input integers) 2 times.\n\tThe test is big so times will be measured in ms.\n"); exit(1); } big = atoi(argv[6]); exp_universe = atoi(argv[1]); exp_n = atoi(argv[2]); alpha = atoi(argv[3]); repeats = atoi(argv[5]); n = 1 << exp_n; n_1 = (alpha * n) / 100; elems = gen_instance(argv[4], n, exp_universe); for (m = 0; m < repeats; m++) { pq1 = pq_new(n_1, exp_universe); pq2 = pq_new(n - n_1, exp_universe); for (i = 0; i < n_1; i++) { pq_insert(pq1, elems[i]); } for (; i < n; i++) { pq_insert(pq2, elems[i]); } clock_gettime(CLOCK_MONOTONIC, &before); pq = pq_merge(pq1, pq2); clock_gettime(CLOCK_MONOTONIC, &after); if (big) { printf("merge: %lldms\n", timespec_diff_ms(after, before)); } else { printf("merge: %lldns\n", timespec_diff_ns(after, before)); } pq_free(pq); } free(elems); }
static void dahdi_dummy_timer(unsigned long param) { unsigned long ms_since_start; struct timespec now; const unsigned long MAX_INTERVAL = 100000L; const unsigned long MS_LIMIT = 3000; if (!atomic_read(&shutdown)) mod_timer(&timer, jiffies + JIFFIES_INTERVAL); now = current_kernel_time(); ms_since_start = timespec_diff_ms(&ztd->start_interval, &now); /* * If the system time has changed, it is possible for us to be far * behind. If we are more than MS_LIMIT milliseconds behind, just * reset our time base and continue so that we do not hang the system * here. * */ if (unlikely((ms_since_start - ztd->calls_since_start) > MS_LIMIT)) { if (printk_ratelimit()) { printk(KERN_INFO "dahdi_dummy: Detected time shift.\n"); } ztd->calls_since_start = 0; ztd->start_interval = now; return; } while (ms_since_start > ztd->calls_since_start) { ztd->calls_since_start++; dahdi_receive(&ztd->span); dahdi_transmit(&ztd->span); } if (ms_since_start > MAX_INTERVAL) { ztd->calls_since_start = 0; ztd->start_interval = now; } }
static void dahdi_dummy_timer(unsigned long param) { unsigned long ms_since_start; struct timespec now; const unsigned long MAX_INTERVAL = 100000L; if (!atomic_read(&shutdown)) mod_timer(&timer, jiffies + JIFFIES_INTERVAL); now = current_kernel_time(); ms_since_start = timespec_diff_ms(&ztd->start_interval, &now); while (ms_since_start > ztd->calls_since_start) { ztd->calls_since_start++; dahdi_receive(&ztd->span); dahdi_transmit(&ztd->span); } if (ms_since_start > MAX_INTERVAL) { ztd->calls_since_start = 0; ztd->start_interval = now; } }
int communicator_loop() { client_t *c; int r, len, i; unsigned int size; unsigned long time_current, ms, sql_t = 0, chk_t = 0; struct timespec tms_current, tms_sql; char buf[1024] = {0}; while (1) { clock_gettime(CLOCK_MONOTONIC_RAW, &tms_current); if (timespec_diff_ms(&tms_current, &tms_sql) >= 200) { data_refresh(); if (g_dbc_error) return 0; tms_sql = tms_current; } time_current = time(NULL); srand(time_current); c = g_clients; while (c) { if (g_dbc_error) return 0; //_log("%u %u %u", c->ip, c->sock, c->time_connected); if (c->active) { if (sizeof (c->rbuf) - 1 > c->rn) size = sizeof (c->rbuf) - c->rn - 1; else size = sizeof (c->rbuf) - 1; if ((r = recv(c->sock, c->rbuf + c->rn, size, 0)) > 0) { c->rn += r; c->rbuf[c->rn] = NULL; _log("BUF: %s", c->rbuf); } else if (errno != EAGAIN) { if (opt.debug_log) _log("[Notice] communicator_loop: (errno!=EAGAIN)"); client_operation(c, 1); close(c->sock); c->active = 0; continue; } else if (!c->initialized && time_current - c->time_connected > UNINITIALIZED_CLIENT_TIMEOUT_S) { if (opt.debug_log) _log("[Notice] communicator_loop: Uninitialized client timed out. Disconnecting it."); client_operation(c, 1); close(c->sock); c->active = 0; continue; } if (c->initialized && c->rn >= 2 && c->rbuf[c->rn - 1] == '\n') { c->rbuf[c->rn - 1] = NULL; if (c->rbuf[c->rn - 2] == '\r') c->rbuf[c->rn - 2] = NULL; if (c->rn > 2) client_operation(c, 2); c->rn = 0; } if (!c->initialized && c->rn > 4 && c->rbuf[c->rn - 1] == '\n') { c->rbuf[c->rn - 1] = NULL; if (c->rbuf[c->rn - 2] == '\r') c->rbuf[c->rn - 2] = NULL; client_initialize(c); c->rn = 0; } if (c->initialized && time_current > c->time_checked) { socksend(c->sock, (unsigned char*) "P", 1, 1); c->time_checked = time_current + 30; } if (*c->sbuf != 0) { if (opt.debug_log) _log("[Notice] communicator_loop: Sending sbuf. Data: %s", c->sbuf); i = strlen(c->sbuf); c->sbuf[i] = '\r'; c->sbuf[i + 1] = '\n'; socksend(c->sock, (unsigned char*) c->sbuf, i + 2, 1); *c->sbuf = 0; } if (c->rn > 120) c->rn = 0; } c = c->next; } usleep(1000 * 50); } return 1; }
int main(int argc, char **argv) { sigset_t sigmask; struct pollfd pollfds[NPFD_COUNT]; int npollfds; int k; int64_t wait_ms; struct paging_data pd0; struct paging_data pd1; bool recheck_time; int init_pass = 0; /* * if running interactively, output initially to the terminal, * otherwise to syslog right away */ if (isatty(fileno(stderr))) { log_fp = stderr; log_syslog = false; } else { log_fp = NULL; log_syslog = true; } if (log_syslog) openlog(progname, LOG_CONS | LOG_PID, LOG_DAEMON); /* parse arguments */ handle_cmdline(argc, argv); if (run_as_daemon) daemonize(); debug_msg(1, "debug level set to %d", debug_level); // page_size = sysconf(_SC_PAGESIZE); // if (page_size <= 0) // fatal_msg("unable to get system page size"); /* * Block signals so that they aren't handled according to their * default dispositions */ sigemptyset(&sigmask); sigaddset(&sigmask, SIGHUP); sigaddset(&sigmask, SIGTERM); if (sigprocmask(SIG_BLOCK, &sigmask, NULL) < 0) fatal_perror("sigprocmask"); /* * Receive signals on file descriptors */ sigemptyset(&sigmask); sigaddset(&sigmask, SIGHUP); fd_sighup = signalfd(-1, &sigmask, 0); if (fd_sighup < 0) fatal_perror("signalfd(SIGHUP)"); sigemptyset(&sigmask); sigaddset(&sigmask, SIGTERM); fd_sigterm = signalfd(-1, &sigmask, 0); if (fd_sigterm < 0) fatal_perror("signalfd(SIGTERM)"); /* select clock to use */ select_clk_id(); /* verify we are running under a hypervisor */ verify_hypervisor(); pollfds[NPFD_SIGTERM].fd = fd_sigterm; pollfds[NPFD_SIGTERM].events = POLLIN|POLLPRI; pollfds[NPFD_SIGHUP].fd = fd_sighup; pollfds[NPFD_SIGHUP].events = POLLIN|POLLPRI; /* keep xs poll fd last in the array */ pollfds[NPFD_XS].fd = -1; pollfds[NPFD_XS].events = POLLIN|POLLPRI; /* initialize xenstore structure */ initialize_xs(pollfds); pollfds[NPFD_XS].fd = xs_fileno(xs); get_paging_data(&pd0); for (;;) { try_subscribe_membalance_settings(); /* calculate sleep time till next sample point */ if (initialized_xs) { wait_ms = timespec_diff_ms(pd0.ts, getnow()) + interval * MSEC_PER_SEC; } else { /* if xs not initialzied, keep retrying */ wait_ms = interval * MSEC_PER_SEC; if (++init_pass > 30) wait_ms *= 2; } if (wait_ms >= tolerance_ms) { for (k = 0; k < countof(pollfds); k++) pollfds[k].revents = 0; /* if settings need to be updated, retry in 1 sec or sooner */ if (need_update_membalance_settings) wait_ms = min(wait_ms, MSEC_PER_SEC); /* include xs in the poll only if has initialized xs */ npollfds = countof(pollfds); if (!initialized_xs) npollfds--; if (poll(pollfds, npollfds, wait_ms) < 0) { if (errno == EINTR) continue; fatal_perror("poll"); } recheck_time = false; handle_signals(pollfds, &recheck_time); if (!initialized_xs) { /* try to initialzie xs */ initialize_xs(NULL); /* if successful, start monitoring page map-in rate */ if (initialized_xs) get_paging_data(&pd0); continue; } if (pollfds[NPFD_XS].revents & (POLLIN|POLLPRI)) { /* a watched value in xenstore has been changed */ handle_xs_watch(); recheck_time = true; } if (need_update_membalance_settings) update_membalance_settings(); if (recheck_time) { /* go sleep again if wait interval has not expired yet */ if (timespec_diff_ms(getnow(), pd0.ts) < interval * MSEC_PER_SEC - tolerance_ms) continue; } } if (!initialized_xs) { /* try to initialzie xs */ initialize_xs(NULL); /* if successful, start monitoring page map-in rate */ if (initialized_xs) get_paging_data(&pd0); continue; } /* process sample and set it as the new "previous" one */ get_paging_data(&pd1); process_sample(&pd1, &pd0); pd0 = pd1; } /* close connection to xenstore */ shutdown_xs(); return EXIT_SUCCESS; }
/* * Process next sample of memory statistics data taken after another @interval. * @pd1 = current reading * @pd0 = reading taken @interval ago */ static void process_sample(const struct paging_data *pd1, const struct paging_data *pd0) { int64_t ms; int64_t kbs, kbs_sec; double free_pct; char report[512]; char struct_version = 'A'; int nretries = 0; /* discard sample if weird timing */ ms = timespec_diff_ms(pd1->ts, pd0->ts); if (ms < tolerance_ms || ms > interval * MSEC_PER_SEC * 10) return; /* discard the sample if weird data */ kbs = (int64_t) (pd1->pgpgin - pd0->pgpgin); if (kbs < 0) return; kbs_sec = (kbs * MSEC_PER_SEC) / ms; free_pct = 100.0 * (double) pd1->nr_free_pages / (double) pd1->mem_pages; /* manual override (development time only) */ if (simulated_kbs >= 0) kbs_sec = simulated_kbs; if (simulated_free_pct >= 0) free_pct = simulated_free_pct; if (log_fp && debug_level >= 3) { fprintf(log_fp, "pgpgin=%llu, nr_free_pages=%llu, kbs=%lu, kbs_sec=%lu, free%%=%f\n", (unsigned long long) pd1->pgpgin, (unsigned long long) pd1->nr_free_pages, (unsigned long) kbs, (unsigned long) kbs_sec, free_pct); } /* format memory pressure report string */ /* (could use json if data structure were more complicated and changeable) */ sprintf(report, "%c\n" "action: report\n" "progname: %s\n" "progversion: %s\n" "seq: %llu\n" "kb: %lu\n" "kbsec: %lu\n" "freepct: %f\n", struct_version, progname, progversion, report_seq++, (unsigned long) kbs, (unsigned long) kbs_sec, free_pct); /* write report data to xenstore */ for (;;) { if (!begin_singleop_xs()) break; if (!xs_write(xs, xst, membalance_report_path, report, strlen(report))) { error_perror("unable to write xenstore"); abort_singleop_xs(); break; } if (commit_singleop_xs(&nretries) != XSTS_RETRY) break; } }