Beispiel #1
0
static void
init_phase_two(workqueue_t *wq)
{
	int num;

	/*
	 * We're going to continually merge the first two entries on the queue,
	 * placing the result on the end, until there's nothing left to merge.
	 * At that point, everything will have been merged into one.  The
	 * initial value of ninqueue needs to be equal to the total number of
	 * entries that will show up on the queue, both at the start of the
	 * phase and as generated by merges during the phase.
	 */
	wq->wq_ninqueue = num = fifo_len(wq->wq_donequeue);
	while (num != 1) {
		wq->wq_ninqueue += num / 2;
		num = num / 2 + num % 2;
	}

	/*
	 * Move the done queue to the work queue.  We won't be using the done
	 * queue in phase 2.
	 */
	assert(fifo_len(wq->wq_queue) == 0);
	fifo_free(wq->wq_queue, NULL);
	wq->wq_queue = wq->wq_donequeue;
}
Beispiel #2
0
static int
handle_buffer(struct rev_server *revsrv, struct rev_client *cl)
{
	struct FIFOBUF *inbuf = INBUF(cl);

	if (fifo_len(inbuf) < 3)
		return 0; /* not enough data */

	int msg_size = *((uint16_t*)inbuf->data);
	int msg_id = *((uint8_t*)(inbuf->data+2));

	ASSERT(msg_size <= MAX_MSG_SIZE, "invalid msg size")

	if (fifo_len(inbuf) < 3 + msg_size)
		return 0; /* not enough data */

	/* skip size & id */
	fifo_read(inbuf, NULL, 3);

	char buf[MAX_MSG_SIZE];
	struct netmsg msg;

	msg.id = msg_id;
	msg.size = msg_size;
	msg.data = buf;

	//printf("got msg id %d size %d\n", msg_id, msg_size);
	/* read and handle message */
	fifo_read(inbuf, buf, msg_size);
	ASSERT(handle_msg(revsrv, cl, &msg) == 0, "invalid msg");

	if (fifo_len(inbuf) > 0)
		return 1; /* there is data left */
	return 0;
}
Beispiel #3
0
t_bool			test_sym_prod(
		char const **str,
		size_t nb_prods,
		size_t nb_symbols,
		t_bool (*test)(t_prod **prod, t_symbol **syms, ...))
{
	t_prod		**prods;
	t_symbol	**syms;
	t_fifo		*sym_lists[2];
	t_bool		result;

	sym_lists[0] = f_fifo_create();
	sym_lists[1] = f_fifo_create();
	f_fifo_add(sym_lists[1], create_symbol("END_OF_INPUT"));
	prods = parse_prods(str, nb_prods, sym_lists);
	syms = parse_symbols(str + nb_prods, nb_symbols, sym_lists);
	if (prods != NULL && syms != NULL
			&& (fifo_len(sym_lists[0]) == 0
				|| compute_sets_all_syms(sym_lists[1], sym_lists[0])))
		result = test(prods, syms, sym_lists[0], sym_lists[1],
				nb_prods, nb_symbols);
	else
		result = FALSE;
	destroy_prods(&prods, nb_prods);
	free(syms);
	f_fifo_destroy(&sym_lists[0], sym_del);
	f_fifo_destroy(&sym_lists[1], sym_del);
	return (result);
}
Beispiel #4
0
/*
 * Main loop for worker threads.
 */
static void
worker_thread(workqueue_t *wq)
{
	worker_runphase1(wq);

	debug(2, "%d: entering first barrier\n", pthread_self());

	if (barrier_wait(&wq->wq_bar1)) {

		debug(2, "%d: doing work in first barrier\n", pthread_self());

		finalize_phase_one(wq);

		init_phase_two(wq);

		debug(2, "%d: ninqueue is %d, %d on queue\n", pthread_self(),
		    wq->wq_ninqueue, fifo_len(wq->wq_queue));
	}

	debug(2, "%d: entering second barrier\n", pthread_self());

	(void) barrier_wait(&wq->wq_bar2);

	debug(2, "%d: phase 1 complete\n", pthread_self());

	worker_runphase2(wq);
}
Beispiel #5
0
/*
 * Retrieve 'len' bytes from the fifo, refilling if necessary.
 */
static int trace_fifo_get(struct thread_data *td, struct fifo *fifo, int fd,
			  void *buf, unsigned int len)
{
	if (fifo_len(fifo) < len) {
		int ret = refill_fifo(td, fifo, fd);

		if (ret < 0)
			return ret;
	}

	return fifo_get(fifo, buf, len);
}
Beispiel #6
0
/*
 * Pass a tdata_t tree, built from an input file, off to the work queue for
 * consumption by worker threads.
 */
static int
merge_ctf_cb(tdata_t *td, char *name, void *arg)
{
	workqueue_t *wq = arg;

	debug(3, "Adding tdata %p for processing\n", (void *)td);

	pthread_mutex_lock(&wq->wq_queue_lock);
	while (fifo_len(wq->wq_queue) > wq->wq_ithrottle) {
		debug(2, "Throttling input (len = %d, throttle = %d)\n",
		    fifo_len(wq->wq_queue), wq->wq_ithrottle);
		pthread_cond_wait(&wq->wq_work_removed, &wq->wq_queue_lock);
	}

	fifo_add(wq->wq_queue, td);
	debug(1, "Thread %d announcing %s\n", pthread_self(), name);
	pthread_cond_broadcast(&wq->wq_work_avail);
	pthread_mutex_unlock(&wq->wq_queue_lock);

	return (1);
}
Beispiel #7
0
static void
finalize_phase_one(workqueue_t *wq)
{
	int startslot, i;

	/*
	 * wip slots are cleared out only when maxbatchsz td's have been merged
	 * into them.  We're not guaranteed that the number of files we're
	 * merging is a multiple of maxbatchsz, so there will be some partial
	 * groups in the wip array.  Move them to the done queue in batch ID
	 * order, starting with the slot containing the next batch that would
	 * have been placed on the done queue, followed by the others.
	 * One thread will be doing this while the others wait at the barrier
	 * back in worker_thread(), so we don't need to worry about pesky things
	 * like locks.
	 */

	for (startslot = -1, i = 0; i < wq->wq_nwipslots; i++) {
		if (wq->wq_wip[i].wip_batchid == wq->wq_lastdonebatch + 1) {
			startslot = i;
			break;
		}
	}

	assert(startslot != -1);

	for (i = startslot; i < startslot + wq->wq_nwipslots; i++) {
		int slotnum = i % wq->wq_nwipslots;
		wip_t *wipslot = &wq->wq_wip[slotnum];

		if (wipslot->wip_td != NULL) {
			debug(2, "clearing slot %d (%d) (saving %d)\n",
			    slotnum, i, wipslot->wip_nmerged);
		} else
			debug(2, "clearing slot %d (%d)\n", slotnum, i);

		if (wipslot->wip_td != NULL) {
			fifo_add(wq->wq_donequeue, wipslot->wip_td);
			wq->wq_wip[slotnum].wip_td = NULL;
		}
	}

	wq->wq_lastdonebatch = wq->wq_next_batchid++;

	debug(2, "phase one done: donequeue has %d items\n",
	    fifo_len(wq->wq_donequeue));
}
Beispiel #8
0
ICACHE_FLASH_ATTR void
netout_flush(struct netclient *netclient)
{
	char *p;
	unsigned int l;
	sint8 rc;

	if (fifo_len(&netclient->fifo_net) == 0)
		return;

	if (netclient->fifo_net_sending == 0) {
		netclient->fifo_net_sending = 1;

		p = fifo_getbulk(&netclient->fifo_net, &l);
		rc = espconn_sent(netclient->espconn, p, l);
		if (rc != ESPCONN_OK) {
			syslog_send(LOG_DAEMON|LOG_DEBUG, "telnet: espconn_sent: error %d", rc);
			espconn_disconnect(netclient->espconn);
		}
	}
}
int main(int argc, char **argv)
{
    int c;
    int inflag = 0;
    int dbg = 0;
    int sr_ds = 200;
    char * rec_name = "vfdb/427";
    char * db_path = "/opt/physiobank/database";
    size_t win_sec = 8;
    /* r stands for record with folder
     * p for path
     * i for information of record
     * s downsample sr
     * w window length default:8
     * d debug
     */
    while ((c = getopt(argc, argv, "idr:p:s:w:")) != -1)
        switch (c){
            case 'i':
                inflag = 1; 
                break;
            case 'r':
                rec_name = optarg;
                break;
            case 'p':
                db_path = optarg;
                break;
            case 's':
                sr_ds= atoi(optarg);
                break;
            case'w':
                win_sec = atoi(optarg);
                break;
            case'd':
                dbg = 1;
                break;
            default:
                abort();
        }            
    int i, j, nsig;
    WFDB_Sample *v;
    WFDB_Siginfo *s;
    WFDB_Anninfo a;
    setwfdb(db_path);
    
    nsig = isigopen(rec_name, NULL, 0);
    if (nsig < 1){
        printf("nsig:%d\n",nsig);
        exit(1);
    }
    s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo));
    if (isigopen(rec_name, s, nsig) != nsig)
        exit(1);
    v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample));

    int orig_sr = sampfreq(rec_name);
    a.name = "atr"; a.stat = WFDB_READ;
    if (wfdbinit(rec_name, &a, 1, s, nsig) != nsig) exit(3);
    if(1 == inflag ){
        printf("sr:%d\n",orig_sr);
        printf("%d signals\n", nsig);
        for (i = 0; i < nsig; i++) {
            printf("Group %d, Signal %d:\n", s[i].group, i); 
            printf("File: %s\n", s[i].fname);
            printf("Description: %s\n", s[i].desc);
            printf("Gain: ");
            if (s[i].gain == 0.) 
                printf("uncalibrated; assume %g", WFDB_DEFGAIN);
            else printf("%g", s[i].gain);
            printf(" adu/%s\n", s[i].units ? s[i].units : "mV");
            printf(" Initial value: %d\n", s[i].initval);
            printf(" Storage format: %d\n", s[i].fmt);
            printf(" I/O: ");
            if (s[i].bsize == 0) printf("can be unbuffered\n");
            else printf("%d-byte blocks\n", s[i].bsize);
            printf(" ADC resolution: %d bits\n", s[i].adcres);
            printf(" ADC zero: %d\n", s[i].adczero);
            if (s[i].nsamp > 0L) {
                printf(" Length: %s (%ld sample intervals)\n",
                       timstr(s[i].nsamp), s[i].nsamp);
                printf(" Checksum: %d\n", s[i].cksum);
            }
            else printf(" Length undefined\n");
        }
    }

    fifo_t fifo_ecg;
    int fifo_ecg_buf[FIFO_SIZE];
    fifo_init(&fifo_ecg, fifo_ecg_buf, FIFO_SIZE);

    fifo_t fifo_bt;
    int fifo_bt_buf[FIFO_SIZE];
    fifo_init(&fifo_bt, fifo_bt_buf, FIFO_SIZE);

    int tmp = 0;
    int sr = 200;
    WFDB_Time begin_samp = 0;
    WFDB_Time end_samp = orig_sr*win_sec;
    WFDB_Annotation begin_ann;
    WFDB_Annotation end_ann;
    getann(0, &begin_ann);
    while(0 == getann(0, &end_ann))
         if ((end_ann.aux != NULL && *end_ann.aux > 0)
                    ||0 == strcmp(annstr(end_ann.anntyp), "[")
                    ||0 == strcmp(annstr(end_ann.anntyp), "]")
                    ||0 == strcmp(annstr(end_ann.anntyp), "~")
                ){
            break;
        }
    
    int * pBt_len = (int*)calloc(win_sec,sizeof(int));
    ResetBDAC();
    for (; ;) {
        if (getvec(v) < 0)
            break;
//        for (j = 0; j < nsig; j++){
//        }
        tmp = v[nsig-1];
        tmp = v[0];
        int vout1 = 0;
        static int bt_i = 0;
        static unsigned int samplecnt = 0;
        int idx = 0;
        if(down_sample(tmp, &vout1, orig_sr, sr)) {
                samplecnt ++;
                fifo_write(&fifo_ecg, &vout1, 1*sizeof(int));
                int beatType, beatMatch;
                long ltmp = vout1-s[0].adczero;
                ltmp *= 200; ltmp /= s[0].gain;
                int bdac_dly = BeatDetectAndClassify(ltmp, &beatType, &beatMatch);
                idx = bt_i/sr;
                if (0 != bdac_dly ) {
                    pBt_len[idx]++;
                    fifo_write(&fifo_bt, &beatType, sizeof(int));
                }
                bt_i = ++bt_i%(win_sec*sr);
        }

        double cm = 0.0;

        int size = win_sec*sr;
        if(fifo_len(&fifo_ecg)/sizeof(int) >= sr*win_sec){
            int * win_data = (int*)malloc(win_sec*sr*sizeof(int));
            int * ds_data = (int*)malloc(win_sec*sr_ds*sizeof(int));
            
            int len = fifo_len(&fifo_bt)/sizeof(int);
            int * p = (int*)calloc(len, sizeof(int));
           
            if (0 != len){
               //printf("bt_i:%d\n", bt_i);
                fifo_read_steps(&fifo_bt, p, len*sizeof(int), pBt_len[bt_i/sr]*sizeof(int));
                //for (i = 0;i< len;i++) printf("%d ", p[i]);
                //printf("\n");

            }
            pBt_len[bt_i/sr] = 0;
            
            fifo_read_steps(&fifo_ecg, win_data, size*sizeof(int), sr*sizeof(int));
            filtering(win_data, size, sr);
            int i = 0;
            int ds_size = 0;
            int vout;
            for(i = 0;i < size;i++){
               // if(down_sample(win_data[i], &vout, sr, sr_ds)) ds_data[ds_size++] = vout;
            }
            double dven = 0.0;

            if (0 != len){
                int tmp_cnt = 0;
                for(i = 0; i < len ; i++){
                    if(5 == p[i]) dven ++;
                }
                //printf("div:%d %d\n", tmp_cnt, len);
                dven /= len; 
            }
                         
            //cm = ecg_complexity_measure(win_data, size);
            //cm = ecg_complexity_measure(ds_data, ds_size);
            //cm = cpsd(ds_data, ds_size, 0.5*sr_ds);
            //cm = calc_grid(ds_data, ds_size, 0.5*sr_ds);
            cm = calc_grid(win_data, size, 0.5*sr);


        
            if (-1 == cm ) continue;
            //VT print 1;
            //VF print 2;
            
            int hr =  (int)((double)(len*60)/win_sec+0.5);
            int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VT");
            if (1 == ret){
                printf("%d %lf %lf %d\n", 1, cm, dven, hr);
            } else if (0 == ret) {
                ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VFL");
                int ret2 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "[");
                if (1 == ret || 1 == ret2){
                    printf("%d %lf %lf %d\n", 2, cm, dven, hr);
                } else if (0 == ret){
//                    ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(N");
//                    int ret3 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "N");
//                    if ((1 == ret  || 1 == ret3) && -1 != begin_ann.subtyp) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); 

                    if (1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFIB") 
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFL")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(IVR")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SBR")
                        || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(BII")
                       ) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); 
                    
                   // int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA");
                   // if (1 == ret)  printf ("%d %lf\n", 0, cm); 
                }
            }
            //iannsettime(begin_samp);
            begin_samp += orig_sr;
            end_samp += orig_sr;
            if(end_ann.time < begin_samp){
                begin_ann = end_ann;
                
                while(1)
                    if (0 != getann(0, &end_ann)){
                        end_ann = begin_ann;
                        /*the last sample of the signal*/
                        end_ann.time = s[nsig-1].nsamp;
                        break;
                    }else if ((end_ann.aux != NULL && *end_ann.aux > 0)
                                ||0 == strcmp(annstr(end_ann.anntyp), "[")
                                ||0 == strcmp(annstr(end_ann.anntyp), "]")
                                ||0 == strcmp(annstr(end_ann.anntyp), "~")
                            ){
                        break;
                    }
                if(dbg){
                    printf("begin tm:%s type:%s ", mstimstr(begin_ann.time), annstr(begin_ann.anntyp));
                    if(begin_ann.aux != NULL)
                        printf("begin aux:%s", begin_ann.aux+1);
                    printf("\n");
                    printf("end tm:%s type:%s ", mstimstr(end_ann.time), annstr(end_ann.anntyp));
                    if (end_ann.aux != NULL)
                        printf("end aux:%s", end_ann.aux+1);
                    printf("\n");

                    printf("begin sample:%s\n", mstimstr(begin_samp));
                    printf("ann diff:%s\n", mstimstr(end_ann.time-begin_ann.time));
                }
            }
            free(p);
            free(ds_data);
            free(win_data);
        }

    }
    free(pBt_len);
    wfdbquit();
    return 0;
}
Beispiel #10
0
int
main(int argc, char **argv)
{
	tdata_t *mstrtd, *savetd;
	char *uniqfile = NULL, *uniqlabel = NULL;
	char *withfile = NULL;
	char *label = NULL;
	char **ifiles, **tifiles;
	int verbose = 0, docopy = 0;
	int write_fuzzy_match = 0;
	int require_ctf = 0;
	int nifiles, nielems;
	int c, i, idx, tidx, err;

	progname = basename(argv[0]);

	if (getenv("CTFMERGE_DEBUG_LEVEL"))
		debug_level = atoi(getenv("CTFMERGE_DEBUG_LEVEL"));

	err = 0;
	while ((c = getopt(argc, argv, ":cd:D:fl:L:o:tvw:s")) != EOF) {
		switch (c) {
		case 'c':
			docopy = 1;
			break;
		case 'd':
			/* Uniquify against `uniqfile' */
			uniqfile = optarg;
			break;
		case 'D':
			/* Uniquify against label `uniqlabel' in `uniqfile' */
			uniqlabel = optarg;
			break;
		case 'f':
			write_fuzzy_match = CTF_FUZZY_MATCH;
			break;
		case 'l':
			/* Label merged types with `label' */
			label = optarg;
			break;
		case 'L':
			/* Label merged types with getenv(`label`) */
			if ((label = getenv(optarg)) == NULL)
				label = CTF_DEFAULT_LABEL;
			break;
		case 'o':
			/* Place merged types in CTF section in `outfile' */
			outfile = optarg;
			break;
		case 't':
			/* Insist *all* object files built from C have CTF */
			require_ctf = 1;
			break;
		case 'v':
			/* More debugging information */
			verbose = 1;
			break;
		case 'w':
			/* Additive merge with data from `withfile' */
			withfile = optarg;
			break;
		case 's':
			/* use the dynsym rather than the symtab */
			dynsym = CTF_USE_DYNSYM;
			break;
		default:
			usage();
			exit(2);
		}
	}

	/* Validate arguments */
	if (docopy) {
		if (uniqfile != NULL || uniqlabel != NULL || label != NULL ||
		    outfile != NULL || withfile != NULL || dynsym != 0)
			err++;

		if (argc - optind != 2)
			err++;
	} else {
		if (uniqfile != NULL && withfile != NULL)
			err++;

		if (uniqlabel != NULL && uniqfile == NULL)
			err++;

		if (outfile == NULL || label == NULL)
			err++;

		if (argc - optind == 0)
			err++;
	}

	if (err) {
		usage();
		exit(2);
	}

	if (uniqfile && access(uniqfile, R_OK) != 0) {
		warning("Uniquification file %s couldn't be opened and "
		    "will be ignored.\n", uniqfile);
		uniqfile = NULL;
	}
	if (withfile && access(withfile, R_OK) != 0) {
		warning("With file %s couldn't be opened and will be "
		    "ignored.\n", withfile);
		withfile = NULL;
	}
	if (outfile && access(outfile, R_OK|W_OK) != 0)
		terminate("Cannot open output file %s for r/w", outfile);

	/*
	 * This is ugly, but we don't want to have to have a separate tool
	 * (yet) just for copying an ELF section with our specific requirements,
	 * so we shoe-horn a copier into ctfmerge.
	 */
	if (docopy) {
		copy_ctf_data(argv[optind], argv[optind + 1]);

		exit(0);
	}

	set_terminate_cleanup(terminate_cleanup);

	/* Sort the input files and strip out duplicates */
	nifiles = argc - optind;
	ifiles = xmalloc(sizeof (char *) * nifiles);
	tifiles = xmalloc(sizeof (char *) * nifiles);

	for (i = 0; i < nifiles; i++)
		tifiles[i] = argv[optind + i];
	qsort(tifiles, nifiles, sizeof (char *), (int (*)())strcompare);

	ifiles[0] = tifiles[0];
	for (idx = 0, tidx = 1; tidx < nifiles; tidx++) {
		if (strcmp(ifiles[idx], tifiles[tidx]) != 0)
			ifiles[++idx] = tifiles[tidx];
	}
	nifiles = idx + 1;

	/* Make sure they all exist */
	if ((nielems = count_files(ifiles, nifiles)) < 0)
		terminate("Some input files were inaccessible\n");

	/* Prepare for the merge */
	wq_init(&wq, nielems);

	start_threads(&wq);

	/*
	 * Start the merge
	 *
	 * We're reading everything from each of the object files, so we
	 * don't need to specify labels.
	 */
	if (read_ctf(ifiles, nifiles, NULL, merge_ctf_cb,
	    &wq, require_ctf) == 0) {
		/*
		 * If we're verifying that C files have CTF, it's safe to
		 * assume that in this case, we're building only from assembly
		 * inputs.
		 */
		if (require_ctf)
			exit(0);
		terminate("No ctf sections found to merge\n");
	}

	pthread_mutex_lock(&wq.wq_queue_lock);
	wq.wq_nomorefiles = 1;
	pthread_cond_broadcast(&wq.wq_work_avail);
	pthread_mutex_unlock(&wq.wq_queue_lock);

	pthread_mutex_lock(&wq.wq_queue_lock);
	while (wq.wq_alldone == 0)
		pthread_cond_wait(&wq.wq_alldone_cv, &wq.wq_queue_lock);
	pthread_mutex_unlock(&wq.wq_queue_lock);

	join_threads(&wq);

	/*
	 * All requested files have been merged, with the resulting tree in
	 * mstrtd.  savetd is the tree that will be placed into the output file.
	 *
	 * Regardless of whether we're doing a normal uniquification or an
	 * additive merge, we need a type tree that has been uniquified
	 * against uniqfile or withfile, as appropriate.
	 *
	 * If we're doing a uniquification, we stuff the resulting tree into
	 * outfile.  Otherwise, we add the tree to the tree already in withfile.
	 */
	assert(fifo_len(wq.wq_queue) == 1);
	mstrtd = fifo_remove(wq.wq_queue);

	if (verbose || debug_level) {
		debug(2, "Statistics for td %p\n", (void *)mstrtd);

		iidesc_stats(mstrtd->td_iihash);
	}

	if (uniqfile != NULL || withfile != NULL) {
		char *reffile, *reflabel = NULL;
		tdata_t *reftd;

		if (uniqfile != NULL) {
			reffile = uniqfile;
			reflabel = uniqlabel;
		} else
			reffile = withfile;

		if (read_ctf(&reffile, 1, reflabel, read_ctf_save_cb,
		    &reftd, require_ctf) == 0) {
			terminate("No CTF data found in reference file %s\n",
			    reffile);
		}

		savetd = tdata_new();

		if (CTF_TYPE_ISCHILD(reftd->td_nextid))
			terminate("No room for additional types in master\n");

		savetd->td_nextid = withfile ? reftd->td_nextid :
		    CTF_INDEX_TO_TYPE(1, TRUE);
		merge_into_master(mstrtd, reftd, savetd, 0);

		tdata_label_add(savetd, label, CTF_LABEL_LASTIDX);

		if (withfile) {
			/*
			 * savetd holds the new data to be added to the withfile
			 */
			tdata_t *withtd = reftd;

			tdata_merge(withtd, savetd);

			savetd = withtd;
		} else {
			char uniqname[MAXPATHLEN];
			labelent_t *parle;

			parle = tdata_label_top(reftd);

			savetd->td_parlabel = xstrdup(parle->le_name);

			strncpy(uniqname, reffile, sizeof (uniqname));
			uniqname[MAXPATHLEN - 1] = '\0';
			savetd->td_parname = xstrdup(basename(uniqname));
		}

	} else {
		/*
		 * No post processing.  Write the merged tree as-is into the
		 * output file.
		 */
		tdata_label_free(mstrtd);
		tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);

		savetd = mstrtd;
	}

	tmpname = mktmpname(outfile, ".ctf");
	write_ctf(savetd, outfile, tmpname,
	    CTF_COMPRESS | write_fuzzy_match | dynsym);
	if (rename(tmpname, outfile) != 0)
		terminate("Couldn't rename output temp file %s", tmpname);
	free(tmpname);

	return (0);
}
Beispiel #11
0
static void
worker_runphase2(workqueue_t *wq)
{
	tdata_t *pow1, *pow2;
	int batchid;

	for (;;) {
		pthread_mutex_lock(&wq->wq_queue_lock);

		if (wq->wq_ninqueue == 1) {
			pthread_cond_broadcast(&wq->wq_work_avail);
			pthread_mutex_unlock(&wq->wq_queue_lock);

			debug(2, "%d: entering p2 completion barrier\n",
			    pthread_self());
			if (barrier_wait(&wq->wq_bar1)) {
				pthread_mutex_lock(&wq->wq_queue_lock);
				wq->wq_alldone = 1;
				pthread_cond_signal(&wq->wq_alldone_cv);
				pthread_mutex_unlock(&wq->wq_queue_lock);
			}

			return;
		}

		if (fifo_len(wq->wq_queue) < 2) {
			pthread_cond_wait(&wq->wq_work_avail,
			    &wq->wq_queue_lock);
			pthread_mutex_unlock(&wq->wq_queue_lock);
			continue;
		}

		/* there's work to be done! */
		pow1 = fifo_remove(wq->wq_queue);
		pow2 = fifo_remove(wq->wq_queue);
		wq->wq_ninqueue -= 2;

		batchid = wq->wq_next_batchid++;

		pthread_mutex_unlock(&wq->wq_queue_lock);

		debug(2, "%d: merging %p into %p\n", pthread_self(),
		    (void *)pow1, (void *)pow2);
		merge_into_master(pow1, pow2, NULL, 0);
		tdata_free(pow1);

		/*
		 * merging is complete.  place at the tail of the queue in
		 * proper order.
		 */
		pthread_mutex_lock(&wq->wq_queue_lock);
		while (wq->wq_lastdonebatch + 1 != batchid) {
			pthread_cond_wait(&wq->wq_done_cv,
			    &wq->wq_queue_lock);
		}

		wq->wq_lastdonebatch = batchid;

		fifo_add(wq->wq_queue, pow2);
		debug(2, "%d: added %p to queue, len now %d, ninqueue %d\n",
		    pthread_self(), (void *)pow2, fifo_len(wq->wq_queue),
		    wq->wq_ninqueue);
		pthread_cond_broadcast(&wq->wq_done_cv);
		pthread_cond_signal(&wq->wq_work_avail);
		pthread_mutex_unlock(&wq->wq_queue_lock);
	}
}
Beispiel #12
0
/**
 * fifo_is_full - returns true if the fifo is full
 * @fifo: address of the fifo to be used
 */
int fifo_is_full(fifo_t * fifo)
{
    return fifo_len(fifo) > fifo->mask;
}