bool ph_thread_set_affinity(ph_thread_t *me, int affinity) { ph_cpu_set_t set; CPU_ZERO(&set); CPU_SET(affinity, &set); return apply_affinity(&set, me); }
/* { * "base": 0, // base core number; is added to "selector" * "selector": "tid", // use tid * "selector": "wid", // use thr->is_worker id * "selector": [1,2,3], // use 1+base, 2+base, 3+base * "selector": 1, // use 1+base * "selector": "none" // don't specify affinity * } */ bool ph_thread_set_affinity_policy(ph_thread_t *me, ph_variant_t *policy) { ph_cpu_set_t set; uint32_t cores = ph_num_cores(); CPU_ZERO(&set); if (!policy) { ph_cpu_set(me->tid % cores, &set); } else { int base = 0; ph_var_err_t err; ph_variant_t *sel = NULL; ph_var_unpack(policy, &err, 0, "{si, so}", "base", &base, "selector", &sel); if (sel && ph_var_is_array(sel)) { uint32_t i; for (i = 0; i < ph_var_array_size(sel); i++) { int cpu = ph_var_int_val(ph_var_array_get(sel, i)); ph_cpu_set((base + cpu) % cores, &set); } } else if (sel && ph_var_is_string(sel)) { ph_string_t *s = ph_var_string_val(sel); if (ph_string_equal_cstr(s, "tid")) { ph_cpu_set((base + me->tid) % cores, &set); } else if (ph_string_equal_cstr(s, "wid")) { ph_cpu_set((base + me->is_worker - 1) % cores, &set); } else if (ph_string_equal_cstr(s, "none")) { return true; } else { ph_log(PH_LOG_ERR, "Unknown thread affinity selector `Ps%p", (void*)s); } } else if (sel && ph_var_is_int(sel)) { ph_cpu_set((base + ph_var_int_val(sel)) % cores, &set); } else { ph_cpu_set((base + me->tid) % cores, &set); } } return apply_affinity(&set, me); }
static void naive_affine_map_using_spline(float *y, int out_w, int out_h, float *x, int w, int h, int pd, double A[6], int order) { float *fx = malloc(w * h * pd * sizeof*fx); for (int i = 0; i < w * h * pd; i++) fx[i] = x[i]; bool r = prepare_spline(fx, w, h, pd, order); if (!r) exit(fprintf(stderr,"prepare spline failed (ord=%d)\n",order)); //if (1) { // char buf[FILENAME_MAX]; // snprintf(buf,FILENAME_MAX,"/tmp/prepared_spline_%d.tiff",order); // iio_save_image_float_vec(buf, fx, w, h, pd); //} double invA[6]; invert_affinity(invA, A); for (int j = 0; j < out_h; j++) for (int i = 0; i < out_w; i++) { double p[2] = {i, j}; apply_affinity(p, A, p); float *out = y + (j * out_w + i) * pd; evaluate_spline_at(out, fx, w, h, pd, order, p[0], p[1]); } free(fx); }
/*--------------------------------------------------------- */ int main(int argc, char **argv) { int retval = -1; struct options *opts = NULL; int pidfd = -1; unsigned int interval; /* Signal vars */ struct sigaction sig_act; sigset_t sig_set; /* IRQ list. It contain all found IRQs. */ lub_list_t *irqs; /* IRQs need to be balanced */ lub_list_t *balance_irqs; /* CPU list. It contain all found CPUs. */ lub_list_t *cpus; /* NUMA list. It contain all found NUMA nodes. */ lub_list_t *numas; /* Proximity list. */ lub_list_t *pxms; /* Parse command line options */ opts = opts_init(); if (opts_parse(argc, argv, opts)) goto err; /* Initialize syslog */ openlog(argv[0], LOG_CONS, opts->log_facility); syslog(LOG_ERR, "Start daemon.\n"); /* Fork the daemon */ if (!opts->debug) { /* Daemonize */ if (daemon(0, 0) < 0) { syslog(LOG_ERR, "Can't daemonize\n"); goto err; } /* Write pidfile */ if ((pidfd = open(opts->pidfile, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { syslog(LOG_WARNING, "Can't open pidfile %s: %s", opts->pidfile, strerror(errno)); } else { char str[20]; snprintf(str, sizeof(str), "%u\n", getpid()); str[sizeof(str) - 1] = '\0'; if (write(pidfd, str, strlen(str)) < 0) syslog(LOG_WARNING, "Can't write to %s: %s", opts->pidfile, strerror(errno)); close(pidfd); } } /* Set signal handler */ sigemptyset(&sig_set); sigaddset(&sig_set, SIGTERM); sigaddset(&sig_set, SIGINT); sigaddset(&sig_set, SIGQUIT); sig_act.sa_flags = 0; sig_act.sa_mask = sig_set; sig_act.sa_handler = &sighandler; sigaction(SIGTERM, &sig_act, NULL); sigaction(SIGINT, &sig_act, NULL); sigaction(SIGQUIT, &sig_act, NULL); /* Randomize */ srand(time(NULL)); /* Scan NUMA nodes */ numas = lub_list_new(numa_list_compare); scan_numas(numas); if (opts->verbose) show_numas(numas); /* Scan CPUs */ cpus = lub_list_new(cpu_list_compare); scan_cpus(cpus, opts->ht); if (opts->verbose) show_cpus(cpus); /* Prepare data structures */ irqs = lub_list_new(irq_list_compare); balance_irqs = lub_list_new(irq_list_compare); /* Parse proximity file */ pxms = lub_list_new(NULL); if (opts->pxm) parse_pxm_config(opts->pxm, pxms, numas); if (opts->verbose) show_pxms(pxms); /* Main loop */ while (!sigterm) { lub_list_node_t *node; char outstr[10]; time_t t; struct tm *tmp; t = time(NULL); tmp = localtime(&t); if (tmp) { strftime(outstr, sizeof(outstr), "%H:%M:%S", tmp); printf("----[ %s ]----------------------------------------------------------------\n", outstr); } /* Rescan PCI devices for new IRQs. */ scan_irqs(irqs, balance_irqs, pxms); if (opts->verbose) irq_list_show(irqs); /* Link IRQs to CPUs due to real current smp affinity. */ link_irqs_to_cpus(cpus, irqs); /* Gather statistics on CPU load and number of interrupts. */ gather_statistics(cpus, irqs); show_statistics(cpus, opts->verbose); /* Choose IRQ to move to another CPU. */ choose_irqs_to_move(cpus, balance_irqs, opts->threshold, opts->strategy); /* If nothing to balance */ if (lub_list_len(balance_irqs) != 0) { /* Set short interval to make balancing faster. */ interval = opts->short_interval; /* Choose new CPU for IRQs need to be balanced. */ balance(cpus, balance_irqs, opts->threshold); /* Write new values to /proc/irq/<IRQ>/smp_affinity */ apply_affinity(balance_irqs); /* Free list of balanced IRQs */ while ((node = lub_list__get_tail(balance_irqs))) { lub_list_del(balance_irqs, node); lub_list_node_free(node); } } else { /* If nothing to balance */ interval = opts->long_interval; } /* Wait before next iteration */ sleep(interval); } /* Free data structures */ irq_list_free(irqs); lub_list_free(balance_irqs); cpu_list_free(cpus); numa_list_free(numas); pxm_list_free(pxms); retval = 0; err: /* Remove pidfile */ if (pidfd >= 0) { if (unlink(opts->pidfile) < 0) { syslog(LOG_ERR, "Can't remove pid-file %s: %s\n", opts->pidfile, strerror(errno)); } } /* Free command line options */ opts_free(opts); syslog(LOG_ERR, "Stop daemon.\n"); return retval; }