示例#1
0
void execute_string(char *string)
{
	char buf[RESULT_BUF_SIZE];
	int n;

	ec_post_string(string);
	int res = 7;		//means that we have to flush the output.
	while (res == 7) {
		res = ec_resume();
		SKB_DEBUG("\nres = %d\n", res);

		//give back the result and the error messages.
		//in case there is no message, a '.' is still returned
		n = ec_queue_read(1, buf, RESULT_BUF_SIZE);
		if ((n >= 0) && (n < RESULT_BUF_SIZE)) {
			buf[n] = 0;
		}
		SKB_DEBUG("eclipse returned: %s with length %d.\n", buf, n);

		n = ec_queue_read(2, buf, RESULT_BUF_SIZE);
		if ((n >= 0) && (n < RESULT_BUF_SIZE)) {
			buf[n] = 0;
		}
		SKB_DEBUG("eclipse error returned: %s with length %d.\n", buf,
			  n);
	}
}
/*
 * Top level routine to direct suspend/resume of a domain.
 */
void
xen_suspend_domain(void)
{
	extern void rtcsync(void);
	extern hrtime_t hres_last_tick;
	mfn_t start_info_mfn;
	ulong_t flags;
	pfn_t pfn;
	int i;

	/*
	 * Check that we are happy to suspend on this hypervisor.
	 */
	if (xen_hypervisor_supports_solaris(XEN_SUSPEND_CHECK) == 0) {
		cpr_err(CE_WARN, "Cannot suspend on this hypervisor "
		    "version: v%lu.%lu%s, need at least version v3.0.4 or "
		    "-xvm based hypervisor", XENVER_CURRENT(xv_major),
		    XENVER_CURRENT(xv_minor), XENVER_CURRENT(xv_ver));
		return;
	}

	/*
	 * XXPV - Are we definitely OK to suspend by the time we've connected
	 * the handler?
	 */

	cpr_err(CE_NOTE, "Domain suspending for save/migrate");

	SUSPEND_DEBUG("xen_suspend_domain\n");

	/*
	 * suspend interrupts and devices
	 * XXPV - we use suspend/resume for both save/restore domains (like sun
	 * cpr) and for migration.  Would be nice to know the difference if
	 * possible.  For save/restore where down time may be a long time, we
	 * may want to do more of the things that cpr does.  (i.e. notify user
	 * processes, shrink memory footprint for faster restore, etc.)
	 */
	xen_suspend_devices();
	SUSPEND_DEBUG("xenbus_suspend\n");
	xenbus_suspend();

	pfn = hat_getpfnum(kas.a_hat, (caddr_t)xen_info);
	start_info_mfn = pfn_to_mfn(pfn);

	/*
	 * XXPV: cpu hotplug can hold this under a xenbus watch. Are we safe
	 * wrt xenbus being suspended here?
	 */
	mutex_enter(&cpu_lock);

	/*
	 * Suspend must be done on vcpu 0, as no context for other CPUs is
	 * saved.
	 *
	 * XXPV - add to taskq API ?
	 */
	thread_affinity_set(curthread, 0);
	kpreempt_disable();

	SUSPEND_DEBUG("xen_start_migrate\n");
	xen_start_migrate();
	if (ncpus > 1)
		suspend_cpus();

	/*
	 * We can grab the ec_lock as it's a spinlock with a high SPL. Hence
	 * any holder would have dropped it to get through suspend_cpus().
	 */
	mutex_enter(&ec_lock);

	/*
	 * From here on in, we can't take locks.
	 */
	SUSPEND_DEBUG("ec_suspend\n");
	ec_suspend();
	SUSPEND_DEBUG("gnttab_suspend\n");
	gnttab_suspend();

	flags = intr_clear();

	xpv_time_suspend();

	/*
	 * Currently, the hypervisor incorrectly fails to bring back
	 * powered-down VCPUs.  Thus we need to record any powered-down VCPUs
	 * to prevent any attempts to operate on them.  But we have to do this
	 * *after* the very first time we do ec_suspend().
	 */
	for (i = 1; i < ncpus; i++) {
		if (cpu[i] == NULL)
			continue;

		if (cpu_get_state(cpu[i]) == P_POWEROFF)
			CPUSET_ATOMIC_ADD(cpu_suspend_lost_set, i);
	}

	/*
	 * The dom0 save/migrate code doesn't automatically translate
	 * these into PFNs, but expects them to be, so we do it here.
	 * We don't use mfn_to_pfn() because so many OS services have
	 * been disabled at this point.
	 */
	xen_info->store_mfn = mfn_to_pfn_mapping[xen_info->store_mfn];
	xen_info->console.domU.mfn =
	    mfn_to_pfn_mapping[xen_info->console.domU.mfn];

	if (CPU->cpu_m.mcpu_vcpu_info->evtchn_upcall_mask == 0) {
		prom_printf("xen_suspend_domain(): "
		    "CPU->cpu_m.mcpu_vcpu_info->evtchn_upcall_mask not set\n");
		(void) HYPERVISOR_shutdown(SHUTDOWN_crash);
	}

	if (HYPERVISOR_update_va_mapping((uintptr_t)HYPERVISOR_shared_info,
	    0, UVMF_INVLPG)) {
		prom_printf("xen_suspend_domain(): "
		    "HYPERVISOR_update_va_mapping() failed\n");
		(void) HYPERVISOR_shutdown(SHUTDOWN_crash);
	}

	SUSPEND_DEBUG("HYPERVISOR_suspend\n");

	/*
	 * At this point we suspend and sometime later resume.
	 */
	if (HYPERVISOR_suspend(start_info_mfn)) {
		prom_printf("xen_suspend_domain(): "
		    "HYPERVISOR_suspend() failed\n");
		(void) HYPERVISOR_shutdown(SHUTDOWN_crash);
	}

	/*
	 * Point HYPERVISOR_shared_info to its new value.
	 */
	if (HYPERVISOR_update_va_mapping((uintptr_t)HYPERVISOR_shared_info,
	    xen_info->shared_info | PT_NOCONSIST | PT_VALID | PT_WRITABLE,
	    UVMF_INVLPG))
		(void) HYPERVISOR_shutdown(SHUTDOWN_crash);

	if (xen_info->nr_pages != mfn_count) {
		prom_printf("xen_suspend_domain(): number of pages"
		    " changed, was 0x%lx, now 0x%lx\n", mfn_count,
		    xen_info->nr_pages);
		(void) HYPERVISOR_shutdown(SHUTDOWN_crash);
	}

	xpv_time_resume();

	cached_max_mfn = 0;

	SUSPEND_DEBUG("gnttab_resume\n");
	gnttab_resume();

	/* XXPV: add a note that this must be lockless. */
	SUSPEND_DEBUG("ec_resume\n");
	ec_resume();

	intr_restore(flags);

	if (ncpus > 1)
		resume_cpus();

	mutex_exit(&ec_lock);
	xen_end_migrate();
	mutex_exit(&cpu_lock);

	/*
	 * Now we can take locks again.
	 */

	/*
	 * Force the tick value used for tv_nsec in hres_tick() to be up to
	 * date. rtcsync() will reset the hrestime value appropriately.
	 */
	hres_last_tick = xpv_gethrtime();

	/*
	 * XXPV: we need to have resumed the CPUs since this takes locks, but
	 * can remote CPUs see bad state? Presumably yes. Should probably nest
	 * taking of todlock inside of cpu_lock, or vice versa, then provide an
	 * unlocked version.  Probably need to call clkinitf to reset cpu freq
	 * and re-calibrate if we migrated to a different speed cpu.  Also need
	 * to make a (re)init_cpu_info call to update processor info structs
	 * and device tree info.  That remains to be written at the moment.
	 */
	rtcsync();

	rebuild_mfn_list();

	SUSPEND_DEBUG("xenbus_resume\n");
	xenbus_resume();
	SUSPEND_DEBUG("xenbus_resume_devices\n");
	xen_resume_devices();

	thread_affinity_clear(curthread);
	kpreempt_enable();

	SUSPEND_DEBUG("finished xen_suspend_domain\n");

	/*
	 * We have restarted our suspended domain, update the hypervisor
	 * details. NB: This must be done at the end of this function,
	 * since we need the domain to be completely resumed before
	 * these functions will work correctly.
	 */
	xen_set_version(XENVER_CURRENT_IDX);

	/*
	 * We can check and report a warning, but we don't stop the
	 * process.
	 */
	if (xen_hypervisor_supports_solaris(XEN_SUSPEND_CHECK) == 0)
		cmn_err(CE_WARN, "Found hypervisor version: v%lu.%lu%s "
		    "but need at least version v3.0.4",
		    XENVER_CURRENT(xv_major), XENVER_CURRENT(xv_minor),
		    XENVER_CURRENT(xv_ver));

	cmn_err(CE_NOTE, "domain restore/migrate completed");
}
示例#3
0
文件: main.c 项目: huiweics/arrakis
main(int argc, char **argv)
{
    char *	eclipsedir = (char *) 0;
    int		c, new_argc, err;
    int		init_flags = INIT_SHARED|INIT_PRIVATE|INIT_ENGINE|INIT_PROCESS;
    char *	session, * nsrv_hostname;
    unsigned    nsrv_port_number;
    uword	size;

    /*
     * If stdio is not a tty, get rid of the console window. This is not ideal
     * since the window flashes up briefly, but no better solution yet.
     * (The correct way would be not to build eclipse.exe as a "console
     * application" and have a WinMain() instead of main(). But then we have
     * to do all the setup of stdin/out/err, argc/argv, environment etc
     * ourselves)
     */
    if (!isatty(_fileno(stdin))
            && !isatty(_fileno(stdout))
            && !isatty(_fileno(stderr)))
    {
        FreeConsole();
    }

    /*
     * collect information from the command line
     * remove some internally used arguments from the command line
     */
    for (c = new_argc = 1; c < argc; )
    {
        if (argv[c][0] == '-' && argv[c][2] == 0)	/* single char opt */
        {
            switch (argv[c][1])
            {
            case 'a':			/* -a <worker> <session>
                                              <nsrv_hostname> <nsrv_port_no> */
                if (++c + 4 > argc) usage(argv[c-1]);
                ec_set_option_int(EC_OPTION_PARALLEL_WORKER, atoi(argv[c++]));
                session = argv[c++];
                nsrv_hostname = argv[c++];
                nsrv_port_number = atoi(argv[c++]);
                break;

            case 'c':				/* -c <shared_map_file> */
                if (++c + 1 > argc) usage(argv[c-1]);
                ec_set_option_ptr(EC_OPTION_MAPFILE, argv[c++]);
                ec_set_option_int(EC_OPTION_ALLOCATION, ALLOC_FIXED);
                init_flags &= ~INIT_SHARED;
                break;

            case 'm':				/* -m <shared_map_file> */
                if (++c + 1 > argc) usage(argv[c-1]);
                ec_set_option_ptr(EC_OPTION_MAPFILE, argv[c++]);
                ec_set_option_int(EC_OPTION_ALLOCATION, ALLOC_FIXED);
                break;

            case 'b':				/* -b <bootfile> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c++];		/* shift */
                break;

            case 'e':				/* -e <goal> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c++];		/* shift */
                break;

            case 'g':				/* -g <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                size = sizearg(argv[c++]);
                ec_set_option_long(EC_OPTION_GLOBALSIZE, size);
                if (size < MIN_GLOBAL) {
                    fprintf(stderr,"Global stack size out of range\n");
                    exit(-1);
                }
                break;

            case 'd':				/* -d <n> */
                /* delay worker startup by <n> seconds */
                if (++c + 1 > argc) usage(argv[c-1]);
                Sleep(1000 * atoi(argv[c++]));
                break;

            case 'D':				/* -D <eclipsedir> */
                if (++c + 1 > argc) usage(argv[c-1]);
                eclipsedir = argv[c++];
                break;

            case 'l':				/* -l <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                size = sizearg(argv[c++]);
                ec_set_option_long(EC_OPTION_LOCALSIZE, size);
                if (size < MIN_LOCAL) {
                    fprintf(stderr,"Local stack size out of range\n");
                    exit(-1);
                }
                break;

            case 'h':				/* -h <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                size = sizearg(argv[c++]);
                ec_set_option_long(EC_OPTION_PRIVATESIZE, size);
                if (size < MIN_PRIVATE) {
                    fprintf(stderr,"Private heap size out of range\n");
                    exit(-1);
                }
                break;

            case 's':				/* -s <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                size = sizearg(argv[c++]);
                ec_set_option_long(EC_OPTION_SHAREDSIZE, size);
                if (size < MIN_SHARED) {
                    fprintf(stderr,"Shared heap size out of range\n");
                    exit(-1);
                }
                break;

            case 'o':				/* enable oracles */
                c += 1;
                /* vm_options = ORACLES_ENABLED; */
                break;

            case '-':				/* -- give the rest to Prolog */
                for (; c < argc; )
                    argv[new_argc++] = argv[c++];
                break;

            default:				/* unknown: error */
                usage(argv[c]);
                break;
            }
        }
        else if (!strcmp(argv[c], "-debug_level"))
        {
            if (++c + 1 > argc) usage(argv[c-1]);
            ec_set_option_int(EC_OPTION_DEBUG_LEVEL, atoi(argv[c++]));
        }
        else /* raise error unless preceeded by a -- option */
        {
            usage(argv[c]);
        }
    }

    /*----------------------------------------------------------------
     * Entry point after longjmp(reset)
     *----------------------------------------------------------------*/

    switch (setjmp(reset))
    {
    case 0:		/* raw boot or -r from above */
        break;
    case 3:		/* restore program state */
    case 2:
        init_flags = REINIT_SHARED|INIT_ENGINE|INIT_PRIVATE;
        break;
    case 4:		/* restore execution state */
        init_flags = REINIT_SHARED|INIT_PRIVATE;
        break;
    case 1:		/* reset after fatal error */
    default:
        init_flags = INIT_ENGINE;
        switch (memory_corrupted++)
        {
        case 0:
            break;

        case 1:
            /* try to print a message */
            memory_corrupted = 2;
            fprintf(stderr,"\n*** SEPIA Fatal error: memory corrupted\n");
        /* fall to */
        case 2:
            /* we couldn't even print the message */
            exit(-1);
        }
        break;
    }

    /*
     * set up our own panic function which longjumps back to reset
     */
    ec_set_option_ptr(EC_OPTION_PANIC, main_panic);

    ec_set_option_int(EC_OPTION_INIT, init_flags);
    ec_set_option_int(EC_OPTION_ARGC, new_argc);
    ec_set_option_ptr(EC_OPTION_ARGV, argv);
    if (eclipsedir)
        ec_set_option_ptr(EC_OPTION_ECLIPSEDIR, eclipsedir);

    ec_init();
    ec_post_goal(ec_term(ec_did(":",2), ec_atom(ec_did("sepia_kernel",0)),
                         ec_atom(ec_did("standalone_toplevel",0))));
    do {
        err = ec_resume();
    } while (err == PYIELD);
    ec_cleanup();
    return err;
}
示例#4
0
文件: main.c 项目: huiweics/arrakis
int
main(int argc, char **argv)
{
    char	bootfile_buf[MAX_PATH_LEN];
    char *	initfile = (char *) 0;
    char *	eclipsedir = (char *) 0;
    int		c, new_argc;
    pword	goal, module;
    int		err;
    int		init_flags = INIT_SHARED|INIT_PRIVATE|INIT_ENGINE|INIT_PROCESS;
    unsigned	startup_delay = 0;
    int		vm_options = 0;
    char *	session, * nsrv_hostname;
    unsigned    nsrv_port_number;

#ifdef PROFILE
    moncontrol(0);	/* disable profiling by default */
#endif

    /*
     * collect information from the command line
     * remove some internally used arguments from the command line
     */
    for (c = new_argc = 1; c < argc; )
    {
        if (argv[c][0] == '-' && argv[c][2] == 0)	/* single char opt */
        {
            switch (argv[c][1])
            {
            case 'a':			/* -a <worker> <session>
                                              <nsrv_hostname> <nsrv_port_no> */
                if (++c + 4 > argc) usage(argv[c-1]);
                ec_options.parallel_worker = atoi(argv[c++]);
                session = argv[c++];
                nsrv_hostname = argv[c++];
                nsrv_port_number = atoi(argv[c++]);
                break;

            case 'c':				/* -c <shared_map_file> */
                if (++c + 1 > argc) usage(argv[c-1]);
                ec_options.mapfile = argv[c++];
                ec_options.allocation = ALLOC_FIXED;
                init_flags &= ~INIT_SHARED;
                break;

            case 'm':				/* -m <shared_map_file> */
                if (++c + 1 > argc) usage(argv[c-1]);
                ec_options.mapfile = argv[c++];
                ec_options.allocation = ALLOC_FIXED;
                break;

            case 'b':				/* -b <bootfile> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c++];		/* shift */
                break;

            case 'e':				/* -e <goal> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c++];		/* shift */
                break;

            case 'g':				/* -g <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                ec_options.globalsize = sizearg(argv[c++]);
                if (ec_options.globalsize < MIN_GLOBAL) {
                    ec_bad_exit("ECLiPSe: Global stack size out of range.");
                }
                break;

            case 'd':				/* -d <n> */
                /* delay worker startup by <n> seconds */
                if (++c + 1 > argc) usage(argv[c-1]);
                startup_delay = atoi(argv[c++]);
                if (startup_delay == 0)
                    ec_options.io_option = OWN_IO;	/* every worker has its own i/o */
                else
                    sleep(startup_delay);
                break;

            case 'D':				/* -D <eclipsedir> */
                if (++c + 1 > argc) usage(argv[c-1]);
                eclipsedir = argv[c++];
                break;

            case 'l':				/* -l <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                ec_options.localsize = sizearg(argv[c++]);
                if (ec_options.localsize < MIN_LOCAL) {
                    ec_bad_exit("ECLiPSe: local stack size out of range.");
                }
                break;

            case 'h':				/* -h <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                ec_options.privatesize = sizearg(argv[c++]);
                if (ec_options.privatesize < MIN_PRIVATE) {
                    ec_bad_exit("ECLiPSe: Private heap size out of range.");
                }
                break;

            case 's':				/* -s <size> */
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-1]);
                argv[new_argc++] = argv[c];		/* shift */
                ec_options.sharedsize = sizearg(argv[c++]);
                if (ec_options.sharedsize < MIN_SHARED) {
                    ec_bad_exit("ECLiPSe: Shared heap size out of range.");
                }
                break;

            case 'o':				/* enable oracles */
                c += 1;
                vm_options = ORACLES_ENABLED;
                break;

            case 'p':
                argv[new_argc++] = argv[c];		/* shift */
                if (++c + 1 > argc) usage(argv[c-2]);
                argv[new_argc++] = argv[c];		/* shift */
                ec_options.option_p = atoi(argv[c++]);
                break;

            case '-':				/* -- give the rest to Prolog */
                for (; c < argc;)
                    argv[new_argc++] = argv[c++];
                break;

            default:				/* unknown: error */
                usage(argv[c]);
                break;
            }
        }
        else if (!strcmp(argv[c], "-debug_level"))
        {
            if (++c + 1 > argc) usage(argv[c-1]);
            ec_options.debug_level = atoi(argv[c++]);
        }
        else if (!strcmp(argv[c], "-layout"))
        {
            int	lflags = 0;
            char	*from = 0;
            char	*to = 0;
            long	increment = 0L;

            if (++c + 1 <= argc)
                lflags = (int) strtol(argv[c++], (char **) 0, 16);
            if (c + 1 <= argc)
                increment = strtol(argv[c++], (char **) 0, 16);
            if (c + 1 <= argc)
                from = (char *) strtol(argv[c++], (char **) 0, 16);
            if (c + 1 <= argc)
                to = (char *) strtol(argv[c++], (char **) 0, 16);

            if (ec_options.allocation == ALLOC_FIXED)
                mem_layout();
#ifdef HAVE_MMAP
            ec_layout(lflags, from, to, increment);
#else
            ec_bad_exit("ECLiPSe: The -layout scan is not supported without\nmemory mapping.");
#endif
        }
        else if (!strcmp(argv[c], "-norl"))
        {
            argv[new_argc++] = argv[c++];		/* shift */
            ec_options.rl = 0;
        }
        else /* raise error unless preceeded by a -- option */
        {
            usage(argv[c]);
        }
    }

    /*----------------------------------------------------------------
     * Initialize private heap as early as possible
     * (must be before setup_mps())
     *----------------------------------------------------------------*/
    malloc_init();
    irq_lock_init(delayed_break);

    /*----------------------------------------------------------------
     * Init message passing system
     *----------------------------------------------------------------*/
    if (ec_options.parallel_worker)
    {
        setup_mps(ec_options.parallel_worker, session, nsrv_hostname,
                  nsrv_port_number, init_flags & INIT_SHARED);
    }

    /*----------------------------------------------------------------
     * Make the connection to the shared heap, if any.
     * Because of mmap problems on some machines this should
     * happen AFTER initializing the message passing system.
     *----------------------------------------------------------------*/
    mem_init(init_flags);	/* depends on -c and -m options */


    /*----------------------------------------------------------------
     * Init parallel scheduler etc.
     *----------------------------------------------------------------*/
    if (ec_options.parallel_worker)
    {
        parallel_init(init_flags);
    }

    /*----------------------------------------------------------------
     * Init the low-level I/O stuff, ie the part which should
     * really not be done by eclipse itself...
     *----------------------------------------------------------------*/
    /* char_io_init();  does not yet exist */


    /*----------------------------------------------------------------
     * Entry point after longjmp(reset)
     *----------------------------------------------------------------*/

    switch (setjmp(reset))
    {
    case 0:		/* raw boot or -r from above */
        break;
    case 3:		/* restore program state */
    case 2:
        init_flags = REINIT_SHARED|INIT_ENGINE|INIT_PRIVATE;
        break;
    case 4:		/* restore execution state */
        init_flags = REINIT_SHARED|INIT_PRIVATE;
        break;
    case 1:		/* reset after fatal error */
    default:
        if (!(GlobalFlags & HEAP_READY) || ec_options.parallel_worker)
        {
            (void) ec_cleanup();
            exit(-1);
        }
        init_flags = INIT_ENGINE;
        switch (memory_corrupted++)
        {
        case 0:
            break;

        case 1:
            /* try to print a message */
            memory_corrupted = 2;
            ec_bad_exit("ECLiPSe: Fatal error, memory corrupted.");
        /* fall to */
        case 2:
            /* we couldn't even print the message */
            exit(-1);
        }
        break;
    }


    /*
     * set up our own panic function which longjumps back to reset
     * To access command line through global variabes
     */
    ec_options.user_panic = main_panic;
    ec_options.Argc = new_argc;
    ec_options.Argv = argv;
    ec_options.eclipse_home = (char *) 0;
    ec_options.init_flags = init_flags;
    if (eclipsedir)
        ec_options.eclipse_home = eclipsedir;


    /*
     * Init the global (shared) eclipse structures, dictionary, code...
     * Maybe load a saved state.
     * Note that we don't have an engine yet!
     */

    eclipse_global_init(init_flags);


    /*----------------------------------------------------------------
     * Setup the Prolog engine
     *----------------------------------------------------------------*/

    /*
     * If we have a PROG_AND_DATA saved state (execution state saved)
     * we are finished and enter the emulator.
     */
    if (!(init_flags & INIT_ENGINE))
    {
        err = restart_emulc();
        (void) ec_cleanup();
        exit(err);
    }

    /*
     * Initialize the Prolog engine
     */
    emu_init(init_flags, vm_options);

    /*
     * If we are not running an already booted eclipse,
     * compile $ECLIPSEDIR/lib/kernel.eco
     */
    if (init_flags & INIT_SHARED)
    {
        char msg[1024];

        initfile = strcat(strcpy(bootfile_buf, ec_eclipse_home), "/lib/kernel.eco");
        if (ec_access(initfile, R_OK) < 0)
        {
            sprintf(msg,
                    "ECLiPSe: Can't find boot file %s!\nPlease check the setting of your ECLIPSEDIR environment variable\nor use the -D <dir> command line option.",
                    initfile);
            ec_bad_exit(msg);
        }

        err = eclipse_boot(initfile);
        if (err != PSUCCEED)
        {
            (void) ec_cleanup();
            exit(err);
        }
    }

    if (init_flags & (INIT_SHARED|REINIT_SHARED))
        GlobalFlags |= HEAP_READY;	/* for the other workers */

    goal = ec_term(ec_did("main",1), ec_long(init_flags & INIT_SHARED ? 0 : 1));
    module.val.did = d_.kernel_sepia;
    module.tag.kernel = ModuleTag(d_.kernel_sepia);

    if (ec_options.parallel_worker <= 1)	/* only or first worker */
    {
        err = main_emulc_noexit(goal.val, goal.tag, module.val, module.tag);
        if (err == PYIELD)
        {
            memory_corrupted = 0;	/* assume it's ok */
            ec_post_goal(ec_term(ec_did(":",2), ec_atom(ec_did("sepia_kernel",0)),
                                 ec_atom(ec_did("standalone_toplevel",0))));
            do {
                err = ec_resume();
            } while (err == PYIELD);
        }
    }
    else
    {
        err = slave_emulc();
    }
    ec_cleanup();
    exit(err);
    /*NOTREACHED*/
}
示例#5
0
/*
 * Top level routine to direct suspend/resume of a domain.
 */
void
xen_suspend_domain(void)
{
	extern void rtcsync(void);
	extern void ec_resume(void);
	extern kmutex_t ec_lock;
	struct xen_add_to_physmap xatp;
	ulong_t flags;
	int err;

	cmn_err(CE_NOTE, "Domain suspending for save/migrate");

	SUSPEND_DEBUG("xen_suspend_domain\n");

	/*
	 * We only want to suspend the PV devices, since the emulated devices
	 * are suspended by saving the emulated device state.  The PV devices
	 * are all children of the xpvd nexus device.  So we search the
	 * device tree for the xpvd node to use as the root of the tree to
	 * be suspended.
	 */
	if (xpvd_dip == NULL)
		ddi_walk_devs(ddi_root_node(), check_xpvd, NULL);

	/*
	 * suspend interrupts and devices
	 */
	if (xpvd_dip != NULL)
		(void) xen_suspend_devices(ddi_get_child(xpvd_dip));
	else
		cmn_err(CE_WARN, "No PV devices found to suspend");
	SUSPEND_DEBUG("xenbus_suspend\n");
	xenbus_suspend();

	mutex_enter(&cpu_lock);

	/*
	 * Suspend on vcpu 0
	 */
	thread_affinity_set(curthread, 0);
	kpreempt_disable();

	if (ncpus > 1)
		pause_cpus(NULL, NULL);
	/*
	 * We can grab the ec_lock as it's a spinlock with a high SPL. Hence
	 * any holder would have dropped it to get through pause_cpus().
	 */
	mutex_enter(&ec_lock);

	/*
	 * From here on in, we can't take locks.
	 */

	flags = intr_clear();

	SUSPEND_DEBUG("HYPERVISOR_suspend\n");
	/*
	 * At this point we suspend and sometime later resume.
	 * Note that this call may return with an indication of a cancelled
	 * for now no matter ehat the return we do a full resume of all
	 * suspended drivers, etc.
	 */
	(void) HYPERVISOR_shutdown(SHUTDOWN_suspend);

	/*
	 * Point HYPERVISOR_shared_info to the proper place.
	 */
	xatp.domid = DOMID_SELF;
	xatp.idx = 0;
	xatp.space = XENMAPSPACE_shared_info;
	xatp.gpfn = xen_shared_info_frame;
	if ((err = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) != 0)
		panic("Could not set shared_info page. error: %d", err);

	SUSPEND_DEBUG("gnttab_resume\n");
	gnttab_resume();

	SUSPEND_DEBUG("ec_resume\n");
	ec_resume();

	intr_restore(flags);

	if (ncpus > 1)
		start_cpus();

	mutex_exit(&ec_lock);
	mutex_exit(&cpu_lock);

	/*
	 * Now we can take locks again.
	 */

	rtcsync();

	SUSPEND_DEBUG("xenbus_resume\n");
	xenbus_resume();
	SUSPEND_DEBUG("xen_resume_devices\n");
	if (xpvd_dip != NULL)
		(void) xen_resume_devices(ddi_get_child(xpvd_dip), 0);

	thread_affinity_clear(curthread);
	kpreempt_enable();

	SUSPEND_DEBUG("finished xen_suspend_domain\n");

	cmn_err(CE_NOTE, "domain restore/migrate completed");
}