void extint_w2a(void *param) { int n, i, j; conn_t *conn = (conn_t *) param; u4_t ka_time = timer_sec(); // initialize extension for this connection send_msg_mc(conn->mc, false, "EXT ext_client_init"); nbuf_t *nb = NULL; while (TRUE) { int rx_chan, ext_rx_chan; ext_t *ext; if (nb) web_to_app_done(conn, nb); n = web_to_app(conn, &nb); if (n) { char *cmd = nb->buf; cmd[n] = 0; // okay to do this -- see nbuf.c:nbuf_allocq() char id[64]; ka_time = timer_sec(); // receive and send a roundtrip keepalive i = strcmp(cmd, "SET keepalive"); if (i == 0) { ext_send_msg(conn->ext_rx_chan, false, "EXT keepalive"); continue; } ext_rx_chan = conn->ext_rx_chan; //printf("extint_w2a: %s CONN%d-%p RX%d-%p %d <%s>\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn, strlen(cmd), cmd); // answer from client ext about who they are // match against list of known extensions and register msg handler char client[32]; int first_time; i = sscanf(cmd, "SET ext_switch_to_client=%s first_time=%d rx_chan=%d", client, &first_time, &rx_chan); if (i == 3) { for (i=0; i < n_exts; i++) { ext = ext_list[i]; if (strcmp(client, ext->name) == 0) { //printf("ext_switch_to_client: found func %p CONN%d-%p for ext %s RX%d\n", ext->receive_msgs, conn->self_idx, conn, client, rx_chan); ext_users[rx_chan].ext = ext; ext_users[rx_chan].conn = conn; conn->ext_rx_chan = rx_chan; conn->ext = ext; TaskNameS(ext->name); break; } } if (i == n_exts) panic("ext_switch_to_client: unknown ext"); // automatically let extension server-side know the connection has been established and // our stream thread is running if (first_time) ext->receive_msgs((char *) "SET ext_server_init", rx_chan); continue; } i = sscanf(cmd, "SET ext_blur=%d", &rx_chan); if (i == 1) { extint_ext_users_init(rx_chan); continue; } i = strcmp(cmd, "SET init"); if (i == 0) { continue; } i = sscanf(cmd, "SERVER DE CLIENT %s", id); if (i == 1) { continue; } ext_rx_chan = conn->ext_rx_chan; if (ext_rx_chan == -1) { printf("### extint_w2a: %s CONN%d-%p ext_rx_chan == -1?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn); continue; } ext = ext_users[ext_rx_chan].ext; if (ext == NULL) { printf("### extint_w2a: %s CONN%d-%p ext_rx_chan %d ext NULL?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan); continue; } if (ext->receive_msgs) { //printf("extint_w2a: %s ext->receive_msgs() %p CONN%d-%p RX%d-%p %d <%s>\n", conn->ext? conn->ext->name:"?", ext->receive_msgs, conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn, strlen(cmd), cmd); if (ext->receive_msgs(cmd, ext_rx_chan)) continue; } else { printf("### extint_w2a: %s CONN%d-%p RX%d-%p ext->receive_msgs == NULL?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn); continue; } printf("extint_w2a: %s CONN%d-%p unknown command: <%s> ======================================================\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, cmd); continue; } conn->keep_alive = timer_sec() - ka_time; bool keepalive_expired = (conn->keep_alive > KEEPALIVE_SEC); if (keepalive_expired) { ext_rx_chan = conn->ext_rx_chan; ext = ext_users[ext_rx_chan].ext; printf("EXT KEEP-ALIVE EXPIRED RX%d %s\n", ext_rx_chan, ext? ext->name : "(no ext)"); if (ext != NULL && ext->close_conn != NULL) ext->close_conn(ext_rx_chan); extint_ext_users_init(ext_rx_chan); rx_server_remove(conn); panic("shouldn't return"); } TaskSleep(250000); } }
void w2a_admin(void *param) { int n, i, j; conn_t *conn = (conn_t *) param; static char json_buf[16384]; u4_t ka_time = timer_sec(); // send initial values send_msg(conn, SM_NO_DEBUG, "ADM init=%d", RX_CHANS); nbuf_t *nb = NULL; while (TRUE) { if (nb) web_to_app_done(conn, nb); n = web_to_app(conn, &nb); if (n) { char *cmd = nb->buf; cmd[n] = 0; // okay to do this -- see nbuf.c:nbuf_allocq() ka_time = timer_sec(); if (rx_common_cmd("W/F", conn, cmd)) continue; //printf("ADMIN: %d <%s>\n", strlen(cmd), cmd); i = strcmp(cmd, "SET init"); if (i == 0) { continue; } i = strcmp(cmd, "SET gps_update"); if (i == 0) { gps_stats_t::gps_chan_t *c; char *cp = json_buf; n = sprintf(cp, "{ \"FFTch\":%d, \"ch\":[ ", gps.FFTch); cp += n; for (i=0; i < gps_chans; i++) { c = &gps.ch[i]; int un = c->ca_unlocked; n = sprintf(cp, "%s{ \"ch\":%d, \"prn\":%d, \"snr\":%d, \"rssi\":%d, \"gain\":%d, \"hold\":%d, \"wdog\":%d" ", \"unlock\":%d, \"parity\":%d, \"sub\":%d, \"sub_renew\":%d, \"novfl\":%d }", i? ", ":"", i, c->prn, c->snr, c->rssi, c->gain, c->hold, c->wdog, un, c->parity, c->sub, c->sub_renew, c->novfl); cp += n; c->parity = 0; for (j = 0; j < SUBFRAMES; j++) { if (c->sub_renew & (1<<j)) { c->sub |= 1<<j; c->sub_renew &= ~(1<<j); } } } n = sprintf(cp, " ]"); cp += n; UMS hms(gps.StatSec/60/60); unsigned r = (timer_ms() - gps.start)/1000; if (r >= 3600) { n = sprintf(cp, ", \"run\":\"%d:%02d:%02d\"", r / 3600, (r / 60) % 60, r % 60); cp += n; } else { n = sprintf(cp, ", \"run\":\"%d:%02d\"", (r / 60) % 60, r % 60); cp += n; } if (gps.ttff) { n = sprintf(cp, ", \"ttff\":\"%d:%02d\"", gps.ttff / 60, gps.ttff % 60); cp += n; } else { n = sprintf(cp, ", \"ttff\":null"); cp += n; } if (gps.StatDay != -1) { n = sprintf(cp, ", \"gpstime\":\"%s %02d:%02d:%02.0f\"", Week[gps.StatDay], hms.u, hms.m, hms.s); cp += n; } else { n = sprintf(cp, ", \"gpstime\":null"); cp += n; } if (gps.StatLat) { n = sprintf(cp, ", \"lat\":\"%8.6f %c\"", gps.StatLat, gps.StatNS); cp += n; n = sprintf(cp, ", \"lon\":\"%8.6f %c\"", gps.StatLon, gps.StatEW); cp += n; n = sprintf(cp, ", \"alt\":\"%1.0f m\"", gps.StatAlt); cp += n; n = sprintf(cp, ", \"map\":\"<a href='http://wikimapia.org/#lang=en&lat=%8.6f&lon=%8.6f&z=18&m=b' target='_blank'>wikimapia.org</a>\"", gps.sgnLat, gps.sgnLon); cp += n; } else { n = sprintf(cp, ", \"lat\":null"); cp += n; } n = sprintf(cp, ", \"acq\":%d, \"track\":%d, \"good\":%d, \"fixes\":%d, \"adc_clk\":%.6f, \"adc_corr\":%d", gps.acquiring? 1:0, gps.tracking, gps.good, gps.fixes, (adc_clock - adc_clock_offset)/1e6, gps.adc_clk_corr); cp += n; n = sprintf(cp, " }"); cp += n; send_encoded_msg_mc(conn->mc, "ADM", "gps_update", "%s", json_buf); continue; } i = strcmp(cmd, "SET sdr_hu_update"); if (i == 0) { gps_stats_t::gps_chan_t *c; char *cp = json_buf; n = sprintf(cp, "{ "); cp += n; if (gps.StatLat) { n = sprintf(cp, "\"lat\":\"%8.6f\", \"lon\":\"%8.6f\"", gps.sgnLat, gps.sgnLon); cp += n; } n = sprintf(cp, " }"); cp += n; send_encoded_msg_mc(conn->mc, "ADM", "sdr_hu_update", "%s", json_buf); continue; } int force_check; i = sscanf(cmd, "SET force_check=%d force_build=%d", &force_check, &force_build); if (i == 2) { check_for_update(force_check); continue; } i = strcmp(cmd, "SET reload_index_params"); if (i == 0) { reload_index_params(); continue; } i = strcmp(cmd, "SET extint_load_extension_configs"); if (i == 0) { extint_load_extension_configs(conn); continue; } i = strcmp(cmd, "SET restart"); if (i == 0) { lprintf("ADMIN: restart requested by admin..\n"); exit(0); } i = strcmp(cmd, "SET reboot"); if (i == 0) { lprintf("ADMIN: reboot requested by admin..\n"); system("reboot"); while (true) usleep(100000); } i = strcmp(cmd, "SET power_off"); if (i == 0) { lprintf("ADMIN: power off requested by admin..\n"); system("poweroff"); while (true) usleep(100000); } printf("ADMIN: unknown command: <%s>\n", cmd); continue; } conn->keep_alive = timer_sec() - ka_time; bool keepalive_expired = (conn->keep_alive > KEEPALIVE_SEC); if (keepalive_expired) { printf("ADMIN KEEP-ALIVE EXPIRED\n"); rx_server_remove(conn); return; } TaskSleep(250000); } }
int main(int argc, char **argv) { int i,j,k,iad; int aad,bad,cad; int N=16; if(argc>1) { N=atoi(argv[1]); } i=N/4; if(N>(i*4)) N=(i+1)*4; double l2=log(N)/log(2.0); int il2=(int)l2; if(il2<l2) il2++; int MSZ=pow(2,il2); int N4=N/4; printf("N=%d; N/4=%d; msize=%d\n",N,N4,MSZ); // actual memory allocation must be power of 2 although N can be any multiple of 4 float *a=(float *)_mm_malloc(MSZ*MSZ*sizeof(float),128); float *b=(float *)_mm_malloc(MSZ*MSZ*sizeof(float),128); float *c=(float *)_mm_malloc(MSZ*MSZ*sizeof(float),128); int iv=0; #pragma omp parallel for private (i,j,iv,iad) for(i=0; i<N; i++) { for(j=0; j<N; j++) { iv=j+i*N; iad=zorder2d(j,i); a[iad]=b[iad]=iv; c[iad]=0; } } tv ts; timer_reset(ts); timer_start(ts); for(i=0; i<N4; i++) { #pragma omp parallel for private (aad,bad,cad,i,j,k) for(j=0; j<N4; j++) { cad=16*zorder2d(j,i); for(k=0; k<N4; k++) { aad=16*zorder2d(k,i); bad=16*zorder2d(j,k); zmatmul(&a[aad],&b[bad],&c[cad]); } } } timer_stop(ts); printf("sec: %lf\n",timer_sec(ts)); float fN=N; printf("GFlops/s: %lf\n",(double)(fN*fN*(2*fN-1))/timer_sec(ts)/1000000000.0); // pmat(N,a); // pmat(N,b); // pmat(N,c); _mm_free(a); _mm_free(b); _mm_free(c); }
static void ll_printf(u4_t type, conn_t *c, const char *fmt, va_list ap) { int i, sl; char *s, *cp; #define VBUF 1024 if (!do_sdr) { //if (!background_mode) { if ((buf = (char*) malloc(VBUF)) == NULL) panic("log malloc"); vsnprintf(buf, VBUF, fmt, ap); // remove our override and call the actual underlying printf #undef printf printf("%s", buf); #define printf ALT_PRINTF evPrintf(EC_EVENT, EV_PRINTF, -1, "printf", buf); if (buf) free(buf); buf = 0; return; } if (appending) { s = last_s; } else { brem = VBUF; if ((buf = (char*) malloc(VBUF)) == NULL) panic("log malloc"); s = buf; start_s = s; } vsnprintf(s, brem, fmt, ap); sl = strlen(s); // because vsnprintf returns length disregarding limit, not the actual length brem -= sl+1; cp = &s[sl-1]; if (*cp != '\n' && brem && !(type & PRINTF_MSG)) { last_s = cp+1; appending = true; return; } else { appending = false; } // for logging, don't print an empty line at all if ((type & (PRINTF_REG | PRINTF_LOG)) && (!background_mode || strcmp(start_s, "\n") != 0)) { // remove non-ASCII since "systemctl status" gives [blob] message // unlike "systemctl log" which prints correctly int sl = strlen(buf); for (i=0; i < sl; i++) if (buf[i] > 0x7f) buf[i] = '?'; char up_chan_stat[64], *s = up_chan_stat; // uptime u4_t up = timer_sec(); u4_t sec = up % 60; up /= 60; u4_t min = up % 60; up /= 60; u4_t hr = up % 24; up /= 24; u4_t days = up; if (days) sl = sprintf(s, "%dd:%02d:%02d:%02d ", days, hr, min, sec); else sl = sprintf(s, "%d:%02d:%02d ", hr, min, sec); s += sl; // show state of all rx channels rx_chan_t *rx; for (rx = rx_chan, i=0; rx < &rx_chan[RX_CHANS]; rx++, i++) { *s++ = rx->busy? '0'+i : '.'; } *s++ = ' '; // show rx channel number if message is associated with a particular rx channel if (c != NULL) { for (i=0; i < RX_CHANS; i++) *s++ = (i == c->rx_channel)? '0'+i : ' '; } else { for (i=0; i < RX_CHANS; i++) *s++ = ' '; } *s = 0; if (((type & PRINTF_LOG) && (background_mode || log_foreground_mode)) || log_ordinary_printfs) { syslog(LOG_INFO, "%s %s", up_chan_stat, buf); } time_t t; char tb[32]; time(&t); ctime_r(&t, tb); tb[24]=0; // remove our override and call the actual underlying printf #undef printf printf("%s %s %s", tb, up_chan_stat, buf); #define printf ALT_PRINTF evPrintf(EC_EVENT, EV_PRINTF, -1, "printf", buf); } // attempt to also record message remotely if ((type & PRINTF_MSG) && msgs_mc) { if (type & PRINTF_FF) send_encoded_msg_mc(msgs_mc, "MSG", "status_msg", "\f%s", buf); else send_encoded_msg_mc(msgs_mc, "MSG", "status_msg", "%s", buf); } if (buf) free(buf); buf = 0; }
static void update_task(void *param) { conn_t *conn = (conn_t *) FROM_VOID_PARAM(param); bool force_check = (conn && conn->update_check == FORCE_CHECK); bool force_build = (conn && conn->update_check == FORCE_BUILD); bool ver_changed, update_install; lprintf("UPDATE: checking for updates\n"); // Run curl in a Linux child process otherwise this thread will block and cause trouble // if the check is invoked from the admin page while there are active user connections. int status = child_task("kiwi.upd", POLL_MSEC(1000), curl_makefile_ctask, NULL); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { lprintf("UPDATE: curl Makefile error, no Internet access? status=0x%08x WIFEXITED=%d WEXITSTATUS=%d\n", status, WIFEXITED(status), WEXITSTATUS(status)); if (force_check) report_result(conn); goto common_return; } FILE *fp; scallz("fopen Makefile.1", (fp = fopen("/root/" REPO_NAME "/Makefile.1", "r"))); int n1, n2; n1 = fscanf(fp, "VERSION_MAJ = %d\n", &pending_maj); n2 = fscanf(fp, "VERSION_MIN = %d\n", &pending_min); fclose(fp); ver_changed = (n1 == 1 && n2 == 1 && (pending_maj > version_maj || (pending_maj == version_maj && pending_min > version_min))); update_install = (admcfg_bool("update_install", NULL, CFG_REQUIRED) == true); if (force_check) { if (ver_changed) lprintf("UPDATE: version changed (current %d.%d, new %d.%d), but check only\n", version_maj, version_min, pending_maj, pending_min); else lprintf("UPDATE: running most current version\n"); report_result(conn); goto common_return; } else if (ver_changed && !update_install && !force_build) { lprintf("UPDATE: version changed (current %d.%d, new %d.%d), but update install not enabled\n", version_maj, version_min, pending_maj, pending_min); } else if (ver_changed || force_build) { lprintf("UPDATE: version changed%s, current %d.%d, new %d.%d\n", force_build? " (forced)":"", version_maj, version_min, pending_maj, pending_min); lprintf("UPDATE: building new version..\n"); update_in_progress = true; rx_server_user_kick(-1); // kick everyone off to speed up build sleep(5); // Run build in a Linux child process so the server can continue to respond to connection requests // and display a "software update in progress" message. // This is because the calls to system() in update_build_ctask() block for the duration of the build. u4_t build_time = timer_sec(); status = child_task("kiwi.bld", POLL_MSEC(1000), update_build_ctask, TO_VOID_PARAM(force_build)); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { lprintf("UPDATE: build error, no Internet access? status=0x%08x WIFEXITED=%d WEXITSTATUS=%d\n", status, WIFEXITED(status), WEXITSTATUS(status)); goto common_return; } lprintf("UPDATE: build took %d secs\n", timer_sec() - build_time); lprintf("UPDATE: switching to new version %d.%d\n", pending_maj, pending_min); if (admcfg_int("update_restart", NULL, CFG_REQUIRED) == 0) { xit(0); } else { lprintf("UPDATE: rebooting Beagle..\n"); system("sleep 3; reboot"); } } else { lprintf("UPDATE: version %d.%d is current\n", version_maj, version_min); } if (daily_restart) { lprintf("UPDATE: daily restart..\n"); xit(0); } common_return: if (conn) conn->update_check = WAIT_UNTIL_NO_USERS; // restore default update_pending = update_task_running = update_in_progress = false; }