C++程序  |  143行  |  2.49 KB

/*
 * Copyright 2008 Google Inc. All Rights Reserved.
 * Author: md@google.com (Michael Davidson)
 */
#define _GNU_SOURCE	/* for cpu_set macros */

#include <sched.h>
#include <stdlib.h>
#include <stdio.h>
#include "cpuset.h"
#include "logging.h"

/*
 * Return the number of cpus in a cpu_set
 */
int count_cpus(const cpu_set_t *cpus)
{
	int	count	= 0;
	int	cpu;

	for (cpu = 0; cpu < CPU_SETSIZE; cpu++)
		if (CPU_ISSET(cpu, cpus))
			++count;

	return count;
}

/*
 * Parse a string containing a comma separated list of ranges
 * of cpu numbers such as: "0,2,4-7" into a cpu_set_t.
 */
int parse_cpu_set(const char *s, cpu_set_t *cpus)
{
	CPU_ZERO(cpus);

	while (*s) {
		char	*next;
		int	cpu;
		int	start, end;

		start = end = (int)strtol(s, &next, 0);
		if (s == next)
			break;
		s = next;

		if (*s == '-') {
			++s;
			end = (int)strtol(s, &next, 0);
			if (s == next)
				break;
			s = next;
		}

		if (*s == ',')
			++s;

		if (start < 0 || start >= CPU_SETSIZE) {
			ERROR(0, "bad cpu number '%d' in cpu set", start);
			return 1;
		}

		if (end < 0 || end >= CPU_SETSIZE) {
			ERROR(0, "bad cpu number '%d' in cpu set", end);
			return 1;
		}

		if (end < start) {
			ERROR(0, "bad range '%d-%d' in cpu set", start, end);
			return 1;
		}

		for (cpu = start; cpu <= end; ++cpu)
			CPU_SET(cpu, cpus);

	}

	if (*s) {
		ERROR(0, "unexpected character '%c' in cpu set", *s);
		return 1;
	}

	return 0;
}


static int show_range(char *buf, size_t len, const char *prefix,
			int start, int end)
{
	int	n;

	if (start == end)
		n = snprintf(buf, len, "%s%d", prefix, start);
	else
		n = snprintf(buf, len, "%s%d-%d", prefix, start, end);

	if (n < len)
		return n;

	return -1;
}

/*
 * Turn a cpu_set_t into a human readable string containing a
 * comma separated list of ranges of cpu numbers.
 *
 * Returns the number of bytes written to the buffer,
 * not including the terminating '\0' character,
 * or -1 if there was not enough space in the  buffer.
 */
int show_cpu_set(char *buf, size_t len, const cpu_set_t *cpus)
{
	char	*bufp	= buf;
	int	start	= -1;
	int	end	= -1;
	char	*sep	= "";
	int	cpu;

	for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
		if (CPU_ISSET(cpu, cpus)) {
			if (start < 0)
				start = cpu;
			end = cpu;
		} else if (start >= 0) {
			int	n;
			if ((n = show_range(bufp, len, sep, start, end)) < 0)
				return -1;
			len -= n;
			bufp += n;
			sep = ",";
			start = end = -1;
		}
	}

	if (start >= 0) {
		int	n;
		if ((n = show_range(bufp, len, sep, start, end)) < 0)
			return -1;
		bufp += n;
	}

	return bufp - buf;
}