예제 #1
0
static int search_cb(search_t *search, search_event_t *evt, void *udata)
{
    batch_decoder_t *bd = (batch_decoder_t *) udata;
    dict_t *d = search_factory_d2p(bd->sf)->dict;
    double delta = get_time_delta(bd);
    double frate = cmd_ln_int32_r(search_config(search), "-frate");
    FILE *hypfh = NULL;
    void *val;

    if (hash_table_lookup(bd->hypfiles, search_name(search), &val) == 0)
        hypfh = val;
    else
        hypfh = stdout;
    fprintf(hypfh, "time delta %f ", delta);
    switch (evt->event) {
        case SEARCH_PARTIAL_RESULT: {
            int32 score;
            seg_iter_t *seg = search_seg_iter(search, &score);
            fprintf(hypfh, "partial: ");
            for (; seg; seg = seg_iter_next(seg)) {
                int sf, ef;
                seg_iter_times(seg, &sf, &ef);
                fprintf(hypfh, "%s:%.3f ", dict_basestr(d, seg_iter_wid(seg)),
                        (double) ef / frate);
            }
            fprintf(hypfh, "(%s)\n", search_uttid(search));
            break;
        }
        case SEARCH_START_UTT:
            fprintf(hypfh, "start %s\n", search_uttid(search));
            break;
        case SEARCH_END_UTT:
            fprintf(hypfh, "end %s\n", search_uttid(search));
            break;
        case SEARCH_FINAL_RESULT: {
            int32 score;
            seg_iter_t *seg = search_seg_iter(search, &score);
            fprintf(hypfh, "full: ");
            for (; seg; seg = seg_iter_next(seg)) {
                int sf, ef;
                seg_iter_times(seg, &sf, &ef);
                fprintf(hypfh, "%s:%.3f ", dict_basestr(d, seg_iter_wid(seg)),
                        (double) ef / frate);
            }
            fprintf(hypfh, "(%s)\n", search_uttid(search));
            break;
        }
    }
    return 0;
}
예제 #2
0
파일: pcopy.c 프로젝트: brkorb/pcopy
/**
 * Copy wrapup.  If "quiet" has not been specified, then
 * print a message to the curses screen about this thread being done.
 *
 * @param[in] fseg  file segment descriptor.
 */
void
copy_wrap(file_seg_t * fseg)
{
    if (HAVE_OPT(QUIET))
        return;

    pthread_mutex_lock(&tty_mutex);
    move(ENTRY_LINE + 1, 0);
    clrtoeol();
    move(ENTRY_LINE, 0);
    clrtoeol();
    printw("th %2d DONE - copied 0x%08X bytes in %lu seconds",
           fseg->idx, fseg->end - fseg->start, get_time_delta() / BILLION);
    refresh();
    pthread_mutex_unlock(&tty_mutex);
}
예제 #3
0
파일: cursesui.cpp 프로젝트: evgeni/sysdig
void sinsp_cursesui::handle_end_of_sample(sinsp_evt* evt, int32_t next_res)
{
	m_datatable->flush(evt);

	//
	// It's time to refresh the data for this chart.
	// First of all, create the data for the chart
	//
	vector<sinsp_sample_row>* sample = 
		m_datatable->get_sample(get_time_delta());

#ifndef NOCURSESUI
	if(!m_raw_output)
	{
		//
		// If the help page has been shown, don't update the screen
		//
		if(m_viewinfo_page != NULL || m_mainhelp_page != NULL)
		{
			return;
		}

		//
		// Now refresh the UI.
		//
		if(m_viz && !m_paused)
		{
			m_viz->update_data(sample);

			if(m_datatable->m_type == sinsp_table::TT_LIST && m_inspector->is_live())
			{
				m_viz->follow_end();
			}

			m_viz->render(true);
		}

		render();
	}
#endif
	//
	// If this is a trace file, check if we reached the end of the file.
	// Or, if we are in replay mode, wait for a key press before processing
	// the next sample.
	//
	if(!m_inspector->is_live())
	{
#ifndef NOCURSESUI
		if(!m_raw_output)
		{
			if(m_offline_replay)
			{
				while(getch() != ' ')
				{
					usleep(10000);
				}
			}
		}
#endif
	}
}
예제 #4
0
파일: cursesui.cpp 프로젝트: evgeni/sysdig
sysdig_table_action sinsp_cursesui::handle_textbox_input(int ch)
{
	bool closing = false;
	string* str = NULL;
	bool handled = true;

	//
	// Pick the right string based on what we're doing
	//
	if(m_output_filtering)
	{
		str = &m_manual_filter;
	}
	else if(m_output_searching)
	{
		str = &m_manual_search_text;
	}
	else
	{
		if(m_search_caller_interface)
		{
			str = m_search_caller_interface->get_last_search_string();
		}
		else
		{
			ASSERT(false);
		}
	}

	switch(ch)
	{
		case KEY_F(1):
			m_mainhelp_page = new curses_mainhelp_page(this);
			return STA_NONE;
		case KEY_F(2):
			m_is_filter_sysdig = !m_is_filter_sysdig;
			*str = "";
			m_cursor_pos = 0;
			render();
			return STA_NONE;
		case KEY_DOWN:
		case KEY_UP:
		case KEY_PPAGE:
		case KEY_NPAGE:
			if(m_spy_box != NULL)
			{
				m_spy_box->handle_input(ch);
			}
			else
			{
				m_viz->handle_input(ch);
			}
			return STA_NONE;
		case 27: // ESC
			*str = "";

			if(m_spy_box != NULL)
			{
				m_spy_box->scroll_to(m_search_start_x, m_search_start_y);
				m_spy_box->up();
			}
			// FALL THROUGH
		case '\n':
		case '\r':
		case KEY_ENTER:
		case 6:	// CTRL+F
		case KEY_F(4):
			closing = true;
			curs_set(0);

			if(m_is_filter_sysdig && !m_output_searching)
			{
				if(*str != "")
				{
					sinsp_filter* f;

					try
					{
						f = new sinsp_filter(m_inspector, *str);
					}
					catch(sinsp_exception e)
					{
						//
						// Backup the cursor position
						//
						int cx, cy;
						getyx(stdscr, cy, cx);

						//
						// Print the error string
						//
						string wstr = "Invalid sysdig filter";

						attrset(m_colors[sinsp_cursesui::FAILED_SEARCH]);
						mvprintw(m_screenh / 2,
							m_screenw / 2 - wstr.size() / 2, 
							wstr.c_str());	

						//
						// Restore the cursor
						//
						attrset(m_colors[PANEL_HIGHLIGHT_FOCUS]);
						move(cy, cx);
						curs_set(1);
						closing = false;
						break;
					}

					delete f;
				}
			}

			break;
		case KEY_BACKSPACE:
		case 127:
			if(str->size() > 0)
			{
				m_cursor_pos--;
				move(m_screenh - 1, m_cursor_pos);
				addch(' ');
				move(m_screenh - 1, m_cursor_pos);
				*str = str->substr(0, str->size() - 1);

				if(str->size() < 2)
				{
					if(m_spy_box != NULL)
					{
						m_spy_box->scroll_to(m_search_start_x, m_search_start_y); 
					}
				}

				break;
			}
			else
			{
				return STA_NONE;
			}
		case KEY_F(3):
			if(m_search_caller_interface)
			{
				if(m_search_caller_interface->on_search_next())
				{
					render();
				}
				else
				{
					string wstr = "  NOT FOUND ";
					attrset(m_colors[sinsp_cursesui::FAILED_SEARCH]);

					mvprintw(m_screenh / 2,
						m_screenw / 2 - wstr.size() / 2, 
						wstr.c_str());

					render();
				}
			}

			break;
		default:
			handled = false;
			break;
	}

	if(ch >= ' ' && ch <= '~')
	{
		addch(ch);
		*str += ch;
		m_cursor_pos++;
	}
	else
	{
		if(!handled)
		{
			return STA_NONE;
		}
	}

	if(m_output_filtering)
	{
		if(!m_is_filter_sysdig)
		{
			//
			// Update the filter in the datatable
			//
			m_datatable->set_freetext_filter(*str);

			//
			// Refresh the data and the visualization
			//
			m_viz->update_data(m_datatable->get_sample(get_time_delta()), true);
			m_viz->render(true);
		}
	}
	else if(m_output_searching)
	{
		sinsp_table_field* skey = m_datatable->search_in_sample(*str);

		if(skey != NULL)
		{
			int32_t selct = m_datatable->get_row_from_key(skey);
			m_viz->goto_row(selct);
			m_search_nomatch = false;
		}
		else
		{
			m_search_nomatch = true;
			m_viz->render(true);
		}
	}
	else
	{
		if(m_search_caller_interface)
		{
			if(m_search_caller_interface->on_search_key_pressed(*str))
			{
				render();
			}
			else
			{
				string wstr = "  NOT FOUND ";
				attrset(m_colors[sinsp_cursesui::FAILED_SEARCH]);

				mvprintw(m_screenh / 2,
					m_screenw / 2 - wstr.size() / 2, 
					wstr.c_str());

				render();
			}

			render();
		}
		else
		{
			ASSERT(false);
		}
	}

	if(closing)
	{
		sysdig_table_action res = STA_NONE;

		if(m_is_filter_sysdig && !m_output_searching)
		{
			res = STA_SWITCH_VIEW;
		}

		m_search_nomatch = false;
		m_output_filtering = false;
		m_output_searching = false;
		m_search_caller_interface = NULL;
		render();

		if(res != STA_NONE)
		{
			return res;
		}
	}

	return STA_NONE;
}
예제 #5
0
/**
 *	locking_reserve - reserve a slot in the buffer for an event.
 *	@rchan: the channel
 *	@slot_len: the length of the slot to reserve
 *	@ts: variable that will receive the time the slot was reserved
 *	@tsc: the timestamp counter associated with time
 *	@err: receives the result flags
 *	@interrupting: if this write is interrupting another, set to non-zero
 *
 *	Returns pointer to the beginning of the reserved slot, NULL if error.
 *
 *	The err value contains the result flags and is an ORed combination
 *	of the following:
 *
 *	RELAY_BUFFER_SWITCH_NONE - no buffer switch occurred
 *	RELAY_EVENT_DISCARD_NONE - event should not be discarded
 *	RELAY_BUFFER_SWITCH - buffer switch occurred
 *	RELAY_EVENT_DISCARD - event should be discarded (all buffers are full)
 *	RELAY_EVENT_TOO_LONG - event won't fit into even an empty buffer
 */
inline char *
locking_reserve(struct rchan *rchan,
                u32 slot_len,
                struct timeval *ts,
                u32 *tsc,
                int *err,
                int *interrupting)
{
    u32 buffers_ready;
    int bytes_written;

    *err = RELAY_BUFFER_SWITCH_NONE;

    if (slot_len >= rchan->buf_size) {
        *err = RELAY_WRITE_DISCARD | RELAY_WRITE_TOO_LONG;
        return NULL;
    }

    if (rchan->initialized == 0) {
        rchan->initialized = 1;
        get_timestamp(&rchan->buf_start_time,
                      &rchan->buf_start_tsc, rchan);
        rchan->unused_bytes[0] = 0;
        bytes_written = rchan->callbacks->buffer_start(
                            rchan->id, cur_write_pos(rchan),
                            rchan->buf_id, rchan->buf_start_time,
                            rchan->buf_start_tsc, using_tsc(rchan));
        cur_write_pos(rchan) += bytes_written;
        *tsc = get_time_delta(ts, rchan);
        return cur_write_pos(rchan);
    }

    *tsc = get_time_delta(ts, rchan);

    if (in_progress_event_size(rchan)) {
        interrupted_pos(rchan) = cur_write_pos(rchan);
        cur_write_pos(rchan) = in_progress_event_pos(rchan)
                               + in_progress_event_size(rchan)
                               + interrupting_size(rchan);
        *interrupting = 1;
    } else {
        in_progress_event_pos(rchan) = cur_write_pos(rchan);
        in_progress_event_size(rchan) = slot_len;
        interrupting_size(rchan) = 0;
    }

    if (cur_write_pos(rchan) + slot_len > write_limit(rchan)) {
        if (atomic_read(&rchan->suspended) == 1) {
            in_progress_event_pos(rchan) = NULL;
            in_progress_event_size(rchan) = 0;
            interrupting_size(rchan) = 0;
            *err = RELAY_WRITE_DISCARD;
            return NULL;
        }

        buffers_ready = rchan->bufs_produced - rchan->bufs_consumed;
        if (buffers_ready == rchan->n_bufs - 1) {
            if (!mode_continuous(rchan)) {
                atomic_set(&rchan->suspended, 1);
                in_progress_event_pos(rchan) = NULL;
                in_progress_event_size(rchan) = 0;
                interrupting_size(rchan) = 0;
                get_timestamp(ts, tsc, rchan);
                switch_buffers(*ts, *tsc, rchan, 0, 0, 1);
                recalc_time_delta(ts, tsc, rchan);
                rchan->half_switch = 1;

                cur_write_pos(rchan) = write_buf_end(rchan) - 1;
                *err = RELAY_BUFFER_SWITCH | RELAY_WRITE_DISCARD;
                return NULL;
            }
        }

        get_timestamp(ts, tsc, rchan);
        switch_buffers(*ts, *tsc, rchan, 0, 0, 0);
        recalc_time_delta(ts, tsc, rchan);
        *err = RELAY_BUFFER_SWITCH;
    }

    return cur_write_pos(rchan);
}
예제 #6
0
static int batch_decoder_decode_adc(batch_decoder_t *bd, FILE *infh, int sf,
        int ef, alignment_t *al)
{
    featbuf_t *fb = search_factory_featbuf(bd->sf);
    float32 samprate = cmd_ln_float32_r(bd->config, "-samprate");
    int32 frate = cmd_ln_int32_r(bd->config, "-frate");
    int16 buf[512];

    if (ef != -1) {
        ef = (int32) (((ef - sf) * samprate / frate) + (samprate
                * cmd_ln_float32_r(bd->config, "-wlen")));
    }
    sf = (int32) (sf * (samprate / frate));
    fseek(infh, cmd_ln_int32_r(bd->config, "-adchdr") + sf * sizeof(int16),
            SEEK_SET);

    if (al) {
        alignment_iter_t *itor;
        double starttime = 0.0;
        for (itor = alignment_words(al); itor; itor = alignment_iter_next(itor)) {
            alignment_entry_t *ent = alignment_iter_get(itor);
            double nsec = (double) ent->duration / frate;
            double endtime = starttime + nsec;
            size_t nsamp = (size_t) (nsec * samprate);
            E_INFO("Processing %d samples for %s (%f seconds ending %f)\n",
            nsamp, dict_wordstr(search_factory_d2p(bd->sf)->dict, ent->id.wid),
            nsec, endtime);
            E_INFO("Woke up at delta %f\n", get_time_delta(bd));
            while (nsamp > 0) {
                size_t nread = 512;
                if (nread > nsamp) nread = nsamp;
                nread = fread(buf, sizeof(int16), nread, infh);
                if (nread == 0)
                break;
                featbuf_producer_process_raw(fb, buf, nread, FALSE);
                nsamp -= nread;
                starttime += (nread / samprate);
                double delta = get_time_delta(bd);
                if (starttime > delta) {
                    E_INFO("Sleeping until next start time (%f seconds)\n",
                            starttime - delta);
                    usleep((int)((starttime - delta) * 1000000));
                }
            }
            double delta = get_time_delta(bd);
            if (endtime > delta) {
                E_INFO("Sleeping until end time (%f seconds)\n",
                        endtime - delta);
                usleep((int)((endtime - delta) * 1000000));
            }
        }
    }
    else {
        while (ef == -1 || sf < ef) {
            size_t nread = 512;
            if (ef != -1 && nread > ef - sf)
            nread = ef - sf;
            nread = fread(buf, sizeof(int16), nread, infh);
            if (nread == 0)
            break;
            featbuf_producer_process_raw(fb, buf, nread, FALSE);
            //usleep((int)((double)nread / 16000 * 1000000));
            sf += nread;
        }
    }
    return 0;
}
예제 #7
0
파일: pcopy.c 프로젝트: brkorb/pcopy
/**
 * Return nanoseconds since start of copy.
 *
 * @returns nanoseconds since program start as a 64 bit unsigned integer.
 */
uint64_t
get_time_delta(void)
{
    static struct timeval stv = {.tv_sec = 0};

    struct timeval ctv;

    if (gettimeofday(&ctv, NULL) < 0)
        fserr(PCOPY_EXIT_FAILURE, "gettimeofday", "current");

    if (stv.tv_sec == 0)
        stv = ctv;

    if (stv.tv_sec == ctv.tv_sec)
        return (ctv.tv_usec - stv.tv_usec) * THOUSAND;

    uint64_t res = ctv.tv_sec - stv.tv_sec - 1;
    res *= MILLION;
    res += (MILLION - stv.tv_usec) + ctv.tv_usec;
    return res * THOUSAND; // micros to nanos
}

/**
 * Start up the copy of a segment.  Once the open is complete and
 * the seek to the correct offset is done, let the main thread know
 * it can continue with the next thread.  We start one at a time.
 *
 * @param[in,out] fseg  The descriptor of the segment to copy.
 */
void
copy_start(file_seg_t * fseg)
{
    static char const st_fmt[]  = "th %2d reading 0x%08lX";

    if (! HAVE_OPT(QUIET)) {
        pthread_mutex_lock(&tty_mutex);
        if (fseg->idx == 0) {
            move(0,0);
            printw("copying %s", fseg->fname);
            move(1,0);
            printw("copy to %s", fseg->dname);
        }

        move(ENTRY_LINE, 0);
        printw(st_fmt, fseg->idx, fseg->start);
        refresh();
        pthread_mutex_unlock(&tty_mutex);
    }

    fseg->fdin = open(fseg->fname, O_RDONLY);
    if (fseg->fdin < 0)
        fserr(PCOPY_EXIT_FS_ERR_IN, "open (r)", fseg->fname);

    fseg->fdout = open(fseg->dname, O_RDWR | O_CREAT, 0600);
    if (fseg->fdout < 0)
        fserr(PCOPY_EXIT_FS_ERR_OUT, "open (w)", fseg->dname);

    if (fseg->start > 0) {
        if (lseek(fseg->fdin,  fseg->start, SEEK_SET) != fseg->start)
            fserr(PCOPY_EXIT_FS_ERR_IN, "seek (in)", fseg->fname);

        if (lseek(fseg->fdout, fseg->start, SEEK_SET) != fseg->start)
            fserr(PCOPY_EXIT_FS_ERR_OUT, "seek (out)", fseg->dname);
    }

    if (posix_fadvise(fseg->fdin, fseg->start, fseg->end - fseg->start,
                      POSIX_FADV_SEQUENTIAL) != 0)
        fserr(PCOPY_EXIT_FS_ERR_IN, "fadvise(r)", fseg->fname);

    if (posix_fadvise(fseg->fdout, fseg->start, fseg->end - fseg->start,
                      POSIX_FADV_SEQUENTIAL) != 0)
        fserr(PCOPY_EXIT_FS_ERR_OUT, "fadvise(w)", fseg->dname);

    pthread_mutex_lock(&th_start_mutex);
    pthread_cond_signal(&th_start_cond);
    pthread_mutex_unlock(&th_start_mutex);

    fseg->lastt = get_time_delta();
}

/**
 *  Show copy progress.  The display happens if "quiet" has not been
 *  specified.  This function will also sleep, if "flow-rate" has
 *  been specified and the time since the last segment read has been
 *  too short.
 *
 * @param[in,out] fseg  file segment descriptor.  "lastt" may be updated.
 */
void
copy_progress(file_seg_t * fseg)
{
    static char const prg_fmt[] =  "      read to 0x%08lX togo 0x%08lX";

    if (! HAVE_OPT(QUIET)) {
        pthread_mutex_lock(&tty_mutex);
        move(ENTRY_LINE + 1, 0);
        printw(prg_fmt, fseg->start, fseg->end - fseg->start);
        refresh();
        pthread_mutex_unlock(&tty_mutex);
    }

    if (HAVE_OPT(FLOW_RATE)) {
        uint64_t cdelta     = get_time_delta();     // delta from start
        uint64_t chunk_time = cdelta - fseg->lastt; // since chunk start

        /*
         * If the time used is more than 1/100 of a second less than
         * the time that is supposed to be consumed, then nanosleep.
         */
        if (chunk_time < nsec_per_iteration - (10*MILLION)) {
            uint64_t slptm = nsec_per_iteration - chunk_time;
            struct timespec ts = {
                .tv_sec  = (slptm > BILLION) ? (slptm / BILLION) : 0,
                .tv_nsec = (slptm > BILLION) ? (slptm % BILLION) : slptm
            };
            (void)nanosleep(&ts, NULL);
            fseg->lastt = get_time_delta();

        } else {
            fseg->lastt = cdelta;
        }
    }
}