Beispiel #1
0
/*
 * Open connection to xenstore.
 *
 * @pollfds defines of signal-handling descriptors to be watched
 * if has to wait.
 *
 * Will not touch pollfds[NPFD_XS].
 */
static void open_xs_connection(struct pollfd *pollfds)
{
	struct timespec ts0;
	int64_t wsec;
	bool displayed_msg = false;
	int k;

	/*
	 * If we are running as a daemon during system startup, there
	 * can be a race condition with continuing Xen initialization
	 * (/proc/xen including /proc/xen/privcmd may be unavailable yet,
	 * still to be created even though Xen service startup completion
	 * has already been signalled), so wait for a while if necessary.
	 */
	for (ts0 = getnow();;)
	{
		if (!xs)
			xs = xs_open(0);
		if (xs)
			break;

		/* time since the start */
		wsec = timespec_diff_ms(getnow(), ts0) / MSEC_PER_SEC;

		if (run_as_daemon && wsec < max_xen_init_retries)
		{
			if (wsec >= xen_init_retry_msg && !displayed_msg)
			{
				notice_msg("waiting for Xen to initialize");
				displayed_msg = true;
			}

			if (pollfds != NULL)
			{
				int npollfds = NPFD_COUNT - 1;
				for (k = 0;  k < npollfds;  k++)
					pollfds[k].revents = 0;
				if (poll(pollfds, npollfds, 1 * MSEC_PER_SEC) < 0)
					fatal_perror("poll");
				handle_signals(pollfds, NULL);
			}
			else
			{
				sleep(1);
			}
		}
		else
		{
			fatal_perror("unable to open connection to xenstore");
		}
	}
}
Beispiel #2
0
int  dfs(int w)  
{  
    int now,x,y,k;  
    if (w==cnt) return 1;  
    now=getnow();  
    if (now==-1)
    {
        printf("now==-1\n");
        return 0;}  
  
    x=order[now].x;  
    y=order[now].y;  
    for (k=1;k<=9;k++)  
        if (order[now].candidate[k])  //如果k这个数字是可以填 
        {  
            row[x][k]=1;  
            col[y][k]=1;  
            block[x/3*3+y/3][k]=1;  
            table[x][y]=k;  
  
            updata();  
            if (dfs(w+1)==1) return 1;  
  
            row[x][k]=0;  
            col[y][k]=0;  
            block[x/3*3+y/3][k]=0;  
            table[x][y]=0;  
  
            updata();  
        }  
  
    return 0;  //一个好使的解都没有找到,直接返回0 
}  
Beispiel #3
0
/*
 * Read memory statistics data
 */
static void get_paging_data(struct paging_data *pd)
{
	static const char *key_pgpgin = "pgpgin";
	static const char *key_nr_free_pages = "nr_free_pages";
	static const char parse_error_msg[] = "error parsing /proc/vmstat";
	char *cp, *xp;
	bool found_pgpgin = false;
	bool found_nr_free_pages = false;
	int nfound = 0;
	const int need_found = 2;

	pd->ts = getnow();

	pd->mem_pages = sysconf(_SC_PHYS_PAGES);
	if (pd->mem_pages <= 0)
		fatal_msg("unable to get system memory size");

	read_whole_file("/proc/vmstat", &vmstat, &vmstat_size, 4096);

	for (cp = vmstat; *cp != '\0';)
	{
		if (is_key(&cp, key_pgpgin))
		{
			if (!consume_umax(&cp, &pd->pgpgin))
				fatal_msg(parse_error_msg);

			if (!found_pgpgin)
			{
				found_pgpgin = true;
				if (need_found == ++nfound)
					break;
			}
		}
		else if (is_key(&cp, key_nr_free_pages))
		{
			if (!consume_umax(&cp, &pd->nr_free_pages))
				fatal_msg(parse_error_msg);

			if (!found_nr_free_pages)
			{
				found_nr_free_pages = true;
				if (need_found == ++nfound)
					break;
			}
		}
		else
		{
			xp = strchr(cp, '\n');
			if (!xp) break;
			cp = xp + 1;
		}
	}

	if (need_found != nfound)
		fatal_msg(parse_error_msg);
}
Beispiel #4
0
int
rpl_nanosleep (const struct timespec *requested_delay,
	       struct timespec *remaining_delay)
{
  /* nanosleep mishandles large sleeps due to internal overflow
     problems, so check that the proper amount of time has actually
     elapsed.  */

  struct timespec delay = *requested_delay;
  struct timespec t0;
  getnow (&t0);

  for (;;)
    {
      int r = nanosleep (&delay, remaining_delay);
      if (r == 0)
	{
	  time_t secs_sofar;
	  struct timespec now;
	  getnow (&now);

	  secs_sofar = now.tv_sec - t0.tv_sec;
	  if (requested_delay->tv_sec < secs_sofar)
	    return 0;
	  delay.tv_sec = requested_delay->tv_sec - secs_sofar;
	  delay.tv_nsec = requested_delay->tv_nsec - (now.tv_nsec - t0.tv_nsec);
	  if (delay.tv_nsec < 0)
	    {
	      if (delay.tv_sec == 0)
		return 0;
	      delay.tv_nsec += BILLION;
	      delay.tv_sec--;
	    }
	  else if (BILLION <= delay.tv_nsec)
	    {
	      delay.tv_nsec -= BILLION;
	      delay.tv_sec++;
	    }
	}
    }
}
Beispiel #5
0
void execute(const struct command *commands, size_t mlen, const uint8_t *cores,
	     size_t rlen)
{
	uint64_t *times = alloca(mlen * sizeof(uint64_t));
	uint64_t start = getnow(), now, next;
	struct timespec ts;
	msrval_t *values;
	msradr_t *addresses;

	values = alloca(mlen * rlen * sizeof (msrval_t));
	addresses = alloca(mlen * rlen * sizeof (msradr_t));
	
	print_header(commands, mlen, cores, rlen);

	signal(SIGINT, handle_signal);
	signal(SIGTERM, handle_signal);
	signal(SIGQUIT, handle_signal);
	
	setup_start_data(addresses, commands, mlen, rlen);
	setup_next_data(values, commands, mlen, rlen);
	setup_start_times(times, commands, mlen, start);

	while (!stopped) {
		now = getnow();

		apply_commands(values, addresses, times, commands, mlen, cores,
			       rlen, now);

		print_data(times, values, commands, mlen, rlen, start, now);

		next = setup_next_times(times, commands, mlen, now);
		if (next == ~(0ul))
			break;
		setup_next_data(values, commands, mlen, rlen);

		ts.tv_sec  =  (next - now)             / 1000;
		ts.tv_nsec = ((next - now) - ts.tv_sec * 1000) * 1000000;
		nanosleep(&ts, NULL);
	}
}
Beispiel #6
0
void *sh_timeradd(unsigned long msec,int flags,void (*action)(void*),void *handle) 
{
	register Timer_t *tp;
	double t;
	Handler_t fn;
	t = ((double)msec)/1000.;
	if(t<=0 || !action)
		return((void*)0);
	if(tp=tpfree)
		tpfree = tp->next;
	else if(!(tp=(Timer_t*)malloc(sizeof(Timer_t))))
		return((void*)0);
	tp->wakeup = getnow() + t;
	tp->incr = (flags?t:0);
	tp->action = action;
	tp->handle = handle;
	time_state |= IN_ADDTIMEOUT;
	tp->next = tptop;
	tptop = tp;
	if(!tpmin || tp->wakeup < tpmin->wakeup)
	{
		tpmin = tp;
		fn = (Handler_t)signal(SIGALRM,sigalrm);
		if((t= setalarm(t))>0 && fn  && fn!=(Handler_t)sigalrm)
		{
			Handler_t *hp = (Handler_t*)malloc(sizeof(Handler_t));
			if(hp)
			{
				*hp = fn;
				sh_timeradd((long)(1000*t), 0, oldalrm, (void*)hp);
			}
		}
		tp = tptop;
	}
	else if(tpmin && !tpmin->action)
		time_state |= DEFER_SIGALRM;
	time_state &= ~IN_ADDTIMEOUT;
	if(time_state&DEFER_SIGALRM)
	{
		time_state=SIGALRM_CALL;
		sigalrm(SIGALRM);
		if(tp!=tptop)
			tp=0;
	}
	return((void*)tp);
}
Beispiel #7
0
/* signal handler for alarm call */
static void sigalrm(int sig)
{
	register Timer_t *tp, *tplast, *tpold, *tpnext;
	double now;
	static double left;
	NOT_USED(sig);
	left = 0;
	if(time_state&SIGALRM_CALL)
		time_state &= ~SIGALRM_CALL;
	else if(alarm(0))
		sh_fault(SIGALRM|SH_TRAP);
	if(time_state)
	{
		if(time_state&IN_ADDTIMEOUT)
			time_state |= DEFER_SIGALRM;
		errno = EINTR;
		return;
	}
	time_state |= IN_SIGALRM;
	sigrelease(SIGALRM);
	while(1)
	{
		now = getnow();
		tpold = tpmin = 0;
		for(tplast=0,tp=tptop; tp; tp=tpnext)
		{
			tpnext = tp->next;
			if(tp->action)
			{
				if(tp->wakeup <=now)
				{
					if(!tpold || tpold->wakeup>tp->wakeup)
						tpold = tp;
				}
				else
				{
					if(!tpmin || tpmin->wakeup>tp->wakeup)
						tpmin=tp;
				}
				tplast = tp;
			}
			else
			{
				if(tplast)
					tplast->next = tp->next;
				else
					tptop = tp->next;
				tp->next = tpfree;
				tpfree = tp;
			}
		}
		if((tp=tpold) && tp->incr)
		{
			while((tp->wakeup += tp->incr) <= now);
			if(!tpmin || tpmin->wakeup>tp->wakeup)
				tpmin=tp;
		}
		if(tpmin && (left==0 || (tp && tpmin->wakeup < (now+left))))
		{
			if(left==0)
				signal(SIGALRM,sigalrm);
			left = setalarm(tpmin->wakeup-now);
			if(left && (now+left) < tpmin->wakeup)
				setalarm(left);
			else
				left=tpmin->wakeup-now;
		}
		if(tp)
		{
			void	(*action)(void*);
			action = tp->action;
			if(!tp->incr)
				tp->action = 0;
			errno = EINTR;
			time_state &= ~IN_SIGALRM;
			(*action)(tp->handle);
			time_state |= IN_SIGALRM;
		}
		else
			break;
	}
	if(!tpmin)
		signal(SIGALRM,(sh.sigflag[SIGALRM]&SH_SIGFAULT)?sh_fault:SIG_DFL);
	time_state &= ~IN_SIGALRM;
	errno = EINTR;
}
Beispiel #8
0
size_t get_worker(void) {
	// get a worker
	// off, so we don't check worker 0 a million times
	static size_t off = -1;
	static int tries = 0;
	++off;
	int which;
	for(which=0;which<numworkers;++which) {
		size_t derp = (which+off)%numworkers;
		switch(workers[derp].status) {
		case IDLE:
			workers[derp].status = BUSY;
			PFD(derp).events = POLLIN;
			tries = 0;
			return derp;
		};
	}

	if(tries < 3) {
		++tries;
		// if we timeout 3 times, stop waiting for idle workers.
		return -1;
	}

	/* no idle found, try starting some workers */
	if(numworkers < MAXWORKERS) {
		// add a worker to the end
		if(start_worker()) {
			tries = 0;
			return numworkers-1;
		}
	} else {
		reap_workers();
		for(which=0;which<numworkers;++which) {
			if(workers[which].status == DOOMED) {
				/*
					if 995 ns left (expiration - now) and doom delay is 1000ns
					1000 - 995 < 50, so wait a teensy bit longer please
				*/
				Time diff = timediff(DOOM_DELAY,
														 timediff(workers[which].expiration,
																			getnow()));
				if(diff.tv_nsec > 50) {
					// waited too long, kill the thing.
					kill_worker(which);
					if(start_worker()) {
						tries = 0;
						return numworkers-1;
					}
				}
			}
		}
	}
	if(wait_for_accept()) {
		if(accept_workers()) {
			return get_worker();
		}
	}
	// have to wait until the new worker connects
	errno = EAGAIN; // eh
	return -1;
}
Beispiel #9
0
void stop_worker(int which) {
	workers[which].status = DOOMED;
	workers[which].expiration = timeadd(getnow(),DOOM_DELAY);
	kill(workers[which].pid,SIGTERM);
	reap_workers();
}
Beispiel #10
0
int main(int argc, char **argv)
{
	sigset_t sigmask;
	struct pollfd pollfds[NPFD_COUNT];
	int npollfds;
	int k;
	int64_t wait_ms;
	struct paging_data pd0;
	struct paging_data pd1;
	bool recheck_time;
	int init_pass = 0;

	/*
	 * if running interactively, output initially to the terminal,
	 * otherwise to syslog right away
	 */
	if (isatty(fileno(stderr)))
	{
		log_fp = stderr;
		log_syslog = false;
	}
	else
	{
		log_fp = NULL;
		log_syslog = true;
	}

	if (log_syslog)
		openlog(progname, LOG_CONS | LOG_PID, LOG_DAEMON);

	/* parse arguments */
	handle_cmdline(argc, argv);

	if (run_as_daemon)
		daemonize();

	debug_msg(1, "debug level set to %d", debug_level);

	// page_size = sysconf(_SC_PAGESIZE);
	// if (page_size <= 0)
	//	fatal_msg("unable to get system page size");

	/*
	 * Block signals so that they aren't handled according to their
	 * default dispositions
	 */
	sigemptyset(&sigmask);
	sigaddset(&sigmask, SIGHUP);
	sigaddset(&sigmask, SIGTERM);
        if (sigprocmask(SIG_BLOCK, &sigmask, NULL) < 0)
		fatal_perror("sigprocmask");

	/*
	 * Receive signals on file descriptors
	 */
	sigemptyset(&sigmask);
	sigaddset(&sigmask, SIGHUP);
	fd_sighup = signalfd(-1, &sigmask, 0);
	if (fd_sighup < 0)
		fatal_perror("signalfd(SIGHUP)");

	sigemptyset(&sigmask);
	sigaddset(&sigmask, SIGTERM);
	fd_sigterm = signalfd(-1, &sigmask, 0);
	if (fd_sigterm < 0)
		fatal_perror("signalfd(SIGTERM)");

	/* select clock to use */
	select_clk_id();

	/* verify we are running under a hypervisor */
	verify_hypervisor();

	pollfds[NPFD_SIGTERM].fd = fd_sigterm;
	pollfds[NPFD_SIGTERM].events = POLLIN|POLLPRI;

	pollfds[NPFD_SIGHUP].fd = fd_sighup;
	pollfds[NPFD_SIGHUP].events = POLLIN|POLLPRI;

	/* keep xs poll fd last in the array */
	pollfds[NPFD_XS].fd = -1;
	pollfds[NPFD_XS].events = POLLIN|POLLPRI;

	/* initialize xenstore structure */
	initialize_xs(pollfds);
	pollfds[NPFD_XS].fd = xs_fileno(xs);

	get_paging_data(&pd0);

        for (;;)
	{
		try_subscribe_membalance_settings();

		/* calculate sleep time till next sample point */
		if (initialized_xs)
		{
			wait_ms = timespec_diff_ms(pd0.ts, getnow()) + interval * MSEC_PER_SEC;
		}
		else
		{
			/* if xs not initialzied, keep retrying */
			wait_ms = interval * MSEC_PER_SEC;
			if (++init_pass > 30)
				wait_ms *= 2;
		}

		if (wait_ms >= tolerance_ms)
		{
			for (k = 0;  k < countof(pollfds);  k++)
				pollfds[k].revents = 0;

			/* if settings need to be updated, retry in 1 sec or sooner */
			if (need_update_membalance_settings)
				wait_ms = min(wait_ms, MSEC_PER_SEC);

			/* include xs in the poll only if has initialized xs */
			npollfds = countof(pollfds);
			if (!initialized_xs)
				npollfds--;

			if (poll(pollfds, npollfds, wait_ms) < 0)
			{
				if (errno == EINTR)
					continue;
				fatal_perror("poll");
			}

			recheck_time = false;

			handle_signals(pollfds, &recheck_time);

			if (!initialized_xs)
			{
				/* try to initialzie xs */
				initialize_xs(NULL);
				/* if successful, start monitoring page map-in rate */
				if (initialized_xs)
					get_paging_data(&pd0);
				continue;
			}

			if (pollfds[NPFD_XS].revents & (POLLIN|POLLPRI))
			{
				/* a watched value in xenstore has been changed */
				handle_xs_watch();
				recheck_time = true;
			}

			if (need_update_membalance_settings)
				update_membalance_settings();

			if (recheck_time)
			{
				/* go sleep again if wait interval has not expired yet */
				if (timespec_diff_ms(getnow(), pd0.ts) < interval * MSEC_PER_SEC - tolerance_ms)
					continue;
			}
		}

		if (!initialized_xs)
		{
			/* try to initialzie xs */
			initialize_xs(NULL);
			/* if successful, start monitoring page map-in rate */
			if (initialized_xs)
				get_paging_data(&pd0);
			continue;
		}

		/* process sample and set it as the new "previous" one */
		get_paging_data(&pd1);
		process_sample(&pd1, &pd0);
		pd0 = pd1;
	}

	/* close connection to xenstore */
	shutdown_xs();

	return EXIT_SUCCESS;
}