Esempio n. 1
0
int main(int argc, char **argv) {
    NOTUSED(argc);
    NOTUSED(argv);

    initConfig();
    parseOptions(argc,argv);
    initScreen();
    initEditor(l81.fb,30,30,30,30);
    editorOpen(l81.filename);
    while(1) {
        resetProgram();
        loadProgram();
        if (!l81.luaerr) {
            SDL_setFramerate(&l81.fb->fps_mgr,l81.fps);
            l81.start_ms = mstime();
            while(!processSdlEvents());
            if (editorFileWasModified()) editorSave(l81.filename);
        }
        editorRun();
    }
    return 0;
}
Esempio n. 2
0
File: db.c Progetto: hylaz/redis
int expireIfNeeded(redisDb *db, robj *key) {
    mstime_t when = getExpire(db,key);//微秒
    mstime_t now;

    if (when < 0) return 0; /* No expire for this key */

    /* Don't expire anything while loading. It will be done later. */
    if (server.loading) return 0;

    /* If we are in the context of a Lua script, we claim that time is
     * blocked to when the Lua script started. This way a key can expire
     * only the first time it is accessed and not in the middle of the
     * script execution, making propagation to slaves / AOF consistent.
     * See issue #1525 on Github for more information. */
    now = server.lua_caller ? server.lua_time_start : mstime();

    /* If we are running in the context of a slave, return ASAP:
     * the slave key expiration is controlled by the master that will
     * send us synthesized DEL operations for expired keys.
     *
     * Still we try to return the right information to the caller,
     * that is, 0 if we think the key should be still valid, 1 if
     * we think the key is expired at this time. */
    if (server.masterhost != NULL) return now > when;

    /* Return when this key has not expired */
    if (now <= when) return 0;

    /* Delete the key */
    server.stat_expiredkeys++;

    propagateExpire(db,key);
    //事件函数的处理
    notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,
                        "expired",key,db->id);
    //删除该键
    return dbDelete(db,key);
}
Esempio n. 3
0
void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
    long long elapsed;
    REDIS_NOTUSED(ar);
    REDIS_NOTUSED(lua);

    elapsed = mstime() - server.lua_time_start;
    if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {
        redisLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);
        server.lua_timedout = 1;
        /* Once the script timeouts we reenter the event loop to permit others
         * to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason
         * we need to mask the client executing the script from the event loop.
         * If we don't do that the client may disconnect and could no longer be
         * here when the EVAL command will return. */
         aeDeleteFileEvent(server.el, server.lua_caller->fd, AE_READABLE);
    }
    if (server.lua_timedout) processEventsWhileBlocked();
    if (server.lua_kill) {
        redisLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL.");
        lua_pushstring(lua,"Script killed by user with SCRIPT KILL...");
        lua_error(lua);
    }
}
Esempio n. 4
0
    /* Call it */
    return cliSendCommand(argc+3-got_comma, argv2, config.repeat);
}

#define LATENCY_SAMPLE_RATE 10 /* milliseconds. */
#define LATENCY_HISTORY_DEFAULT_INTERVAL 15000 /* milliseconds. */
static void latencyMode(void) {
    redisReply *reply;
    long long start, latency, min = 0, max = 0, tot = 0, count = 0;
    long long history_interval =
        config.interval ? config.interval/1000 :
                          LATENCY_HISTORY_DEFAULT_INTERVAL;
    double avg;
    long long history_start = mstime();

    if (!context) exit(1);
    while(1) {
        start = mstime();
        reply = redisCommand(context,"PING");
        if (reply == NULL) {
            fprintf(stderr,"\nI/O error\n");
            exit(1);
        }
        latency = mstime()-start;
        freeReplyObject(reply);
        count++;
        if (count == 1) {
            min = max = tot = latency;
            avg = (double) latency;
        } else {
            if (latency < min) min = latency;
            if (latency > max) max = latency;
            tot += latency;
            avg = (double) tot/count;
        }
        printf("\x1b[0G\x1b[2Kmin: %lld, max: %lld, avg: %.2f (%lld samples)",
            min, max, avg, count);
        fflush(stdout);
        if (config.latency_history && mstime()-history_start > history_interval)
        {
            printf(" -- %.2f seconds range\n", (float)(mstime()-history_start)/1000);
            history_start = mstime();
            min = max = tot = count = 0;
        }
        usleep(LATENCY_SAMPLE_RATE * 1000);
    }
}
Esempio n. 5
0
/* *
 * slotsrestore key ttl val [key ttl val ...]
 * */
void
slotsrestoreCommand(redisClient *c) {
    if (c->argc < 4 || (c->argc - 1) % 3 != 0) {
        addReplyErrorFormat(c, "wrong number of arguments for 'slotsrestore' command");
        return;
    }
    int n = (c->argc - 1) / 3;

    long long *ttls = zmalloc(sizeof(long long) * n);
    robj **vals = zmalloc(sizeof(robj *) * n);
    for (int i = 0; i < n; i ++) {
        vals[i] = NULL;
    }

    for (int i = 0; i < n; i ++) {
        robj *key = c->argv[i * 3 + 1];
        robj *ttl = c->argv[i * 3 + 2];
        robj *val = c->argv[i * 3 + 3];
        if (lookupKeyWrite(c->db, key) != NULL) {
            redisLog(REDIS_WARNING, "slotsrestore: slot = %d, key = '%s' already exists",
                    slots_num(key->ptr, NULL), (char *)key->ptr);
        }
        if (getLongLongFromObjectOrReply(c, ttl, &ttls[i], NULL) != REDIS_OK) {
            goto cleanup;
        } else if (ttls[i] < 0) {
            addReplyError(c, "invalid ttl value, must be >= 0");
            goto cleanup;
        }
        rio payload;
        int type;
        if (verifyDumpPayload(val->ptr, sdslen(val->ptr)) != REDIS_OK) {
            addReplyError(c, "dump payload version or checksum are wrong");
            goto cleanup;
        }
        rioInitWithBuffer(&payload, val->ptr);
        if (((type = rdbLoadObjectType(&payload)) == -1) ||
                ((vals[i] = rdbLoadObject(type, &payload)) == NULL)) {
            addReplyError(c, "bad data format");
            goto cleanup;
        }
    }

    for (int i = 0; i < n; i ++) {
        robj *key = c->argv[i * 3 + 1];
        long long ttl = ttls[i];
        robj *val = vals[i];
        dbDelete(c->db, key);
        dbAdd(c->db, key, val);
        incrRefCount(val);
        if (ttl) {
            setExpire(c->db, key, mstime() + ttl);
        }
        signalModifiedKey(c->db, key);
        server.dirty ++;
    }
    addReply(c, shared.ok);

cleanup:
    for (int i = 0; i < n; i ++) {
        if (vals[i] != NULL) {
            decrRefCount(vals[i]);
        }
    }
    zfree(vals);
    zfree(ttls);
}
Esempio n. 6
0
//
//=========================================================================
//
// Receive new messages and populate the interactive mode with more info
//
struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
    struct aircraft *a, *aux;

    // Return if (checking crc) AND (not crcok) AND (not fixed)
    if (Modes.check_crc && (mm->crcok == 0) && (mm->correctedbits == 0)) 
        return NULL;

    // Lookup our aircraft or create a new one
    a = interactiveFindAircraft(mm->addr);
    if (!a) {                              // If it's a currently unknown aircraft....
        a = interactiveCreateAircraft(mm); // ., create a new record for it,
        a->next = Modes.aircrafts;         // .. and put it at the head of the list
        Modes.aircrafts = a;
    } else {
        /* If it is an already known aircraft, move it on head
         * so we keep aircrafts ordered by received message time.
         *
         * However move it on head only if at least one second elapsed
         * since the aircraft that is currently on head sent a message,
         * othewise with multiple aircrafts at the same time we have an
         * useless shuffle of positions on the screen. */
        if (0 && Modes.aircrafts != a && (time(NULL) - a->seen) >= 1) {
            aux = Modes.aircrafts;
            while(aux->next != a) aux = aux->next;
            /* Now we are a node before the aircraft to remove. */
            aux->next = aux->next->next; /* removed. */
            /* Add on head */
            a->next = Modes.aircrafts;
            Modes.aircrafts = a;
        }
    }

    a->signalLevel[a->messages & 7] = mm->signalLevel;// replace the 8th oldest signal strength
    a->seen      = time(NULL);
    a->timestamp = mm->timestampMsg;
    a->messages++;

    // If a (new) CALLSIGN has been received, copy it to the aircraft structure
    if (mm->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) {
        memcpy(a->flight, mm->flight, sizeof(a->flight));
    }

    // If a (new) ALTITUDE has been received, copy it to the aircraft structure
    if (mm->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
        if ( (a->modeCcount)                   // if we've a modeCcount already
          && (a->altitude  != mm->altitude ) ) // and Altitude has changed
//        && (a->modeC     != mm->modeC + 1)   // and Altitude not changed by +100 feet
//        && (a->modeC + 1 != mm->modeC    ) ) // and Altitude not changes by -100 feet
            {
            a->modeCcount   = 0;               //....zero the hit count
            a->modeACflags &= ~MODEAC_MSG_MODEC_HIT;
            }
        a->altitude = mm->altitude;
        a->modeC    = (mm->altitude + 49) / 100;
    }

    // If a (new) SQUAWK has been received, copy it to the aircraft structure
    if (mm->bFlags & MODES_ACFLAGS_SQUAWK_VALID) {
        if (a->modeA != mm->modeA) {
            a->modeAcount   = 0; // Squawk has changed, so zero the hit count
            a->modeACflags &= ~MODEAC_MSG_MODEA_HIT;
        }
        a->modeA = mm->modeA;
    }

    // If a (new) HEADING has been received, copy it to the aircraft structure
    if (mm->bFlags & MODES_ACFLAGS_HEADING_VALID) {
        a->track = mm->heading;
    }

    // If a (new) SPEED has been received, copy it to the aircraft structure
    if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) {
        a->speed = mm->velocity;
    }

    // If a (new) Vertical Descent rate has been received, copy it to the aircraft structure
    if (mm->bFlags & MODES_ACFLAGS_VERTRATE_VALID) {
        a->vert_rate = mm->vert_rate;
    }

    // if the Aircraft has landed or taken off since the last message, clear the even/odd CPR flags
    if ((mm->bFlags & MODES_ACFLAGS_AOG_VALID) && ((a->bFlags ^ mm->bFlags) & MODES_ACFLAGS_AOG)) {
        a->bFlags &= ~(MODES_ACFLAGS_LLBOTH_VALID | MODES_ACFLAGS_AOG);
    } 

    // If we've got a new cprlat or cprlon
    if (mm->bFlags & MODES_ACFLAGS_LLEITHER_VALID) {

        if (mm->bFlags & MODES_ACFLAGS_LLODD_VALID) {
            a->odd_cprlat  = mm->raw_latitude;
            a->odd_cprlon  = mm->raw_longitude;
            a->odd_cprtime = mstime();
        } else {
            a->even_cprlat  = mm->raw_latitude;
            a->even_cprlon  = mm->raw_longitude;
            a->even_cprtime = mstime();
        }

        if (((mm->bFlags | a->bFlags) & MODES_ACFLAGS_LLEITHER_VALID) == MODES_ACFLAGS_LLBOTH_VALID) {
        // If we now have both even and odd, decode the CPR

            // Try relative CPR first
            if (decodeCPRrelative(a, (mm->bFlags & MODES_ACFLAGS_LLODD_VALID), (mm->bFlags & MODES_ACFLAGS_AOG))) {
                // If relative CPR fails then try global if the two data are less than 10 seconds apart
                if (abs((int)(a->even_cprtime - a->odd_cprtime)) <= 10000) {
                    decodeCPR(a, (mm->bFlags & MODES_ACFLAGS_LLODD_VALID), (mm->bFlags & MODES_ACFLAGS_AOG));
                }
            }

            //If we sucessfully decoded, back copy the results to mm so that we can print them in list output
            if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) {
                mm->bFlags |= MODES_ACFLAGS_LATLON_VALID;
                mm->fLat    = a->lat;
                mm->fLon    = a->lon;
            }
        }
    }

    // Update the aircrafts a->bFlags to reflect the newly received mm->bFlags;
    a->bFlags |= mm->bFlags;

    if (mm->msgtype == 32) {
        int flags = a->modeACflags;
        if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) { 
            //
            // This Mode-C doesn't currently hit any known Mode-S, but it used to because MODEAC_MSG_MODEC_OLD is
            // set  So the aircraft it used to match has either changed altitude, or gone out of our receiver range
            //
            // We've now received this Mode-A/C again, so it must be a new aircraft. It could be another aircraft
            // at the same Mode-C altitude, or it could be a new airctraft with a new Mods-A squawk. 
            //
            // To avoid masking this aircraft from the interactive display, clear the MODEAC_MSG_MODES_OLD flag
            // and set messages to 1;
            //
            a->modeACflags = flags & ~MODEAC_MSG_MODEC_OLD;
            a->messages    = 1;
        }  
    }

    a->fs = mm->fs;

    return (a);
}
Esempio n. 7
0
//
//=========================================================================
//
// Show the currently captured interactive data on screen.
//
void interactiveShowData(void) {
    struct aircraft *a = Modes.aircrafts;
    time_t now = time(NULL);
    int count = 0;
    char progress;
    char spinner[4] = "|/-\\";

    // Refresh screen every (MODES_INTERACTIVE_REFRESH_TIME) miliseconde
    if ((mstime() - Modes.interactive_last_update) < MODES_INTERACTIVE_REFRESH_TIME)
       {return;}

    Modes.interactive_last_update = mstime();    

    // Attempt to reconsile any ModeA/C with known Mode-S
    // We can't condition on Modes.modeac because ModeA/C could be comming 
    // in from a raw input port which we can't turn off.
    interactiveUpdateAircraftModeS();

    progress = spinner[time(NULL)%4];

#ifndef _WIN32
    printf("\x1b[H\x1b[2J");    // Clear the screen
#else
    cls();
#endif

    if (Modes.interactive_rtl1090 == 0) {
        printf (
"Hex     Mode  Sqwk  Flight   Alt    Spd  Hdg    Lat      Long   Sig  Msgs   Ti%c\n", progress);
    } else {
        printf (
"Hex    Flight   Alt      V/S GS  TT  SSR  G*456^ Msgs    Seen %c\n", progress);
    }
    printf(
"-------------------------------------------------------------------------------\n");

    while(a && (count < Modes.interactive_rows)) {

        if ((now - a->seen) < Modes.interactive_display_ttl)
            {
            int msgs  = a->messages;
            int flags = a->modeACflags;

            if ( (((flags & (MODEAC_MSG_FLAG                             )) == 0                    )                 )
              || (((flags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEA_ONLY)) == MODEAC_MSG_MODEA_ONLY) && (msgs > 4  ) ) 
              || (((flags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD )) == 0                    ) && (msgs > 127) ) 
              ) {
                int altitude = a->altitude, speed = a->speed;
                char strSquawk[5] = " ";
                char strFl[6]     = " ";
                char strTt[5]     = " ";
                char strGs[5]     = " ";

                // Convert units to metric if --metric was specified
                if (Modes.metric) {
                    altitude = (int) (altitude / 3.2828);
                    speed    = (int) (speed    * 1.852);
                }
        
                if (a->bFlags & MODES_ACFLAGS_SQUAWK_VALID) {
                    snprintf(strSquawk,5,"%04x", a->modeA);}

                if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) {
                    snprintf (strGs, 5,"%3d", speed);}

                if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) {
                    snprintf (strTt, 5,"%03d", a->track);}
        
                if (msgs > 99999) {
                    msgs = 99999;}
        
                if (Modes.interactive_rtl1090) { // RTL1090 display mode

                    if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
                        snprintf(strFl,6,"F%03d",(altitude/100));
                    }
                    printf("%06x %-8s %-4s         %-3s %-3s %4s        %-6d  %-2d\n", 
                    a->addr, a->flight, strFl, strGs, strTt, strSquawk, msgs, (int)(now - a->seen));

                } else {                         // Dump1090 display mode
                    char strMode[5]               = "    ";
                    char strLat[8]                = " ";
                    char strLon[9]                = " ";
                    unsigned char * pSig       = a->signalLevel;
                    unsigned int signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] + 
                                                  pSig[4] + pSig[5] + pSig[6] + pSig[7] + 3) >> 3; 

                    if ((flags & MODEAC_MSG_FLAG) == 0) {
                        strMode[0] = 'S';
                    } else if (flags & MODEAC_MSG_MODEA_ONLY) {
                        strMode[0] = 'A';
                    }
                    if (flags & MODEAC_MSG_MODEA_HIT) {strMode[2] = 'a';}
                    if (flags & MODEAC_MSG_MODEC_HIT) {strMode[3] = 'c';}

                    if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) {
                        snprintf(strLat, 8,"%7.03f", a->lat);
                        snprintf(strLon, 9,"%8.03f", a->lon);
                    }

                    if (a->bFlags & MODES_ACFLAGS_AOG) {
                        snprintf(strFl, 6," grnd");
                    } else if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
                        snprintf(strFl, 6, "%5d", altitude);
                    }
 
                    printf("%06x  %-4s  %-4s  %-8s %5s  %3s  %3s  %7s %8s  %3d %5d   %2d\n",
                    a->addr, strMode, strSquawk, a->flight, strFl, strGs, strTt,
                    strLat, strLon, signalAverage, msgs, (int)(now - a->seen));
                }
                count++;
            }
        }
Esempio n. 8
0
void pexpireCommand(redisClient *c) {
    expireGenericCommand(c,mstime(),UNIT_MILLISECONDS);
}
Esempio n. 9
0
int main(int argc, char *argv[]) {
    printf("Second:%d, Millisecond:%lld, Microsecond:%lld\n",
        time(NULL), mstime(), ustime());
    exit(0);
}
Esempio n. 10
0
static void repl() {
    sds historyfile = NULL;
    int history = 0;
    char *line;
    int argc;
    sds *argv;

    config.interactive = 1;
    linenoiseSetCompletionCallback(completionCallback);

    /* Only use history when stdin is a tty. */
    if (isatty(fileno(stdin))) {
        history = 1;

        if (getenv("HOME") != NULL) {
            historyfile = sdscatprintf(sdsempty(),"%s/.rediscli_history",getenv("HOME"));
            linenoiseHistoryLoad(historyfile);
        }
    }

    cliRefreshPrompt();
    while((line = linenoise(context ? config.prompt : "not connected> ")) != NULL) {
        if (line[0] != '\0') {
            argv = sdssplitargs(line,&argc);
            if (history) linenoiseHistoryAdd(line);
            if (historyfile) linenoiseHistorySave(historyfile);

            if (argv == NULL) {
                printf("Invalid argument(s)\n");
                free(line);
                continue;
            } else if (argc > 0) {
                if (strcasecmp(argv[0],"quit") == 0 ||
                    strcasecmp(argv[0],"exit") == 0)
                {
                    exit(0);
                } else if (argc == 3 && !strcasecmp(argv[0],"connect")) {
                    sdsfree(config.hostip);
                    config.hostip = sdsnew(argv[1]);
                    config.hostport = atoi(argv[2]);
                    cliConnect(1);
                } else if (argc == 1 && !strcasecmp(argv[0],"clear")) {
                    linenoiseClearScreen();
                } else {
                    long long start_time = mstime(), elapsed;
                    int repeat, skipargs = 0;

                    repeat = atoi(argv[0]);
                    if (argc > 1 && repeat) {
                        skipargs = 1;
                    } else {
                        repeat = 1;
                    }

                    while (1) {
                        config.cluster_reissue_command = 0;
                        if (cliSendCommand(argc-skipargs,argv+skipargs,repeat)
                            != REDIS_OK)
                        {
                            cliConnect(1);

                            /* If we still cannot send the command print error.
                             * We'll try to reconnect the next time. */
                            if (cliSendCommand(argc-skipargs,argv+skipargs,repeat)
                                != REDIS_OK)
                                cliPrintContextError();
                        }
                        /* Issue the command again if we got redirected in cluster mode */
                        if (config.cluster_mode && config.cluster_reissue_command) {
                            cliConnect(1);
                        } else {
                            break;
                        }
                    }
                    elapsed = mstime()-start_time;
                    if (elapsed >= 500) {
                        printf("(%.2fs)\n",(double)elapsed/1000);
                    }
                }
            }
            /* Free the argument vector */
            while(argc--) sdsfree(argv[argc]);
            zfree(argv);
        }
        /* linenoise() returns malloc-ed lines like readline() */
        free(line);
    }
    exit(0);
}
Esempio n. 11
0
//
//=========================================================================
//
int main(int argc, char **argv) {
    int j;

    // Set sane defaults
    modesInitConfig();

    // signal handlers:
    signal(SIGINT, sigintHandler);
    signal(SIGTERM, sigtermHandler);

    // Parse the command line options
    for (j = 1; j < argc; j++) {
        int more = j+1 < argc; // There are more arguments

        if (!strcmp(argv[j],"--device-index") && more) {
            Modes.dev_name = strdup(argv[++j]);
        } else if (!strcmp(argv[j],"--gain") && more) {
            Modes.gain = (int) (atof(argv[++j])*10); // Gain is in tens of DBs
        } else if (!strcmp(argv[j],"--enable-agc")) {
            Modes.enable_agc++;
        } else if (!strcmp(argv[j],"--freq") && more) {
            Modes.freq = (int) strtoll(argv[++j],NULL,10);
        } else if (!strcmp(argv[j],"--ifile") && more) {
            Modes.filename = strdup(argv[++j]);
        } else if (!strcmp(argv[j],"--iformat") && more) {
            ++j;
            if (!strcasecmp(argv[j], "uc8")) {
                Modes.input_format = INPUT_UC8;
            } else if (!strcasecmp(argv[j], "sc16")) {
                Modes.input_format = INPUT_SC16;
            } else if (!strcasecmp(argv[j], "sc16q11")) {
                Modes.input_format = INPUT_SC16Q11;
            } else {
                fprintf(stderr, "Input format '%s' not understood (supported values: UC8, SC16, SC16Q11)\n",
                        argv[j]);
                exit(1);
            }
        } else if (!strcmp(argv[j],"--dcfilter")) {
            Modes.dc_filter = 1;
        } else if (!strcmp(argv[j],"--measure-noise")) {
            Modes.measure_noise = 1;
        } else if (!strcmp(argv[j],"--fix")) {
            Modes.nfix_crc = 1;
        } else if (!strcmp(argv[j],"--no-fix")) {
            Modes.nfix_crc = 0;
        } else if (!strcmp(argv[j],"--no-crc-check")) {
            Modes.check_crc = 0;
        } else if (!strcmp(argv[j],"--phase-enhance")) {
            Modes.phase_enhance = 1;
        } else if (!strcmp(argv[j],"--raw")) {
            Modes.raw = 1;
        } else if (!strcmp(argv[j],"--net")) {
            Modes.net = 1;
        } else if (!strcmp(argv[j],"--modeac")) {
            Modes.mode_ac = 1;
        } else if (!strcmp(argv[j],"--net-beast")) {
            Modes.beast = 1;
        } else if (!strcmp(argv[j],"--net-only")) {
            Modes.net = 1;
            Modes.net_only = 1;
       } else if (!strcmp(argv[j],"--net-heartbeat") && more) {
            Modes.net_heartbeat_interval = (uint64_t)(1000 * atof(argv[++j]));
       } else if (!strcmp(argv[j],"--net-ro-size") && more) {
            Modes.net_output_flush_size = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-ro-rate") && more) {
            Modes.net_output_flush_interval = 1000 * atoi(argv[++j]) / 15; // backwards compatibility
        } else if (!strcmp(argv[j],"--net-ro-interval") && more) {
            Modes.net_output_flush_interval = (uint64_t)(1000 * atof(argv[++j]));
        } else if (!strcmp(argv[j],"--net-ro-port") && more) {
            if (Modes.beast) // Required for legacy backward compatibility
                {Modes.net_output_beast_port = atoi(argv[++j]);;}
            else
                {Modes.net_output_raw_port = atoi(argv[++j]);}
        } else if (!strcmp(argv[j],"--net-ri-port") && more) {
            Modes.net_input_raw_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-bo-port") && more) {
            Modes.net_output_beast_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-bi-port") && more) {
            Modes.net_input_beast_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-bind-address") && more) {
            Modes.net_bind_address = strdup(argv[++j]);
        } else if (!strcmp(argv[j],"--net-http-port") && more) {
            Modes.net_http_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-fatsv-port") && more) {
            Modes.net_fatsv_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-sbs-port") && more) {
            Modes.net_output_sbs_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-buffer") && more) {
            Modes.net_sndbuf_size = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-verbatim")) {
            Modes.net_verbatim = 1;
        } else if (!strcmp(argv[j],"--forward-mlat")) {
            Modes.forward_mlat = 1;
        } else if (!strcmp(argv[j],"--onlyaddr")) {
            Modes.onlyaddr = 1;
        } else if (!strcmp(argv[j],"--metric")) {
            Modes.metric = 1;
        } else if (!strcmp(argv[j],"--aggressive")) {
            Modes.nfix_crc = MODES_MAX_BITERRORS;
        } else if (!strcmp(argv[j],"--interactive")) {
            Modes.interactive = Modes.throttle = 1;
        } else if (!strcmp(argv[j],"--throttle")) {
            Modes.throttle = 1;
        } else if (!strcmp(argv[j],"--interactive-rows") && more) {
            Modes.interactive_rows = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--interactive-ttl") && more) {
            Modes.interactive_display_ttl = (uint64_t)(1000 * atof(argv[++j]));
        } else if (!strcmp(argv[j],"--lat") && more) {
            Modes.fUserLat = atof(argv[++j]);
        } else if (!strcmp(argv[j],"--lon") && more) {
            Modes.fUserLon = atof(argv[++j]);
        } else if (!strcmp(argv[j],"--max-range") && more) {
            Modes.maxRange = atof(argv[++j]) * 1852.0; // convert to metres
        } else if (!strcmp(argv[j],"--debug") && more) {
            char *f = argv[++j];
            while(*f) {
                switch(*f) {
                case 'D': Modes.debug |= MODES_DEBUG_DEMOD; break;
                case 'd': Modes.debug |= MODES_DEBUG_DEMODERR; break;
                case 'C': Modes.debug |= MODES_DEBUG_GOODCRC; break;
                case 'c': Modes.debug |= MODES_DEBUG_BADCRC; break;
                case 'p': Modes.debug |= MODES_DEBUG_NOPREAMBLE; break;
                case 'n': Modes.debug |= MODES_DEBUG_NET; break;
                case 'j': Modes.debug |= MODES_DEBUG_JS; break;
                default:
                    fprintf(stderr, "Unknown debugging flag: %c\n", *f);
                    exit(1);
                    break;
                }
                f++;
            }
        } else if (!strcmp(argv[j],"--stats")) {
            if (!Modes.stats)
                Modes.stats = (uint64_t)1 << 60; // "never"
        } else if (!strcmp(argv[j],"--stats-range")) {
            Modes.stats_range_histo = 1;
        } else if (!strcmp(argv[j],"--stats-every") && more) {
            Modes.stats = (uint64_t) (1000 * atof(argv[++j]));
        } else if (!strcmp(argv[j],"--snip") && more) {
            snipMode(atoi(argv[++j]));
            exit(0);
        } else if (!strcmp(argv[j],"--help")) {
            showHelp();
            exit(0);
        } else if (!strcmp(argv[j],"--ppm") && more) {
            Modes.ppm_error = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--quiet")) {
            Modes.quiet = 1;
        } else if (!strcmp(argv[j],"--show-only") && more) {
            Modes.show_only = (uint32_t) strtoul(argv[++j], NULL, 16);
        } else if (!strcmp(argv[j],"--mlat")) {
            Modes.mlat = 1;
        } else if (!strcmp(argv[j],"--interactive-rtl1090")) {
            Modes.interactive = 1;
            Modes.interactive_rtl1090 = 1;
        } else if (!strcmp(argv[j],"--oversample")) {
            Modes.oversample = 1;
#ifndef _WIN32
        } else if (!strcmp(argv[j], "--write-json") && more) {
            Modes.json_dir = strdup(argv[++j]);
        } else if (!strcmp(argv[j], "--write-json-every") && more) {
            Modes.json_interval = (uint64_t)(1000 * atof(argv[++j]));
            if (Modes.json_interval < 100) // 0.1s
                Modes.json_interval = 100;
        } else if (!strcmp(argv[j], "--json-location-accuracy") && more) {
            Modes.json_location_accuracy = atoi(argv[++j]);
#endif
        } else {
            fprintf(stderr,
                "Unknown or not enough arguments for option '%s'.\n\n",
                argv[j]);
            showHelp();
            exit(1);
        }
    }

#ifndef _WIN32
    // Setup for SIGWINCH for handling lines
    if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
#endif

    if (Modes.mode_ac && Modes.oversample) {
        fprintf(stderr,
                "Warning: --modeac is currently ignored when --oversample is used;\n"
                "         no ModeA/C messages will be decoded.\n");
    }

    // Initialization
    log_with_timestamp("%s %s starting up.", MODES_DUMP1090_VARIANT, MODES_DUMP1090_VERSION);
    modesInit();

    if (Modes.net_only) {
        fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
    } else if (Modes.filename == NULL) {
        if (modesInitRTLSDR() < 0) {
            exit(1);
        }
    } else {
        if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
            Modes.fd = STDIN_FILENO;
        } else if ((Modes.fd = open(Modes.filename,
#ifdef _WIN32
                                    (O_RDONLY | O_BINARY)
#else
                                    (O_RDONLY)
#endif
                                    )) == -1) {
            perror("Opening data file");
            exit(1);
        }
    }
    if (Modes.net) modesInitNet();

    // init stats:
    Modes.stats_current.start = Modes.stats_current.end =
        Modes.stats_alltime.start = Modes.stats_alltime.end =
        Modes.stats_periodic.start = Modes.stats_periodic.end =
        Modes.stats_5min.start = Modes.stats_5min.end =
        Modes.stats_15min.start = Modes.stats_15min.end = mstime();

    for (j = 0; j < 15; ++j)
        Modes.stats_1min[j].start = Modes.stats_1min[j].end = Modes.stats_current.start;

    // write initial json files so they're not missing
    writeJsonToFile("receiver.json", generateReceiverJson);
    writeJsonToFile("stats.json", generateStatsJson);
    writeJsonToFile("aircraft.json", generateAircraftJson);

    // If the user specifies --net-only, just run in order to serve network
    // clients without reading data from the RTL device
    if (Modes.net_only) {
        while (!Modes.exit) {
            struct timespec start_time;

            start_cpu_timing(&start_time);
            backgroundTasks();
            end_cpu_timing(&start_time, &Modes.stats_current.background_cpu);

            usleep(100000);
        }
    } else {
        // Create the thread that will read the data from the device.
        pthread_mutex_lock(&Modes.data_mutex);
        pthread_create(&Modes.reader_thread, NULL, readerThreadEntryPoint, NULL);

        while (Modes.exit == 0) {
            struct timespec start_time;

            if (Modes.first_free_buffer == Modes.first_filled_buffer) {
                /* wait for more data.
                 * we should be getting data every 50-60ms. wait for max 100ms before we give up and do some background work.
                 * this is fairly aggressive as all our network I/O runs out of the background work!
                 */

                struct timespec ts;
                clock_gettime(CLOCK_REALTIME, &ts);
                ts.tv_nsec += 100000000;
                normalize_timespec(&ts);

                pthread_cond_timedwait(&Modes.data_cond, &Modes.data_mutex, &ts); // This unlocks Modes.data_mutex, and waits for Modes.data_cond
            }

            // Modes.data_mutex is locked, and possibly we have data.

            // copy out reader CPU time and reset it
            add_timespecs(&Modes.reader_cpu_accumulator, &Modes.stats_current.reader_cpu, &Modes.stats_current.reader_cpu);
            Modes.reader_cpu_accumulator.tv_sec = 0;
            Modes.reader_cpu_accumulator.tv_nsec = 0;

            if (Modes.first_free_buffer != Modes.first_filled_buffer) {
                // FIFO is not empty, process one buffer.

                struct mag_buf *buf;

                start_cpu_timing(&start_time);
                buf = &Modes.mag_buffers[Modes.first_filled_buffer];

                // Process data after releasing the lock, so that the capturing
                // thread can read data while we perform computationally expensive
                // stuff at the same time.
                pthread_mutex_unlock(&Modes.data_mutex);

                if (Modes.oversample) {
                    demodulate2400(buf);
                } else {
                    demodulate2000(buf);
                }

                Modes.stats_current.samples_processed += buf->length;
                Modes.stats_current.samples_dropped += buf->dropped;
                end_cpu_timing(&start_time, &Modes.stats_current.demod_cpu);

                // Mark the buffer we just processed as completed.
                pthread_mutex_lock(&Modes.data_mutex);
                Modes.first_filled_buffer = (Modes.first_filled_buffer + 1) % MODES_MAG_BUFFERS;
                pthread_cond_signal(&Modes.data_cond);
                pthread_mutex_unlock(&Modes.data_mutex);
            } else {
                // Nothing to process this time around.
                pthread_mutex_unlock(&Modes.data_mutex);
            }

            start_cpu_timing(&start_time);
            backgroundTasks();
            end_cpu_timing(&start_time, &Modes.stats_current.background_cpu);

            pthread_mutex_lock(&Modes.data_mutex);
        }

        pthread_mutex_unlock(&Modes.data_mutex);

        pthread_join(Modes.reader_thread,NULL);     // Wait on reader thread exit
        pthread_cond_destroy(&Modes.data_cond);     // Thread cleanup - only after the reader thread is dead!
        pthread_mutex_destroy(&Modes.data_mutex);
    }

    // If --stats were given, print statistics
    if (Modes.stats) {
        display_total_stats();
    }

    cleanup_converter(Modes.converter_state);
    log_with_timestamp("Normal exit.");

    pthread_exit(0);
#ifdef _WIN32
    return (0);
#endif
}
Esempio n. 12
0
int generic_transfer(struct wgetfile *finfo, FILE *out, size_t len,
		size_t sofar, int closefd)
{
#define RET(n) do{ ret = n; goto fin; }while(0)
	int ret = 0;
	long last_progress, last_speed_calc;
	long chunk = 0; /* for bps */
	long speed = 0;

	last_progress = last_speed_calc = mstime();
	if(!len)
		progress_unknown(sofar, 0);

	do{
		ssize_t nread;
		char buffer[BSIZ];
		long t;

		switch((nread = recv(finfo->sock, buffer, sizeof buffer, 0))){
			case -1:
				if(errno == EINTR)
					continue;

				/* TODO: retry */
				if(len && sofar == len)
					goto end_of_stream;
				connection_close_fd(finfo->sock);
				output_perror("recv()");
				RET(1);

			case 0:
end_of_stream:
				connection_close_fd(finfo->sock);

				if(len){
					if(sofar == len){
						RET(0);
					}else{
						/* TODO: goto retry */
						progress_incomplete();
						RET(1);
					}
				}else{
					/* no length, assume we have the whole file */
					RET(0);
				}
				/* unreachable */

			default:
			{
				int trunc = 0;

				if(len && sofar + nread > len){
					output_err(OUT_WARN, "too much data, truncating by %zu bytes", sofar + nread - len);
					trunc = 1;
					nread = len - sofar;
					sofar = len;
				}else{
					sofar += nread;
				}

				while(fwrite(buffer, sizeof(buffer[0]), nread, out) != (unsigned)nread){
					if(errno == EINTR)
						continue;
					output_perror("fwrite()");
					RET(1);
				}

				if(sofar == len)
					RET(0); /* don't wait for more, maybe be pipelining */

				chunk += nread;

				if(trunc)
					goto end_of_stream;
			}
		}

		t = mstime();
		if(last_progress + 250 < t){
			if(last_speed_calc + 1000 < t){
				long tdiff = t - last_speed_calc;

				if(tdiff){
					speed = 1000.0f /* kbps */ * (float)chunk / (float)tdiff;
					chunk = 0;
					last_speed_calc = t;
				}
			}

			last_progress = t;
			if(len)
				progress_show(sofar, len, speed);
			else
				progress_unknown(sofar, speed);
		}
	}while(1);

fin:
	if(len)
		progress_fin(sofar, len);
	else
		progress_fin(0, 0);

	if(closefd) {
		ret |= wget_close(finfo, out);
		if(ret)
			wget_failure(finfo);
		else
			wget_success(finfo);
	}

	return ret;
}
Esempio n. 13
0
static void bench_start(char *bench) {
    start_ = mstime();
    benchmark_ = bench;
    done_ = 0;
    next_report_ = 0;
}
Esempio n. 14
0
static int
slotsmgrt(redisClient *c, sds host, sds port, int fd, int dbid, int timeout, robj *keys[], robj *vals[], int n) {
    rio cmd;
    rioInitWithBuffer(&cmd, sdsempty());
    redisAssertWithInfo(c, NULL, rioWriteBulkCount(&cmd, '*', 2));
    redisAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "SELECT", 6));
    redisAssertWithInfo(c, NULL, rioWriteBulkLongLong(&cmd, dbid));

    redisAssertWithInfo(c, NULL, rioWriteBulkCount(&cmd, '*', 1 + 3 * n));
    redisAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "SLOTSRESTORE", 12));

    sds onekey = NULL;
    for (int i = 0; i < n; i ++) {
        robj *key = keys[i], *val = vals[i];
        long long ttl = 0, expireat = getExpire(c->db, key);
        if (expireat != -1) {
            ttl = expireat - mstime();
            if (ttl < 1) {
                ttl = 1;
            }
        }
        sds skey = key->ptr;
        redisAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, skey, sdslen(skey)));
        redisAssertWithInfo(c, NULL, rioWriteBulkLongLong(&cmd, ttl));
        do {
            rio pld;
            createDumpPayload(&pld, val);
            sds buf = pld.io.buffer.ptr;
            redisAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, buf, sdslen(buf)));
            sdsfree(buf);
        } while (0);
        if (onekey == NULL) {
            onekey = skey;
        }
    }

    do {
        sds buf = cmd.io.buffer.ptr;
        size_t pos = 0, towrite;
        int nwritten = 0;
        while ((towrite = sdslen(buf) - pos) > 0) {
            towrite = (towrite > (64 * 1024) ? (64 * 1024) : towrite);
            nwritten = syncWrite(fd, buf + pos, towrite, timeout);
            if (nwritten != (signed)towrite) {
                redisLog(REDIS_WARNING, "slotsmgrt: writing to target %s:%s, error '%s', "
                        "nkeys = %d, onekey = '%s', cmd.len = %ld, pos = %ld, towrite = %ld",
                        host, port, server.neterr, n, onekey, sdslen(buf), pos, towrite);
                addReplySds(c, sdsnew("-IOERR error or timeout writing to target\r\n"));
                sdsfree(buf);
                return -1;
            }
            pos += nwritten;
        }
        sdsfree(buf);
    } while (0);

    do {
        char buf1[1024];
        char buf2[1024];

        if (syncReadLine(fd, buf1, sizeof(buf1), timeout) <= 0 ||
                syncReadLine(fd, buf2, sizeof(buf2), timeout) <= 0) {
            redisLog(REDIS_WARNING, "slotsmgrt: reading from target %s:%s, error '%s', nkeys = %d, onekey = '%s'",
                    host, port, server.neterr, n, onekey);
            addReplySds(c, sdsnew("-IOERR error or timeout reading from target\r\n"));
            return -1;
        }
        if (buf1[0] == '-' || buf2[0] == '-') {
            redisLog(REDIS_WARNING, "slotsmgrt: response from target %s:%s: rsp1 = '%s', rsp2 = '%s', nkeys = %d, onekey = '%s'",
                    host, port, buf1, buf2, n, onekey);
            addReplyError(c, "error on slotsrestore");
            return -1;
        }
    } while (0);

    redisLog(REDIS_VERBOSE, "slotsmgrt: migrate to %s:%s, nkeys = %d, onekey = '%s'", host, port, n, onekey);
    return 0;
}
Esempio n. 15
0
static int show_throughput(ae_event_loop *el, long long id, void *priv) {
    float dt = (float)(mstime() - conf.start) / 1000.0;
    float rps = (float)conf.requests_finished / dt;
    printf("%s: %.2f\n", conf.title, rps);
    return 250; /* every 250ms */
}
Esempio n. 16
0
/* Main */
int
clusterMain (int argc, char **argv)
{
  long long teid;
  redisLog (REDIS_WARNING, "Server started, Redis version " REDIS_VERSION);
#ifdef __linux__
  linuxOvercommitMemoryWarning ();
#endif
  loadDataFromDisk ();
  server.last_bgsave_seqnum = server.smr_seqnum;

  /* Warning the user about suspicious maxmemory setting. */
  if (server.maxmemory > 0 && server.maxmemory < 1024 * 1024)
    {
      redisLog (REDIS_WARNING,
		"WARNING: You specified a maxmemory value that is less than 1MB (current value is %llu bytes). Are you sure this is what you really want?",
		server.maxmemory);
    }

  smrConnect ();

  /* initializeCron for handling sigterm */
  teid = aeCreateTimeEvent (server.el, 1, initializeCron, NULL, NULL);
  aeMain (server.el);
  aeDeleteTimeEvent (server.el, teid);

  if (server.need_rckpt)
    {
      redisLog (REDIS_NOTICE,
		"Need more checkpoint from %s:%d", server.ckpt_host,
		server.ckpt_port);
      smrDisconnect ();
      server.smr_init_flags = SMR_INIT_RCKPT;
      if (getdump
	  (server.ckpt_host, server.ckpt_port, server.rdb_filename,
	   "0-8191", REDIS_GETDUMP_DEFAULT_NET_LIMIT_MB) != REDIS_OK)
	{
	  exit (1);
	}

      emptyDb (NULL);
      loadDataFromDisk ();
      server.last_bgsave_seqnum = server.smr_seqnum;

      smrConnect ();
      aeMain (server.el);
    }

  if (!server.is_ready)
    {
      redisLog (REDIS_WARNING, "Invalid initialization state");
      exit (1);
    }

  if (server.last_bgsave_seqnum)
    {
      if (smr_seq_ckpted (server.smr_conn, server.last_bgsave_seqnum) != 0)
	{
	  redisLog (REDIS_WARNING,
		    "Failed to notify checkpointed sequence to smr");
	  exit (1);
	}
      else
	{
	  redisLog (REDIS_NOTICE,
		    "Checkpointed sequence is sent to SMR, seqnum:%lld",
		    server.last_bgsave_seqnum);
	}
    }

  server.smr_seqnum_reset = 0;
  server.last_catchup_check_mstime = mstime ();
  server.smr_init_flags = SMR_INIT_CATCHUP_PHASE1;
  if (smr_catchup (server.smr_conn) == -1)
    {
      redisLog (REDIS_WARNING, "Failed to catchup errno(%d)", errno);
      exit (1);
    }
  server.smr_init_flags = SMR_INIT_CATCHUP_PHASE2;
  checkSmrCatchup ();
  aeSetBeforeSleepProc (server.el, beforeSleep);
  aeMain (server.el);
  aeDeleteEventLoop (server.el);
  exit (0);
}
Esempio n. 17
0
int main(int argc, char* argv[])
{
	int startTime = mstime();
	DDS_PoolConstraints reqs;
	DDS_DomainParticipant    domainParticipant;
	DDS_Publisher    publisher;
	DDS_Subscriber    subscriber;
	DDS_ReturnCode_t retCode;
	char *configTopicName[nofConfigTopics];
	DDS_Topic configTopic[nofConfigTopics];
	DDS_Topic stateTopic[nofStateTopics];
	DDS_Topic statisticTopic[nofStatisticTopics];
	DDS_DataWriterQos dataWriterQos;
	DDS_DataWriter    configDataWriter[nofConfigTopics];
	DDS_DataWriter    stateDataWriter[nofStateTopics];
	DDS_DataWriter    statisticDataWriter[nofStatisticTopics];
	DDS_DataReaderQos dataReaderQos;
	DDS_DataReader    configDataReader[nofConfigTopics];
	acceptance_high_end_Config config;
	acceptance_high_end_State state;
	acceptance_high_end_Statistic statistic;
	DDS_InstanceHandle_t configInstance[nofConfigTopics][nofConfigInstances];
	DDS_InstanceHandle_t stateInstance[nofStateTopics][nofStateInstances];
	DDS_InstanceHandle_t statisticInstance[nofStatisticTopics][nofStatisticInstances];
	int i = 0;
	int j = 0;

	int firstConfigTopic = (argc > 1) ? atoi(argv[1]) : 0;
	int firstStateTopic = (argc > 2) ? atoi(argv[2]) : 0;
	int firstStatisticTopic = (argc > 3) ? atoi(argv[3]) : 0;
	int stagedLoading = (argc > 4) ? atoi(argv[4]) : 0;
	printf("[0] Config topics start at %d...\r\n", firstConfigTopic);
	printf("[0] State topics start at %d...\r\n", firstStateTopic);
	printf("[0] Statistic topics start at %d...\r\n", firstStatisticTopic);
	printf("[0] Staged loading %s.\r\n", stagedLoading ? "on" : "off");

	if (stagedLoading) {
		char file_name[24];
		sprintf(file_name, "/tmp/acceptStageLoad%d", firstConfigTopic);
		struct stat buf;
		if (stat(file_name, &buf)) {
			printf ("[%d] Waiting for %s\r\n", mstime() - startTime, file_name);
			do {
				sleep(1);
			}
			while (stat(file_name, &buf));
			printf ("[%d] Got %s!\r\n", mstime() - startTime, file_name);
		}
	}

        DDS_program_name (&argc, argv);
	DDS_entity_name ("Technicolor Limits Component");
	DDS_get_default_pool_constraints(&reqs, ~0, 100);
#ifdef MINIMAL_POOLS
	configure_minimal_pool_constraints (&reqs);
#else
	configure_optimal_pool_constraints (&reqs);
#endif
	DDS_set_pool_constraints(&reqs);

#ifdef DDS_DEBUG
	DDS_Debug_start ();
#endif

	/* Create domain participant... */
	domainParticipant = DDS_DomainParticipantFactory_create_participant(0, NULL, NULL, 0);
	if (!domainParticipant) {
		fprintf(stderr, "Error creating domain participant.\r\n");
		return -1;
	}
	printf("[%d] Created domain participant.\r\n", mstime() - startTime);
	sleep(1);

	/* Create publisher... */
	publisher = DDS_DomainParticipant_create_publisher(domainParticipant, NULL, NULL, 0);
	if (!publisher) {
		fprintf(stderr, "Error creating publisher.\r\n");
		return -1;
	}
	printf("[%d] Created publisher.\r\n", mstime() - startTime);
	sleep(1);

	/* Create subscriber... */
	subscriber = DDS_DomainParticipant_create_subscriber(domainParticipant, NULL, NULL, 0);
	if (!subscriber) {
		fprintf(stderr, "Error creating subscriber.\r\n");
		return -1;
	}
	printf("[%d] Created subscriber.\r\n", mstime() - startTime);
	sleep(1);

	/* Register types... */
	retCode = acceptance_high_end_ConfigTypeSupport_register_type(domainParticipant, NULL);
	if (retCode != DDS_RETCODE_OK) {
		fprintf(stderr, "Error registering type (%s).\r\n", DDS_error(retCode));
		return -1;
	}
	printf("[%d] Registered config type.\r\n", mstime() - startTime);
	retCode = acceptance_high_end_StateTypeSupport_register_type(domainParticipant, NULL);
	if (retCode != DDS_RETCODE_OK) {
		fprintf(stderr, "Error registering type (%s).\r\n", DDS_error(retCode));
		return -1;
	}
	printf("[%d] Registered state type.\r\n", mstime() - startTime);
	retCode = acceptance_high_end_StatisticTypeSupport_register_type(domainParticipant, NULL);
	if (retCode != DDS_RETCODE_OK) {
		fprintf(stderr, "Error registering type (%s).\r\n", DDS_error(retCode));
		return -1;
	}
	printf("[%d] Registered statistic type.\r\n", mstime() - startTime);
	sleep(1);

	/* Create topics... */
	for (i = 0; i < nofConfigTopics; i++) {
		char topicName[32];
		sprintf(topicName, "ConfigTopic%d", firstConfigTopic + i);
		configTopicName[i] = strdup (topicName);
		configTopic[i] = DDS_DomainParticipant_create_topic(domainParticipant, topicName, acceptance_high_end_ConfigTypeSupport_get_type_name(), NULL, NULL, 0);
		if (!configTopic[i]) {
			fprintf(stderr, "Error creating topic.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d config topics.\r\n", mstime() - startTime, nofConfigTopics);
	for (i = 0; i < nofStateTopics; i++) {
		char topicName[32];
		sprintf(topicName, "StateTopic%d", firstStateTopic + i);
		stateTopic[i] = DDS_DomainParticipant_create_topic(domainParticipant, topicName, acceptance_high_end_StateTypeSupport_get_type_name(), NULL, NULL, 0);
		if (!stateTopic[i]) {
			fprintf(stderr, "Error creating topic.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d state topics.\r\n", mstime() - startTime, nofStateTopics);
	for (i = 0; i < nofStatisticTopics; i++) {
		char topicName[32];
		sprintf(topicName, "StatisticTopic%d", firstStatisticTopic + i);
		statisticTopic[i] = DDS_DomainParticipant_create_topic(domainParticipant, topicName, acceptance_high_end_StatisticTypeSupport_get_type_name(), NULL, NULL, 0);
		if (!statisticTopic[i]) {
			fprintf(stderr, "Error creating topic.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d statistic topics.\r\n", mstime() - startTime, nofStatisticTopics);
	sleep(1);

	/* Create data writers... */
	DDS_Publisher_get_default_datawriter_qos(publisher, &dataWriterQos);
	dataWriterQos.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
	dataWriterQos.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS;
	for (i = 0; i < nofConfigTopics; i++) {
		configDataWriter[i] = DDS_Publisher_create_datawriter(publisher, configTopic[i], &dataWriterQos, NULL, 0);

		if (!configDataWriter[i]) {
			fprintf(stderr, "Error creating data writer.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d config data writers.\r\n", mstime() - startTime, nofConfigTopics);
	DDS_Publisher_get_default_datawriter_qos(publisher, &dataWriterQos);
	dataWriterQos.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
	dataWriterQos.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS;
	for (i = 0; i < nofStateTopics; i++) {
		stateDataWriter[i] = DDS_Publisher_create_datawriter(publisher, stateTopic[i], &dataWriterQos, NULL, 0);
		if (!stateDataWriter[i]) {
			fprintf(stderr, "Error creating data writer.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d state data writers.\r\n", mstime() - startTime, nofStateTopics);
	DDS_Publisher_get_default_datawriter_qos(publisher, &dataWriterQos);
	for (i = 0; i < nofStatisticTopics; i++) {
		statisticDataWriter[i] = DDS_Publisher_create_datawriter(publisher, statisticTopic[i], &dataWriterQos, NULL, 0);
		if (!statisticDataWriter[i]) {
			fprintf(stderr, "Error creating data writer.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d statistic data writers.\r\n", mstime() - startTime, nofStatisticTopics);
	sleep(1);

	/* Create data readers... */
	DDS_Subscriber_get_default_datareader_qos(subscriber, &dataReaderQos);
	dataReaderQos.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
	dataReaderQos.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS;
	for (i = 0; i < nofConfigTopics; i++) {
		configDataReader[i] = DDS_Subscriber_create_datareader(subscriber, DDS_DomainParticipant_lookup_topicdescription(domainParticipant, configTopicName[i]), &dataReaderQos, NULL, 0);
		if (!configDataReader[i]) {
			fprintf(stderr, "Error creating data reader.\r\n");
			return -1;
		}
	}
	printf("[%d] Created %d config data readers.\r\n", mstime() - startTime, nofConfigTopics);
	sleep(1);

	/* Register instances... */
	for (i = 0; i < nofConfigTopics; i++) {
		for (j = 0; j < nofConfigInstances; j++) {
			config.key = j;
			configInstance[i][j] = DDS_DataWriter_register_instance(configDataWriter[i], &config);
			if (!configInstance[i][j]) {
				fprintf(stderr, "Error registering instance.\r\n");
				break;
			}
		}
	}
	printf("[%d] Registered %d config instances.\r\n", mstime() - startTime, nofConfigTopics * nofConfigInstances);
	for (i = 0; i < nofStateTopics; i++) {
		for (j = 0; j < nofStateInstances; j++) {
			state.key = j;
			stateInstance[i][j] = DDS_DataWriter_register_instance(stateDataWriter[i], &state);
			if (!stateInstance[i][j]) {
				fprintf(stderr, "Error registering instance.\r\n");
				break;
			}
		}
	}
	printf("[%d] Registered %d state instances.\r\n", mstime() - startTime, nofStatisticTopics * nofStatisticInstances);
	for (i = 0; i < nofStatisticTopics; i++) {
		for (j = 0; j < nofStatisticInstances; j++) {
			statistic.key = j;
			statisticInstance[i][j] = DDS_DataWriter_register_instance(statisticDataWriter[i], &statistic);
			if (!statisticInstance[i][j]) {
				fprintf(stderr, "Error registering instance.\r\n");
				break;
			}
		}
	}
	printf("[%d] Registered %d statistic instances.\r\n", mstime() - startTime, nofStatisticTopics * nofStatisticInstances);
	sleep(1);

	/* Publish samples... */
	for (i = 0; i < nofConfigTopics; i++) {
		for (j = 0; j < nofConfigInstances; j++) {
			config.key = j;
			retCode = DDS_DataWriter_write(configDataWriter[i], &config, configInstance[i][j]);
			if (retCode != DDS_RETCODE_OK) {
				fprintf(stderr, "Error publishing sample (%s).\r\n", DDS_error(retCode));
				break;
			}
		}
	}
	printf("[%d] Published %d config samples.\r\n", mstime() - startTime, nofConfigTopics * nofConfigInstances);
	for (i = 0; i < nofStateTopics; i++) {
		for (j = 0; j < nofStateInstances; j++) {
			state.key = j;
			retCode = DDS_DataWriter_write(stateDataWriter[i], &state, stateInstance[i][j]);
			if (retCode != DDS_RETCODE_OK) {
				fprintf(stderr, "Error publishing sample (%s).\r\n", DDS_error(retCode));
				break;
			}
		}
	}
	printf("[%d] Published %d state samples.\r\n", mstime() - startTime, nofStateTopics * nofStateInstances);
	for (i = 0; i < nofStatisticTopics; i++) {
		for (j = 0; j < nofStatisticInstances; j++) {
			statistic.key = j;
			retCode = DDS_DataWriter_write(statisticDataWriter[i], &statistic, statisticInstance[i][j]);
			if (retCode != DDS_RETCODE_OK) {
				fprintf(stderr, "Error publishing sample (%s).\r\n", DDS_error(retCode));
				break;
			}
		}
	}
	printf("[%d] Published %d statistic samples.\r\n", mstime() - startTime, nofStatisticTopics * nofStatisticInstances);
	sleep(1);

	if (stagedLoading) {
		char file_name[24];
		sprintf(file_name, "/tmp/acceptStageLoad%d", firstConfigTopic + nofConfigTopics);
		FILE *f = fopen(file_name, "w");
		fclose(f);
	}

//	dbg_printf ("Zzzzzzz ... \r\n");
	sleep(TEST_TIME);
//	dbg_printf ("... o?\r\n");

	/* Delete contained entities... */
//	printf (" -- deleting contained entities.\r\n");
	retCode = DDS_DomainParticipant_delete_contained_entities(domainParticipant);
	if (retCode != DDS_RETCODE_OK) {
		fprintf(stderr, "Error deleting contained entities.\r\n");
		return -1;
	}

	for (i = 0; i < nofConfigTopics; i++)
		free (configTopicName[i]);

//	printf (" -- contained entities deleted!\r\n");
//	sleep(TEST_TIME);

	/* Delete domain participants... */
	retCode = DDS_DomainParticipantFactory_delete_participant(domainParticipant);
	if (retCode != DDS_RETCODE_OK) {
		fprintf(stderr, "Error deleting domain participant.\r\n");
		return -1;
	}

	printf ("[%d] comp completed successfully.\r\n", mstime() - startTime); 
	return 0;
}
Esempio n. 18
0
/* This is executed every second */
void countersCron(void) {
    int history_last_index;
    dictIterator *it;
    dictEntry *de;
    mstime_t now = mstime();

    history_last_index = server.history_index;
    server.history_index = (server.history_index + 1) % server.history_size;

    it = dictGetIterator(server.counters);
    while ((de = dictNext(it)) != NULL) {
        long double rvalue, elapsed, diff, change;
        counter *cntr;
        int miss;

        cntr = dictGetVal(de);

        counterPubSub(cntr, now);

        if (cntr->myshard == NULL) {
            continue;
        }

        change = counterHistoryChange(cntr, now, history_last_index);

        if (cntr->myshard->predict_time > 0) {
            miss = 0;

            /* When our shard doesn't change anymore we should make sure it's predicted value
             * matches the actual value otherwise we never have a mis-prediction and
             * other instances will keep using our wrongly predicted value */
            if (change == 0 && (cntr->myshard->predict_change != 0 || cntr->myshard->predict_value != cntr->myshard->value)) {
                miss = 1;

                serverLog(LL_DEBUG,"Counter %s needs a final prediction (%Lf != %Lf)",
                      cntr->name, cntr->myshard->predict_value, cntr->myshard->value);
            } else {
                elapsed = (now - cntr->myshard->predict_time);
                rvalue = cntr->myshard->predict_value + (elapsed * cntr->myshard->predict_change);
                diff = fabsl(rvalue - cntr->myshard->value);

                if (diff > cntr->precision) {
                    miss = 1;

                    serverLog(LL_DEBUG,"Counter %s needs new prediction (%Lf <= %f)",
                        cntr->name, diff, cntr->precision);
                }
            }

            if (miss == 0) {
                /* It's still up to date, check if we need to resend our last prediction. */
                counterMaybeResend(cntr);

                /* Only count hits for when something actually changed but
                 * is still within our last prediction. */
                if (cntr->history[history_last_index] != cntr->myshard->value) {
                    server.stat_hits++;
                    cntr->hits++;
                }

                counterHistoryUpdate(cntr);

                continue;
            }
        }

        /* Make a new prediction. */

        server.stat_misses++;
        cntr->misses++;
        cntr->revision++;

        counterPredict(cntr, now, change);
        clusterSendShard(cntr);

        counterHistoryUpdate(cntr);

        cntr->updated = mstime();
    }
    dictReleaseIterator(it);
}
Esempio n. 19
0
static void bench_stop(void) {
    long long stop_ = mstime();
    printf("%-12s : take %lld ms, %11.3f op/s\n", benchmark_, (stop_ - start_),
         config.num * 1000.0 / (stop_ - start_));
}
Esempio n. 20
0
/* Check the specified RDB file. Return 0 if the RDB looks sane, otherwise
 * 1 is returned. */
int redis_check_rdb(char *rdbfilename) {
    uint64_t dbid;
    int type, rdbver;
    char buf[1024];
    long long expiretime, now = mstime();
    FILE *fp;
    static rio rdb; /* Pointed by global struct riostate. */

    if ((fp = fopen(rdbfilename,"r")) == NULL) return 1;

    rioInitWithFile(&rdb,fp);
    rdbstate.rio = &rdb;
    rdb.update_cksum = rdbLoadProgressCallback;
    if (rioRead(&rdb,buf,9) == 0) goto eoferr;
    buf[9] = '\0';
    if (memcmp(buf,"REDIS",5) != 0) {
        rdbCheckError("Wrong signature trying to load DB from file");
        return 1;
    }
    rdbver = atoi(buf+5);
    if (rdbver < 1 || rdbver > RDB_VERSION) {
        rdbCheckError("Can't handle RDB format version %d",rdbver);
        return 1;
    }

    startLoading(fp);
    while(1) {
        robj *key, *val;
        expiretime = -1;

        /* Read type. */
        rdbstate.doing = RDB_CHECK_DOING_READ_TYPE;
        if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;

        /* Handle special types. */
        if (type == RDB_OPCODE_EXPIRETIME) {
            rdbstate.doing = RDB_CHECK_DOING_READ_EXPIRE;
            /* EXPIRETIME: load an expire associated with the next key
             * to load. Note that after loading an expire we need to
             * load the actual type, and continue. */
            if ((expiretime = rdbLoadTime(&rdb)) == -1) goto eoferr;
            /* We read the time so we need to read the object type again. */
            rdbstate.doing = RDB_CHECK_DOING_READ_TYPE;
            if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
            /* the EXPIRETIME opcode specifies time in seconds, so convert
             * into milliseconds. */
            expiretime *= 1000;
        } else if (type == RDB_OPCODE_EXPIRETIME_MS) {
            /* EXPIRETIME_MS: milliseconds precision expire times introduced
             * with RDB v3. Like EXPIRETIME but no with more precision. */
            rdbstate.doing = RDB_CHECK_DOING_READ_EXPIRE;
            if ((expiretime = rdbLoadMillisecondTime(&rdb)) == -1) goto eoferr;
            /* We read the time so we need to read the object type again. */
            rdbstate.doing = RDB_CHECK_DOING_READ_TYPE;
            if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
        } else if (type == RDB_OPCODE_EOF) {
            /* EOF: End of file, exit the main loop. */
            break;
        } else if (type == RDB_OPCODE_SELECTDB) {
            /* SELECTDB: Select the specified database. */
            rdbstate.doing = RDB_CHECK_DOING_READ_LEN;
            if ((dbid = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
                goto eoferr;
            rdbCheckInfo("Selecting DB ID %d", dbid);
            continue; /* Read type again. */
        } else if (type == RDB_OPCODE_RESIZEDB) {
            /* RESIZEDB: Hint about the size of the keys in the currently
             * selected data base, in order to avoid useless rehashing. */
            uint64_t db_size, expires_size;
            rdbstate.doing = RDB_CHECK_DOING_READ_LEN;
            if ((db_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
                goto eoferr;
            if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
                goto eoferr;
            continue; /* Read type again. */
        } else if (type == RDB_OPCODE_AUX) {
            /* AUX: generic string-string fields. Use to add state to RDB
             * which is backward compatible. Implementations of RDB loading
             * are requierd to skip AUX fields they don't understand.
             *
             * An AUX field is composed of two strings: key and value. */
            robj *auxkey, *auxval;
            rdbstate.doing = RDB_CHECK_DOING_READ_AUX;
            if ((auxkey = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;
            if ((auxval = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;

            rdbCheckInfo("AUX FIELD %s = '%s'",
                (char*)auxkey->ptr, (char*)auxval->ptr);
            decrRefCount(auxkey);
            decrRefCount(auxval);
            continue; /* Read type again. */
        } else {
            if (!rdbIsObjectType(type)) {
                rdbCheckError("Invalid object type: %d", type);
                return 1;
            }
            rdbstate.key_type = type;
        }

        /* Read key */
        rdbstate.doing = RDB_CHECK_DOING_READ_KEY;
        if ((key = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;
        rdbstate.key = key;
        rdbstate.keys++;
        /* Read value */
        rdbstate.doing = RDB_CHECK_DOING_READ_OBJECT_VALUE;
        if ((val = rdbLoadObject(type,&rdb)) == NULL) goto eoferr;
        /* Check if the key already expired. This function is used when loading
         * an RDB file from disk, either at startup, or when an RDB was
         * received from the master. In the latter case, the master is
         * responsible for key expiry. If we would expire keys here, the
         * snapshot taken by the master may not be reflected on the slave. */
        if (server.masterhost == NULL && expiretime != -1 && expiretime < now)
            rdbstate.already_expired++;
        if (expiretime != -1) rdbstate.expires++;
        rdbstate.key = NULL;
        decrRefCount(key);
        decrRefCount(val);
        rdbstate.key_type = -1;
    }
    /* Verify the checksum if RDB version is >= 5 */
    if (rdbver >= 5 && server.rdb_checksum) {
        uint64_t cksum, expected = rdb.cksum;

        rdbstate.doing = RDB_CHECK_DOING_CHECK_SUM;
        if (rioRead(&rdb,&cksum,8) == 0) goto eoferr;
        memrev64ifbe(&cksum);
        if (cksum == 0) {
            rdbCheckInfo("RDB file was saved with checksum disabled: no check performed.");
        } else if (cksum != expected) {
            rdbCheckError("RDB CRC error");
        } else {
            rdbCheckInfo("Checksum OK");
        }
    }

    fclose(fp);
    return 0;

eoferr: /* unexpected end of file is handled here with a fatal exit */
    if (rdbstate.error_set) {
        rdbCheckError(rdbstate.error);
    } else {
        rdbCheckError("Unexpected EOF reading RDB file");
    }
    return 1;
}
Esempio n. 21
0
/* Write a sequence of commands able to fully rebuild the dataset into
 * "filename". Used both by REWRITEAOF and BGREWRITEAOF.
 *
 * In order to minimize the number of commands needed in the rewritten
 * log Redis uses variadic commands when possible, such as RPUSH, SADD
 * and ZADD. However at max REDIS_AOF_REWRITE_ITEMS_PER_CMD items per time
 * are inserted using a single command. */
int rewriteAppendOnlyFile(char *filename) {
    dictIterator *di = NULL;
    dictEntry *de;
    rio aof;
    FILE *fp;
    char tmpfile[256];
    int j;
    long long now = mstime();

    /* Note that we have to use a different temp name here compared to the
     * one used by rewriteAppendOnlyFileBackground() function. */
    snprintf(tmpfile,256,"temp-rewriteaof-%d.aof", (int) getpid());
    fp = fopen(tmpfile,"w");
    if (!fp) {
        redisLog(REDIS_WARNING, "Opening the temp file for AOF rewrite in rewriteAppendOnlyFile(): %s", strerror(errno));
        return REDIS_ERR;
    }

    rioInitWithFile(&aof,fp);
    for (j = 0; j < server.dbnum; j++) {
        char selectcmd[] = "*2\r\n$6\r\nSELECT\r\n";
        redisDb *db = server.db+j;
        dict *d = db->dict;
        if (dictSize(d) == 0) continue;
        di = dictGetSafeIterator(d);
        if (!di) {
            fclose(fp);
            return REDIS_ERR;
        }

        /* SELECT the new DB */
        if (rioWrite(&aof,selectcmd,sizeof(selectcmd)-1) == 0) goto werr;
        if (rioWriteBulkLongLong(&aof,j) == 0) goto werr;

        /* Iterate this DB writing every entry */
        while((de = dictNext(di)) != NULL) {
            sds keystr;
            robj key, *o;
            long long expiretime;

            keystr = dictGetKey(de);
            o = dictGetVal(de);
            initStaticStringObject(key,keystr);

            expiretime = getExpire(db,&key);

            /* Save the key and associated value */
            if (o->type == REDIS_STRING) {
                /* Emit a SET command */
                char cmd[]="*3\r\n$3\r\nSET\r\n";
                if (rioWrite(&aof,cmd,sizeof(cmd)-1) == 0) goto werr;
                /* Key and value */
                if (rioWriteBulkObject(&aof,&key) == 0) goto werr;
                if (rioWriteBulkObject(&aof,o) == 0) goto werr;
            } else if (o->type == REDIS_LIST) {
                if (rewriteListObject(&aof,&key,o) == 0) goto werr;
            } else if (o->type == REDIS_SET) {
                if (rewriteSetObject(&aof,&key,o) == 0) goto werr;
            } else if (o->type == REDIS_ZSET) {
                if (rewriteSortedSetObject(&aof,&key,o) == 0) goto werr;
            } else if (o->type == REDIS_HASH) {
                if (rewriteHashObject(&aof,&key,o) == 0) goto werr;
            } else {
                redisPanic("Unknown object type");
            }
            /* Save the expire time */
            if (expiretime != -1) {
                char cmd[]="*3\r\n$9\r\nPEXPIREAT\r\n";
                /* If this key is already expired skip it */
                if (expiretime < now) continue;
                if (rioWrite(&aof,cmd,sizeof(cmd)-1) == 0) goto werr;
                if (rioWriteBulkObject(&aof,&key) == 0) goto werr;
                if (rioWriteBulkLongLong(&aof,expiretime) == 0) goto werr;
            }
        }
        dictReleaseIterator(di);
    }

    /* Make sure data will not remain on the OS's output buffers */
    fflush(fp);
    aof_fsync(fileno(fp));
    fclose(fp);

    /* Use RENAME to make sure the DB file is changed atomically only
     * if the generate DB file is ok. */
    if (rename(tmpfile,filename) == -1) {
        redisLog(REDIS_WARNING,"Error moving temp append only file on the final destination: %s", strerror(errno));
        unlink(tmpfile);
        return REDIS_ERR;
    }
    redisLog(REDIS_NOTICE,"SYNC append only file rewrite performed");
    return REDIS_OK;

werr:
    fclose(fp);
    unlink(tmpfile);
    redisLog(REDIS_WARNING,"Write error writing append only file on disk: %s", strerror(errno));
    if (di) dictReleaseIterator(di);
    return REDIS_ERR;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Loads matrix data. on exit, augM will contain the augmented matrix rows associated to this node.
void loadMatrix(const char* inputFile, double* localRows, float* ddtime)
{
	// Record data distribution time on head node
	double ddstartTime = 0;
	if(PID == 0) ddstartTime = mstime();
	
	// Non-distributed read: root node reads data and scatters it to all nodes.
	if(DISTRIBUTE_READ == 0)
	{
		double* augM = malloc(N * (N + 1) * sizeof(double));
		double* cyclicM = malloc(N * (N + 1) * sizeof(double));
		//printf("HERE\n");
		if(PID == 0)
		{
			int nelems = 0;
			// Load the file in the array.
			FILE* in = fopen(inputFile, "rb");
			if(in != NULL)
			{
				while(!feof(in))
				{
					char intString[20];
					fgets(intString, 13, in);
					augM[nelems] = atof(intString);
					nelems++;
					//printf("read %d\n", nelems - 1);
				}
				fclose(in);
				
				printf("File read: nelems = %d\n", nelems - 1);
			}
			else
			{
				printf("FATAL: Could not open file %s\n", inputFile);
			}
			// Reorganize the matrix rows depending on block-cyclic factor R.
			createCyclicMatrix(augM, cyclicM);
		}
		int scatterSize = RPP * (N + 1);
		MPI_Scatter(cyclicM, scatterSize, MPI_DOUBLE, localRows, scatterSize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
		//free(augM);
		//free(cyclicM);
	}
	else
	{
		int nelems = 0;
		// Load the file in the array.
		FILE* in = fopen(inputFile, "rb");
		if(in != NULL)
		{
			// Loop through row indices. If the row is assigned to this processor, read it.
			int i;
			for(i = 0; i < N; i++)
			{
				if(getRowPID(i) == PID)
				{
					// The row belongs to this processor. Compute the row offset.
					int rowSize = 12 * (N + 1);
					int offset = rowSize * i;
					fseek(in, offset, SEEK_SET);
					
					// Now read the row.
					int j;
					for(j = 0; j < N + 1; j++)
					{
						if(feof(in))
						{
							printf("FATAL: unexpected end of file in %s\n", inputFile);
							exit(-1);
						}
						char intString[20];
						fgets(intString, 13, in);
						localRows[nelems] = atof(intString);
						nelems++;
					}
				}
			}
			fclose(in);
			
			printf("File read: nelems = %d\n", nelems - 1);
		}
		else
		{
			printf("FATAL: Could not open file %s\n", inputFile);
		}
	}
	
	*ddtime = mstime() - ddstartTime;
}
Esempio n. 23
0
//
//=========================================================================
//
// This function is called a few times every second by main in order to
// perform tasks we need to do continuously, like accepting new clients
// from the net, refreshing the screen in interactive mode, and so forth
//
void backgroundTasks(void) {
    static uint64_t next_stats_display;
    static uint64_t next_stats_update;
    static uint64_t next_json, next_history;

    uint64_t now = mstime();

    icaoFilterExpire();
    trackPeriodicUpdate();

    if (Modes.net) {
	modesNetPeriodicWork();
    }    


    // Refresh screen when in interactive mode
    if (Modes.interactive) {
        interactiveShowData();
    }

    // always update end time so it is current when requests arrive
    Modes.stats_current.end = now;

    if (now >= next_stats_update) {
        int i;

        if (next_stats_update == 0) {
            next_stats_update = now + 60000;
        } else {
            Modes.stats_latest_1min = (Modes.stats_latest_1min + 1) % 15;
            Modes.stats_1min[Modes.stats_latest_1min] = Modes.stats_current;
            
            add_stats(&Modes.stats_current, &Modes.stats_alltime, &Modes.stats_alltime);
            add_stats(&Modes.stats_current, &Modes.stats_periodic, &Modes.stats_periodic);
            
            reset_stats(&Modes.stats_5min);
            for (i = 0; i < 5; ++i)
                add_stats(&Modes.stats_1min[(Modes.stats_latest_1min - i + 15) % 15], &Modes.stats_5min, &Modes.stats_5min);
            
            reset_stats(&Modes.stats_15min);
            for (i = 0; i < 15; ++i)
                add_stats(&Modes.stats_1min[i], &Modes.stats_15min, &Modes.stats_15min);
            
            reset_stats(&Modes.stats_current);
            Modes.stats_current.start = Modes.stats_current.end = now;
            
            if (Modes.json_dir)
                writeJsonToFile("stats.json", generateStatsJson);

            next_stats_update += 60000;
        }
    }

    if (Modes.stats && now >= next_stats_display) {
        if (next_stats_display == 0) {
            next_stats_display = now + Modes.stats;
        } else {
            add_stats(&Modes.stats_periodic, &Modes.stats_current, &Modes.stats_periodic);
            display_stats(&Modes.stats_periodic);
            reset_stats(&Modes.stats_periodic);

            next_stats_display += Modes.stats;
        }
    }

    if (Modes.json_dir && now >= next_json) {
        writeJsonToFile("aircraft.json", generateAircraftJson);
        next_json = now + Modes.json_interval;
    }

    if ((Modes.json_dir || Modes.net_http_port) && now >= next_history) {
        int rewrite_receiver_json = (Modes.json_aircraft_history[HISTORY_SIZE-1].content == NULL);

        free(Modes.json_aircraft_history[Modes.json_aircraft_history_next].content); // might be NULL, that's OK.
        Modes.json_aircraft_history[Modes.json_aircraft_history_next].content =
            generateAircraftJson("/data/aircraft.json", &Modes.json_aircraft_history[Modes.json_aircraft_history_next].clen);

        if (Modes.json_dir) {
            char filebuf[PATH_MAX];
            snprintf(filebuf, PATH_MAX, "history_%d.json", Modes.json_aircraft_history_next);
            writeJsonToFile(filebuf, generateHistoryJson);
        }

        Modes.json_aircraft_history_next = (Modes.json_aircraft_history_next+1) % HISTORY_SIZE;

        if (rewrite_receiver_json)
            writeJsonToFile("receiver.json", generateReceiverJson); // number of history entries changed

        next_history = now + HISTORY_INTERVAL;
    }
}
void pivot(double* localRows, double* pivotRow, int j, int jpid, int* localRowIds, float* pvtime)
{
	// Record time on head node
	double pvstartTime = 0;
	if(PID == 0) pvstartTime = mstime();

	// Compute local absolute maximum of jth column, for pivot finding.
	int i;
	double maxjelem = 0;
	int maxji = -1;
	for(i = 0; i < RPP; i++)
	{
		double* rowi = &localRows[i * (N + 1)];
		double aej = abs(rowi[j]);
		//printf("NODE %d row%d[%d] = %f\n", PID, i, j, aej);
		if(aej >= maxjelem && localRowIds[i] >= j) 
		{
			maxjelem = aej;
			maxji = i;
			//printf("NODE %d maxji = %d\n", PID, maxji);
		}
	}
	
	// Gather local maximums and rows on first node.
	double gm = 0;
	int gmpid = -1;
	double localMaximums[MAX_P];
	int localMaxRows[MAX_P];
	MPI_Gather(&maxjelem, 1, MPI_DOUBLE, localMaximums, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Gather(&maxji, 1, MPI_INT, localMaxRows, 1, MPI_INT, 0, MPI_COMM_WORLD);
				
	if(PID == 0)
	{
		// Find global maximum
		for(i = 0; i < P; i++)
		{
			if(localMaximums[i] > gm && localMaxRows[i] != -1)
			{
				//printf("GLOBAL (%d)%f > (%d)%f\n", i, localMaximums[i], gmpid, gm);
				gm = localMaximums[i];
				gmpid = i;
			}
		}
	}
	
	// Broadcast the global colum maximum and column owner node to all nodes.
	MPI_Bcast(&gm, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Bcast(&gmpid, 1, MPI_INT, 0, MPI_COMM_WORLD);
	
	// Exchange rows.
	// Special case: pivot and maximum row are on the same node
	if(gmpid == jpid && jpid == PID)
	{
		// If the maximum row is already the current pivot, there is nothing we need to do.
		if(j != localRowIds[maxji])
		{
			double tmp[MAX_N];
			memcpy(tmp, &localRows[maxji * (N + 1)], (N + 1) * sizeof(double));
			memcpy(&localRows[maxji * (N + 1)], pivotRow, (N + 1) * sizeof(double));
			memcpy(pivotRow, tmp, (N + 1) * sizeof(double));
		}
	}
	else
	{
		MPI_Status status;
		// Normal case: send / receive rows.
		if(gmpid == PID)
		{
			double tmp[MAX_N];
			MPI_Send(&localRows[maxji * (N + 1)], N + 1, MPI_DOUBLE, jpid, 0, MPI_COMM_WORLD);
			MPI_Recv(tmp, N + 1, MPI_DOUBLE, jpid, 0, MPI_COMM_WORLD, &status);
			memcpy(&localRows[maxji * (N + 1)], tmp, (N + 1) * sizeof(double));
			//printf("NODE %d SENT MAX ROW %d TO %d\n", PID, maxji, jpid);
		}
		else if(jpid == PID)
		{
			double tmp[MAX_N];
			MPI_Recv(tmp, N + 1, MPI_DOUBLE, gmpid, 0, MPI_COMM_WORLD, &status);
			MPI_Send(pivotRow, N + 1, MPI_DOUBLE, gmpid, 0, MPI_COMM_WORLD);
			memcpy(pivotRow, tmp, (N + 1) * sizeof(double));
			//printf("NODE %d RECVD MAX ROW FOR PIVOT %d FROm %d\n", PID, j, gmpid);
		}
	}
	
	// NOTE: pivot time accumulates, since we run this function for each row.
	if(PID == 0) *pvtime += (mstime() - pvstartTime); 
}
Esempio n. 25
0
void expireCommand(client *c) {
    expireGenericCommand(c,mstime(),UNIT_SECONDS);
}
Esempio n. 26
0
File: evict.c Progetto: Xwuming/misc
/* Return the LRU clock, based on the clock resolution. This is a time
 * in a reduced-bits format that can be used to set and check the
 * object->lru field of redisObject structures. */
unsigned int getLRUClock(void) {
    return (mstime()/LRU_CLOCK_RESOLUTION) & LRU_CLOCK_MAX;
}
Esempio n. 27
0
//
//=========================================================================
//
// Show the currently captured interactive data on screen.
//
void interactiveShowData(void) {
    struct aircraft *a = Modes.aircrafts;
    static uint64_t next_update;
    uint64_t now = mstime();
    int count = 0;
    char progress;
    char spinner[4] = "|/-\\";

    // Refresh screen every (MODES_INTERACTIVE_REFRESH_TIME) miliseconde
    if (now < next_update)
        return;

    next_update = now + MODES_INTERACTIVE_REFRESH_TIME;

    progress = spinner[(now/1000)%4];

#ifndef _WIN32
    printf("\x1b[H\x1b[2J");    // Clear the screen
#else
    cls();
#endif

    if (Modes.interactive_rtl1090 == 0) {
        printf (
" Hex    Mode  Sqwk  Flight   Alt    Spd  Hdg    Lat      Long   RSSI  Msgs  Ti%c\n", progress);
    } else {
        printf (
" Hex   Flight   Alt      V/S GS  TT  SSR  G*456^ Msgs    Seen %c\n", progress);
    }
    printf(
"-------------------------------------------------------------------------------\n");

    while(a && (count < Modes.interactive_rows)) {

        if ((now - a->seen) < Modes.interactive_display_ttl)
            {
            int msgs  = a->messages;
            int flags = a->modeACflags;

            if ( (((flags & (MODEAC_MSG_FLAG                             )) == 0                    ) && (msgs > 1  ) )
              || (((flags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEA_ONLY)) == MODEAC_MSG_MODEA_ONLY) && (msgs > 4  ) ) 
              || (((flags & (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD )) == 0                    ) && (msgs > 127) ) 
              ) {
                char strSquawk[5] = " ";
                char strFl[7]     = " ";
                char strTt[5]     = " ";
                char strGs[5]     = " ";

                if (trackDataValid(&a->squawk_valid)) {
                    snprintf(strSquawk,5,"%04x", a->squawk);
                }

                if (trackDataValid(&a->speed_valid)) {
                    snprintf (strGs, 5,"%3d", convert_speed(a->speed));
                }

                if (trackDataValid(&a->heading_valid)) {
                    snprintf (strTt, 5,"%03d", a->heading);
                }

                if (msgs > 99999) {
                    msgs = 99999;
                }

                if (Modes.interactive_rtl1090) { // RTL1090 display mode
                    if (trackDataValid(&a->altitude_valid)) {
                        snprintf(strFl,6,"F%03d",((a->altitude+50)/100));
                    }
                    printf("%06x %-8s %-4s         %-3s %-3s %4s        %-6d  %-2.0f\n", 
                           a->addr, a->callsign, strFl, strGs, strTt, strSquawk, msgs, (now - a->seen)/1000.0);

                } else {                         // Dump1090 display mode
                    char strMode[5]               = "    ";
                    char strLat[8]                = " ";
                    char strLon[9]                = " ";
                    double * pSig                 = a->signalLevel;
                    double signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] + 
                                            pSig[4] + pSig[5] + pSig[6] + pSig[7]) / 8.0; 

                    if ((flags & MODEAC_MSG_FLAG) == 0) {
                        strMode[0] = 'S';
                    } else if (flags & MODEAC_MSG_MODEA_ONLY) {
                        strMode[0] = 'A';
                    }
                    if (flags & MODEAC_MSG_MODEA_HIT) {strMode[2] = 'a';}
                    if (flags & MODEAC_MSG_MODEC_HIT) {strMode[3] = 'c';}

                    if (trackDataValid(&a->position_valid)) {
                        snprintf(strLat, 8,"%7.03f", a->lat);
                        snprintf(strLon, 9,"%8.03f", a->lon);
                    }

                    if (trackDataValid(&a->airground_valid) && a->airground == AG_GROUND) {
                        snprintf(strFl, 7," grnd");
                    } else if (Modes.use_gnss && trackDataValid(&a->altitude_gnss_valid)) {
                        snprintf(strFl, 7, "%5dH", convert_altitude(a->altitude_gnss));
                    } else if (trackDataValid(&a->altitude_valid)) {
                        snprintf(strFl, 7, "%5d ", convert_altitude(a->altitude));
                    }

                    printf("%s%06X %-4s  %-4s  %-8s %6s %3s  %3s  %7s %8s %5.1f %5d %2.0f\n",
                           (a->addr & MODES_NON_ICAO_ADDRESS) ? "~" : " ", (a->addr & 0xffffff),
                           strMode, strSquawk, a->callsign, strFl, strGs, strTt,
                           strLat, strLon, 10 * log10(signalAverage), msgs, (now - a->seen)/1000.0);
                }
                count++;
            }
        }
        a = a->next;
    }
}
Esempio n. 28
0
void interactiveShowData(void) {
    struct aircraft *a = Modes.aircrafts;
    static uint64_t next_update;
    uint64_t now = mstime();
    char progress;
    char spinner[4] = "|/-\\";

    // Refresh screen every (MODES_INTERACTIVE_REFRESH_TIME) miliseconde
    if (now < next_update)
        return;

    next_update = now + MODES_INTERACTIVE_REFRESH_TIME;

    progress = spinner[(now/1000)%4];
    mvaddch(0, 79, progress);

    int rows = getmaxy(stdscr);
    int row = 2;

    while (a && row < rows) {

        if ((now - a->seen) < Modes.interactive_display_ttl)
            {
            int msgs  = a->messages;

            if (msgs > 1) {
                char strSquawk[5] = " ";
                char strFl[7]     = " ";
                char strTt[5]     = " ";
                char strGs[5]     = " ";

                if (trackDataValid(&a->squawk_valid)) {
                    snprintf(strSquawk,5,"%04x", a->squawk);
                }

                if (trackDataValid(&a->gs_valid)) {
                    snprintf (strGs, 5,"%3d", convert_speed(a->gs));
                }

                if (trackDataValid(&a->track_valid)) {
                    snprintf (strTt, 5,"%03.0f", a->track);
                }

                if (msgs > 99999) {
                    msgs = 99999;
                }

                char strMode[5]               = "    ";
                char strLat[8]                = " ";
                char strLon[9]                = " ";
                double * pSig                 = a->signalLevel;
                double signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] +
                                        pSig[4] + pSig[5] + pSig[6] + pSig[7]) / 8.0;

                strMode[0] = 'S';
                if (a->modeA_hit) {strMode[2] = 'a';}
                if (a->modeC_hit) {strMode[3] = 'c';}

                if (trackDataValid(&a->position_valid)) {
                    snprintf(strLat, 8,"%7.03f", a->lat);
                    snprintf(strLon, 9,"%8.03f", a->lon);
                }

                if (trackDataValid(&a->airground_valid) && a->airground == AG_GROUND) {
                    snprintf(strFl, 7," grnd");
                } else if (Modes.use_gnss && trackDataValid(&a->altitude_geom_valid)) {
                    snprintf(strFl, 7, "%5dH", convert_altitude(a->altitude_geom));
                } else if (trackDataValid(&a->altitude_baro_valid)) {
                    snprintf(strFl, 7, "%5d ", convert_altitude(a->altitude_baro));
                }

                mvprintw(row, 0, "%s%06X %-4s  %-4s  %-8s %6s %3s  %3s  %7s %8s %5.1f %5d %2.0f",
                         (a->addr & MODES_NON_ICAO_ADDRESS) ? "~" : " ", (a->addr & 0xffffff),
                         strMode, strSquawk, a->callsign, strFl, strGs, strTt,
                         strLat, strLon, 10 * log10(signalAverage), msgs, (now - a->seen)/1000.0);
                ++row;
            }
        }
        a = a->next;
    }

    if (Modes.mode_ac) {
        for (unsigned i = 1; i < 4096 && row < rows; ++i) {
            if (modeAC_match[i] || modeAC_count[i] < 50 || modeAC_age[i] > 5)
                continue;

            char strMode[5] = "  A ";
            char strFl[7] = " ";
            unsigned modeA = indexToModeA(i);
            int modeC = modeAToModeC(modeA);
            if (modeC != INVALID_ALTITUDE) {
                strMode[3] = 'C';
                snprintf(strFl, 7, "%5d ", convert_altitude(modeC * 100));
            }

            mvprintw(row, 0,
                     "%7s %-4s  %04x  %-8s %6s %3s  %3s  %7s %8s %5s %5d %2d\n",
                     "",    /* address */
                     strMode, /* mode */
                     modeA, /* squawk */
                     "",    /* callsign */
                     strFl, /* altitude */
                     "",    /* gs */
                     "",    /* heading */
                     "",    /* lat */
                     "",    /* lon */
                     "",    /* signal */
                     modeAC_count[i], /* messages */
                     modeAC_age[i]);  /* age */
            ++row;
        }
    }

    move(row, 0);
    clrtobot();
    refresh();
}
Esempio n. 29
0
void evalGenericCommand(redisClient *c, int evalsha) {
    lua_State *lua = server.lua;
    char funcname[43];
    long long numkeys;
    int delhook = 0, err;

    /* We want the same PRNG sequence at every call so that our PRNG is
     * not affected by external state. */
    redisSrand48(0);

    /* We set this flag to zero to remember that so far no random command
     * was called. This way we can allow the user to call commands like
     * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
     * is called (otherwise the replication and AOF would end with non
     * deterministic sequences).
     *
     * Thanks to this flag we'll raise an error every time a write command
     * is called after a random command was used. */
    server.lua_random_dirty = 0;
    server.lua_write_dirty = 0;

    /* Get the number of arguments that are keys */
    if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
        return;
    if (numkeys > (c->argc - 3)) {
        addReplyError(c,"Number of keys can't be greater than number of args");
        return;
    }

    /* We obtain the script SHA1, then check if this function is already
     * defined into the Lua state */
    funcname[0] = 'f';
    funcname[1] = '_';
    if (!evalsha) {
        /* Hash the code if this is an EVAL call */
        sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
    } else {
        /* We already have the SHA if it is a EVALSHA */
        int j;
        char *sha = c->argv[1]->ptr;

        for (j = 0; j < 40; j++)
            funcname[j+2] = tolower(sha[j]);
        funcname[42] = '\0';
    }

    /* Push the pcall error handler function on the stack. */
    lua_getglobal(lua, "__redis__err__handler");

    /* Try to lookup the Lua function */
    lua_getglobal(lua, funcname);
    if (lua_isnil(lua,-1)) {
        lua_pop(lua,1); /* remove the nil from the stack */
        /* Function not defined... let's define it if we have the
         * body of the function. If this is an EVALSHA call we can just
         * return an error. */
        if (evalsha) {
            lua_pop(lua,1); /* remove the error handler from the stack. */
            addReply(c, shared.noscripterr);
            return;
        }
        if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) {
            lua_pop(lua,1); /* remove the error handler from the stack. */
            /* The error is sent to the client by luaCreateFunction()
             * itself when it returns REDIS_ERR. */
            return;
        }
        /* Now the following is guaranteed to return non nil */
        lua_getglobal(lua, funcname);
        redisAssert(!lua_isnil(lua,-1));
    }

    /* Populate the argv and keys table accordingly to the arguments that
     * EVAL received. */
    luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
    luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);

    /* Select the right DB in the context of the Lua client */
    selectDb(server.lua_client,c->db->id);
    
    /* Set a hook in order to be able to stop the script execution if it
     * is running for too much time.
     * We set the hook only if the time limit is enabled as the hook will
     * make the Lua script execution slower. */
    server.lua_caller = c;
    server.lua_time_start = mstime();
    server.lua_kill = 0;
    if (server.lua_time_limit > 0 && server.masterhost == NULL) {
        lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
        delhook = 1;
    }

    /* At this point whether this script was never seen before or if it was
     * already defined, we can call it. We have zero arguments and expect
     * a single return value. */
    err = lua_pcall(lua,0,1,-2);

    /* Perform some cleanup that we need to do both on error and success. */
    if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
    if (server.lua_timedout) {
        server.lua_timedout = 0;
        /* Restore the readable handler that was unregistered when the
         * script timeout was detected. */
        aeCreateFileEvent(server.el,c->fd,AE_READABLE,
                          readQueryFromClient,c);
    }
    server.lua_caller = NULL;
    selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
    lua_gc(lua,LUA_GCSTEP,1);

    if (err) {
        addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
            funcname, lua_tostring(lua,-1));
        lua_pop(lua,2); /* Consume the Lua reply and remove error handler. */
    } else {
        /* On success convert the Lua return value into Redis protocol, and
         * send it to * the client. */
        luaReplyToRedisReply(c,lua); /* Convert and consume the reply. */
        lua_pop(lua,1); /* Remove the error handler. */
    }

    /* EVALSHA should be propagated to Slave and AOF file as full EVAL, unless
     * we are sure that the script was already in the context of all the
     * attached slaves *and* the current AOF file if enabled.
     *
     * To do so we use a cache of SHA1s of scripts that we already propagated
     * as full EVAL, that's called the Replication Script Cache.
     *
     * For repliation, everytime a new slave attaches to the master, we need to
     * flush our cache of scripts that can be replicated as EVALSHA, while
     * for AOF we need to do so every time we rewrite the AOF file. */
    if (evalsha) {
        if (!replicationScriptCacheExists(c->argv[1]->ptr)) {
            /* This script is not in our script cache, replicate it as
             * EVAL, then add it into the script cache, as from now on
             * slaves and AOF know about it. */
            robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);

            replicationScriptCacheAdd(c->argv[1]->ptr);
            redisAssertWithInfo(c,NULL,script != NULL);
            rewriteClientCommandArgument(c,0,
                resetRefCount(createStringObject("EVAL",4)));
            rewriteClientCommandArgument(c,1,script);
            forceCommandPropagation(c,REDIS_PROPAGATE_REPL|REDIS_PROPAGATE_AOF);
        }
    }
}
Esempio n. 30
0
void ifileRun()
{
    if (ifile.fd < 0)
        return;

    int eof = 0;
    struct timespec next_buffer_delivery;

    struct timespec thread_cpu;
    start_cpu_timing(&thread_cpu);

    uint64_t sampleCounter = 0;

    clock_gettime(CLOCK_MONOTONIC, &next_buffer_delivery);

    pthread_mutex_lock(&Modes.data_mutex);
    while (!Modes.exit && !eof) {
        ssize_t nread, toread;
        void *r;
        struct mag_buf *outbuf, *lastbuf;
        unsigned next_free_buffer;
        unsigned slen;

        next_free_buffer = (Modes.first_free_buffer + 1) % MODES_MAG_BUFFERS;
        if (next_free_buffer == Modes.first_filled_buffer) {
            // no space for output yet
            pthread_cond_wait(&Modes.data_cond, &Modes.data_mutex);
            continue;
        }

        outbuf = &Modes.mag_buffers[Modes.first_free_buffer];
        lastbuf = &Modes.mag_buffers[(Modes.first_free_buffer + MODES_MAG_BUFFERS - 1) % MODES_MAG_BUFFERS];
        pthread_mutex_unlock(&Modes.data_mutex);

        // Compute the sample timestamp for the start of the block
        outbuf->sampleTimestamp = sampleCounter * 12e6 / Modes.sample_rate;
        sampleCounter += MODES_MAG_BUF_SAMPLES;

        // Copy trailing data from last block (or reset if not valid)
        if (lastbuf->length >= Modes.trailing_samples) {
            memcpy(outbuf->data, lastbuf->data + lastbuf->length, Modes.trailing_samples * sizeof(uint16_t));
        } else {
            memset(outbuf->data, 0, Modes.trailing_samples * sizeof(uint16_t));
        }

        // Get the system time for the start of this block
        outbuf->sysTimestamp = mstime();

        toread = MODES_MAG_BUF_SAMPLES * ifile.bytes_per_sample;
        r = ifile.readbuf;
        while (toread) {
            nread = read(ifile.fd, r, toread);
            if (nread <= 0) {
                if (nread < 0) {
                    fprintf(stderr, "ifile: error reading input file: %s\n", strerror(errno));
                }
                // Done.
                eof = 1;
                break;
            }
            r += nread;
            toread -= nread;
        }

        slen = outbuf->length = MODES_MAG_BUF_SAMPLES - toread / ifile.bytes_per_sample;

        // Convert the new data
        ifile.converter(ifile.readbuf, &outbuf->data[Modes.trailing_samples], slen, ifile.converter_state, &outbuf->mean_level, &outbuf->mean_power);

        if (ifile.throttle || Modes.interactive) {
            // Wait until we are allowed to release this buffer to the main thread
            while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_buffer_delivery, NULL) == EINTR)
                ;

            // compute the time we can deliver the next buffer.
            next_buffer_delivery.tv_nsec += outbuf->length * 1e9 / Modes.sample_rate;
            normalize_timespec(&next_buffer_delivery);
        }

        // Push the new data to the main thread
        pthread_mutex_lock(&Modes.data_mutex);
        Modes.first_free_buffer = next_free_buffer;
        // accumulate CPU while holding the mutex, and restart measurement
        end_cpu_timing(&thread_cpu, &Modes.reader_cpu_accumulator);
        start_cpu_timing(&thread_cpu);
        pthread_cond_signal(&Modes.data_cond);
    }

    // Wait for the main thread to consume all data
    while (!Modes.exit && Modes.first_filled_buffer != Modes.first_free_buffer)
        pthread_cond_wait(&Modes.data_cond, &Modes.data_mutex);

    pthread_mutex_unlock(&Modes.data_mutex);
}