Ejemplo n.º 1
0
int eio_open(std::string fname, std::ifstream & in)
{
	int target_big_endian = (endian_host_byte_order() == endian_big);

	in.open(fname.c_str());
	if(!in.is_open())
	{
		fatal("unable to open EIO file `%s'", fname.c_str());
	}

	std::string format_header("/* file_format: 2, file_version: 3, big_endian: 0 */");
	std::string format_header_4("/* file_format: 2, file_version: 4, big_endian: 0 */");
	std::string start_header("/* ** start checkpoint @ -1... */");
	std::string buf;

	getline(in,buf);
	buf += '\n';
	if(buf!=EIO_FILE_HEADER)
	{
		std::cerr << "Failed reading EIO file header, read: " << buf << std::endl;
		std::cerr << "Should have read: " << EIO_FILE_HEADER << std::endl;
		exit(-1);
	}
	getline(in,buf);
	getline(in,buf);
	if(buf!=format_header && buf!=format_header_4)
	{
		std::cerr << "Failed reading format header, read: " << buf << std::endl;
		std::cerr << "Should have read: " << format_header << std::endl;
		std::cerr << "or: " << format_header_4 << std::endl;
		exit(-1);
	}

	int file_format, file_version, big_endian;
	char c_buf;
	in >> c_buf >> file_format >> c_buf >> file_version >> c_buf >> big_endian;
	getline(in,buf);
	if(!in.good())
	{
		fatal("could not read EIO file header");
	}

	getline(in,buf);
	getline(in,buf);
	if(buf!=start_header)
	{
		std::cerr << "Failed reading start header, read: " << buf << std::endl;
		std::cerr << "Should have read: " << start_header << std::endl;
		exit(-1);
	}
	getline(in,buf);

	if(file_format != MD_EIO_FILE_FORMAT)
	{
		fatal("EIO file `%s' has incompatible format", fname.c_str());
	}

	if((file_version != EIO_FILE_VERSION) && (file_version != EIO_FILE_VERSION_NEW))
	{
		fatal("EIO file `%s' has incompatible version", fname.c_str());
	}

	if(!!big_endian != !!target_big_endian)
	{
		warn("endian of `%s' does not match host", fname.c_str());
		warn("running with experimental cross-endian execution support");
		warn("****************************************");
		warn("**>> please check results carefully <<**");
		warn("****************************************");
	}
	return file_version;
}
Ejemplo n.º 2
0
void logger::dolog_msg(const logger::msg& a_msg) {
    try {
        switch (a_msg.m_type) {
        case payload_t::CHAR_FUN: {
            assert(a_msg.m_fun.cf);
            char  buf[4096];
            auto* end = buf + sizeof(buf);
            char*   p = format_header(a_msg, buf,  end);
            int     n = (a_msg.m_fun.cf)(p,  end - p);
            if (p[n-1] == '\n') --p;
            p = format_footer(a_msg, p+n,  end);
            m_sig_slot[level_to_signal_slot(a_msg.level())](
                on_msg_delegate_t::invoker_type(a_msg, buf, p - buf));

            if (fatal_kill_signal() && a_msg.level() == LEVEL_FATAL) {
                m_abort = true;
                dolog_fatal_msg(buf, p - buf);
            }

            break;
        }
        case payload_t::STR_FUN: {
            assert(a_msg.m_fun.cf);
            char  pfx[256], sfx[256];
            char*   p = format_header(a_msg, pfx, pfx + sizeof(pfx));
            char*   q = format_footer(a_msg, sfx, sfx + sizeof(sfx));
            auto  res = (a_msg.m_fun.sf)(pfx, p - pfx, sfx, q - sfx);
            m_sig_slot[level_to_signal_slot(a_msg.level())](
                on_msg_delegate_t::invoker_type(a_msg, res.c_str(), res.size()));

            if (fatal_kill_signal() && a_msg.level() == LEVEL_FATAL) {
                m_abort = true;
                dolog_fatal_msg(res.c_str(), res.size());
            }

            break;
        }
        case payload_t::STR: {
            detail::basic_buffered_print<1024> buf;
            char  pfx[256], sfx[256];
            char* p = format_header(a_msg, pfx, pfx + sizeof(pfx));
            char* q = format_footer(a_msg, sfx, sfx + sizeof(sfx));
            auto ps = p - pfx;
            auto qs = q - sfx;
            buf.reserve(a_msg.m_fun.str.size() + ps + qs + 1);
            buf.sprint(pfx, ps);
            auto& s = a_msg.m_fun.str;
            // Remove trailing new lines
            auto sz = int(s.size());
            while (sz && s[sz-1] == '\n') --sz;
            buf.sprint(s.c_str(), sz);
            buf.sprint(sfx, qs);
            m_sig_slot[level_to_signal_slot(a_msg.level())](
                on_msg_delegate_t::invoker_type(a_msg, buf.str(), buf.size()));

            if (fatal_kill_signal() && a_msg.level() == LEVEL_FATAL) {
                m_abort = true;
                dolog_fatal_msg(buf.c_str(), buf.size());
            }

            break;
        }
        }
    } catch (std::runtime_error& e) {
        if (m_error)
            m_error(e.what());
        else
            throw;
    }
}
Ejemplo n.º 3
0
int
main(int argc, char *argv[])

{
    char *env_top;
    char **preset_argv;
    int preset_argc = 0;
    void *mask;
    int need_mini = 1;

    struct statics statics;
    globalstate *gstate;

    /* get our name */
    if (argc > 0)
    {
	if ((myname = strrchr(argv[0], '/')) == 0)
	{
	    myname = argv[0];
	}
	else
	{
	    myname++;
	}
    }

    /* binary compatibility check */
#ifdef HAVE_UNAME
    {
	struct utsname uts;

	if (uname(&uts) == 0)
	{
	    if (strcmp(uts.machine, UNAME_HARDWARE) != 0)
	    {
		fprintf(stderr, "%s: incompatible hardware platform\n",
			myname);
		exit(EX_UNAVAILABLE);
	    }
	}
    }
#endif

    /* initialization */
    gstate = (globalstate *)calloc(1, sizeof(globalstate));
    gstate->statics = &statics;
    time_mark(NULL);

    /* preset defaults for various options */
    gstate->show_usernames = Yes;
    gstate->topn = DEFAULT_TOPN;
    gstate->delay = DEFAULT_DELAY;
    gstate->fulldraw = Yes;
    gstate->use_color = Yes;
    gstate->interactive = Maybe;

    /* preset defaults for process selection */
    gstate->pselect.idle = Yes;
    gstate->pselect.system = No;
    gstate->pselect.fullcmd = No;
    gstate->pselect.command = NULL;
    gstate->pselect.uid = -1;
    gstate->pselect.mode = 0;

    /* use a large buffer for stdout */
#ifdef HAVE_SETVBUF
    setvbuf(stdout, stdoutbuf, _IOFBF, BUFFERSIZE);
#else
#ifdef HAVE_SETBUFFER
    setbuffer(stdout, stdoutbuf, BUFFERSIZE);
#endif
#endif

    /* get preset options from the environment */
    if ((env_top = getenv("TOP")) != NULL)
    {
	preset_argv = argparse(env_top, &preset_argc);
	preset_argv[0] = myname;
	do_arguments(gstate, preset_argc, preset_argv);
    }

    /* process arguments */
    do_arguments(gstate, argc, argv);

#ifdef ENABLE_COLOR
    /* If colour has been turned on read in the settings. */
    env_top = getenv("TOPCOLOURS");
    if (!env_top)
    {
	env_top = getenv("TOPCOLORS");
    }
    /* must do something about error messages */
    color_env_parse(env_top);
    color_activate(gstate->use_color);
#endif

    /* in order to support forward compatability, we have to ensure that
       the entire statics structure is set to a known value before we call
       machine_init.  This way fields that a module does not know about
       will retain their default values */
    memzero((void *)&statics, sizeof(statics));
    statics.boottime = -1;

    /* call the platform-specific init */
    if (machine_init(&statics) == -1)
    {
	exit(EX_SOFTWARE);
    }

    /* create a helper list of sort order names */
    gstate->order_namelist = string_list(statics.order_names);

    /* look up chosen sorting order */
    if (gstate->order_name != NULL)
    {
	int i;

	if (statics.order_names == NULL)
	{
	    message_error(" This platform does not support arbitrary ordering");
	}
	else if ((i = string_index(gstate->order_name,
				   statics.order_names)) == -1)
	{
	    message_error(" Sort order `%s' not recognized", gstate->order_name);
	    message_error(" Recognized sort orders: %s", gstate->order_namelist);
	}
	else
	{
	    gstate->order_index = i;
	}
    }

    /* initialize extensions */
    init_username();

    /* initialize termcap */
    gstate->smart_terminal = screen_readtermcap(gstate->interactive);

    /* determine interactive state */
    if (gstate->interactive == Maybe)
    {
	gstate->interactive = smart_terminal;
    }

    /* if displays were not specified, choose an appropriate default */
    if (gstate->displays == 0)
    {
	gstate->displays = gstate->smart_terminal ? Infinity: 1;
    }

    /* we don't need a mini display when delay is less than 2
       seconds or when we are not on a smart terminal */
    if (gstate->delay <= 1 || !smart_terminal)
    {
	need_mini = 0;
    }

    /* set constants for username/uid display */
    if (gstate->show_usernames)
    {
	gstate->header_text = format_header("USERNAME");
	gstate->get_userid = username;
    }
    else
    {
	gstate->header_text = format_header("   UID  ");
	gstate->get_userid = itoa7;
    }
    gstate->pselect.usernames = gstate->show_usernames;

    /* initialize display */
    if ((gstate->max_topn = display_init(&statics)) == -1)
    {
	fprintf(stderr, "%s: can't allocate sufficient memory\n", myname);
	exit(EX_OSERR);
    }

    /* check for infinity and for overflowed screen */
    if (gstate->topn == Infinity)
    {
	gstate->topn = INT_MAX;
    }
    else if (gstate->topn > gstate->max_topn)
    {
#if 0
	message_error(" This terminal can only display %d processes",
		      gstate->max_topn);
#endif
    }

#ifdef ENABLE_COLOR
    /* producing a list of color tags is easy */
    if (gstate->show_tags)
    {
	color_dump(stdout);
	exit(EX_OK);
    }
#endif

    /* hold all signals while we initialize the screen */
    mask = hold_signals();
    screen_init();

    /* set the signal handlers */
    set_signals();

    /* longjmp re-entry point */
    /* set the jump buffer for long jumps out of signal handlers */
    if (setjmp(jmp_int) != 0)
    {
	/* this is where we end up after processing sigwinch or sigtstp */

	/* tell display to resize its buffers, and get the new length */
	if ((gstate->max_topn = display_resize()) == -1)
	{
	    /* thats bad */
	    quit(EX_OSERR);
	    /*NOTREACHED*/
	}

	/* set up for a full redraw, and get the current line count */
	gstate->fulldraw = Yes;

	/* safe to release the signals now */
	release_signals(mask);
    }
    else
    {
	/* release the signals */
	release_signals(mask);

	/* some systems require a warmup */
	/* always do a warmup for batch mode */
	if (gstate->interactive == 0 || statics.flags.warmup)
	{
	    struct system_info system_info;
	    struct timeval timeout;

	    time_mark(&(gstate->now));
	    get_system_info(&system_info);
	    (void)get_process_info(&system_info, &gstate->pselect, 0);
	    timeout.tv_sec = 1;
	    timeout.tv_usec = 0;
	    select(0, NULL, NULL, NULL, &timeout);

	    /* if we've warmed up, then we can show good states too */
	    gstate->show_cpustates = Yes;
	    need_mini = 0;
	}
    }

    /* main loop */
    while ((gstate->displays == -1) || (--gstate->displays > 0))
    {
	do_display(gstate);
	if (gstate->interactive)
	{
	    if (need_mini)
	    {
		do_minidisplay(gstate);
		need_mini = 0;
	    }
	    do_command(gstate);
	}
	else
	{
	    do_wait(gstate);
	}
    }

    /* do one last display */
    do_display(gstate);

    quit(EX_OK);
    /* NOTREACHED */
    return 1; /* Keep compiler quiet. */
}
Ejemplo n.º 4
0
void logger::run()
{
    utxx::signal_block block_signals(m_block_signals);

    if (m_on_before_run)
        m_on_before_run();

    if (!m_ident.empty())
        pthread_setname_np(pthread_self(), m_ident.c_str());

    int event_val;
    do
    {
        event_val = m_event.value();
        //wakeup_result rc = wakeup_result::TIMEDOUT;

        while (!m_abort && m_queue.empty()) {
            m_event.wait(&m_wait_timeout, &event_val);

            ASYNC_DEBUG_TRACE(
                ("  %s LOGGER awakened (res=%s, val=%d, futex=%d), abort=%d, head=%s\n",
                 timestamp::to_string().c_str(), to_string(rc).c_str(),
                 event_val, m_event.value(), m_abort,
                 m_queue.empty() ? "empty" : "data")
            );
        }

        // When running with maximum priority, occasionally excessive use of
        // sched_yield may use to system slowdown, so this option is
        // configurable by m_sched_yield_us:
        if (m_queue.empty() && m_sched_yield_us >= 0) {
            time_val deadline(rel_time(0, m_sched_yield_us));
            while (m_queue.empty()) {
                if (m_abort)
                    goto DONE;
                if (now_utc() > deadline)
                    break;
                sched_yield();
            }
        }

        // Get all pending items from the queue
        for (auto* item = m_queue.pop_all(), *next=item; item; item = next) {
            next = item->next();

            try   {
                dolog_msg(item->data());
            }
            catch ( std::exception const& e  )
            {
                // Unhandled error writing data to some destination
                // Print error report to stderr (can't do anything better --
                // the error happened in the m_on_error callback!)
                const msg msg(LEVEL_INFO, "",
                              std::string("Fatal exception in logger"),
                              UTXX_LOG_SRCINFO);
                detail::basic_buffered_print<1024> buf;
                char  pfx[256], sfx[256];
                char* p = format_header(msg, pfx, pfx + sizeof(pfx));
                char* q = format_footer(msg, sfx, sfx + sizeof(sfx));
                auto ps = p - pfx;
                auto qs = q - sfx;
                buf.reserve(msg.m_fun.str.size() + ps + qs + 1);
                buf.sprint(pfx, ps);
                buf.print(msg.m_fun.str);
                buf.sprint(sfx, qs);
                std::cerr << buf.str() << std::endl;

                m_abort = true;

                // TODO: implement attempt to store transient messages to some
                // other medium

                // Free all pending messages
                while (item) {
                    m_queue.free(item);
                    item = next;
                    next = item->next();
                }

                goto DONE;
            }

            m_queue.free(item);
            item = next;
        }
    } while (!m_abort);

DONE:
    if (!m_silent_finish) {
        const msg msg(LEVEL_INFO, "", std::string("Logger thread finished"),
                      UTXX_LOG_SRCINFO);
        try {
            dolog_msg(msg);
        }
        catch (...) {}
    }

    if (m_on_after_run)
        m_on_after_run();
}