flag_beamsave_thread_bin.c 3.58 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
/* flag_beamsave_thread.c
 *
 * Routine to save total power outputs to file for data verification
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>

#include "hashpipe.h"
#include "flag_databuf.h"
#include <xgpu.h>
// #include "total_power.h"

// Create thread status buffer
static hashpipe_status_t * st_p;

// Run method for the thread
static void * run(hashpipe_thread_args_t * args) {

    // Local aliases to shorten access to args fields
    flag_gpu_beamformer_output_databuf_t * db_in = (flag_gpu_beamformer_output_databuf_t  *)args->ibuf;
    hashpipe_status_t st = args->st;
    const char * status_key = args->thread_desc->skey;

    st_p = &st; // allow global (this source file) access to the status buffer

    //int instance_id = args[0].instance_id;
    char data_dir[128];
    hashpipe_status_lock_safe(&st);
    hgets(st.buf, "DATADIR", 127, data_dir);
    hashpipe_status_unlock_safe(&st);
    if (data_dir == NULL) {
        printf("SAV: DATADIR = .\n");
    }
    else {
        printf("SAV: DATADIR = %s\n", data_dir);
    }

    // Mark thread as ready to run
    hashpipe_status_lock_safe(&st);
    hputi4(st.buf, "SAVEREADY", 1);
    hashpipe_status_unlock_safe(&st);

    int rv;
    int curblock_in = 0;
    while (run_threads()) {
        
        // Wait for input buffer block to be filled
        while ((rv=flag_gpu_beamformer_output_databuf_wait_filled(db_in, curblock_in)) != HASHPIPE_OK) {
            if (rv==HASHPIPE_TIMEOUT) {
                hashpipe_status_lock_safe(&st);
                hputs(st.buf, status_key, "waiting for free block");
                hashpipe_status_unlock_safe(&st);
            }
            else {
                hashpipe_error(__FUNCTION__, "error waiting for filled databuf block");
                pthread_exit(NULL);
                break;
            }
        }
        uint64_t start_mcnt = db_in->block[curblock_in].header.mcnt;
        int good_data = (int)(db_in->block[curblock_in].header.good_data);

        char BANK[5];
        hashpipe_status_lock_safe(&st);
        hgets(st.buf, "DATADIR", 127, data_dir);
        hgets(st.buf, "BANKNAM", 4, BANK);
        hashpipe_status_unlock_safe(&st);

        char filename[256];
        //sprintf(filename, "%s/TGBT16A_508_01/TMP/BF/beamformer_%s_mcnt_%lld.out", data_dir, BANK, (long long)start_mcnt);
        //fprintf(stderr, "Saving to %s\n", filename);
        //sprintf(filename, "/dev/null");
        sprintf(filename, "%s/TGBT16A_508_01/TMP/BF/beamformer_%s.out", data_dir, BANK);
        fprintf(stderr, "Saving to %s  at mcnt %lld\n", filename, (long long)start_mcnt);
        //printf("RTBF: mcnt: %lld\n", (long long)start_mcnt);
        if (SAVE) {
            float * p = (float *)db_in->block[curblock_in].data;
            FILE * filePtr = fopen(filename, "w");
            fwrite(p, sizeof(float), N_BEAM_SAMPS, filePtr);
            fwrite(&good_data, sizeof(int), 1, filePtr);
            fclose(filePtr);
        }

        // Mark input block as free and wait for next block
        flag_gpu_beamformer_output_databuf_set_free(db_in, curblock_in);
        curblock_in = (curblock_in + 1) % db_in->header.n_block;

        // Check if program killed
        pthread_testcancel();
    }

    // Thread terminates after loop
    return NULL;
}

// Thread description
static hashpipe_thread_desc_t bsave_thread = {
    name: "flag_beamsave_thread",
    skey: "BEAMSAVE",
    init: NULL,
    run:  run,
    ibuf_desc: {flag_gpu_beamformer_output_databuf_create},
    obuf_desc: {NULL}
};

static __attribute__((constructor)) void ctor() {
    register_hashpipe_thread(&bsave_thread);
}