示例#1
0
文件: pset.c 项目: andreiw/polaris
static int
pset(int subcode, long arg1, long arg2, long arg3, long arg4)
{
	switch (subcode) {
	case PSET_CREATE:
		return (pset_create((psetid_t *)arg1));
	case PSET_DESTROY:
		return (pset_destroy((psetid_t)arg1));
	case PSET_ASSIGN:
		return (pset_assign((psetid_t)arg1,
		    (processorid_t)arg2, (psetid_t *)arg3, 0));
	case PSET_INFO:
		return (pset_info((psetid_t)arg1, (int *)arg2,
		    (uint_t *)arg3, (processorid_t *)arg4));
	case PSET_BIND:
		return (pset_bind((psetid_t)arg1, (idtype_t)arg2,
		    (id_t)arg3, (psetid_t *)arg4));
	case PSET_GETLOADAVG:
		return (pset_getloadavg((psetid_t)arg1, (int *)arg2,
		    (int)arg3));
	case PSET_LIST:
		return (pset_list((psetid_t *)arg1, (uint_t *)arg2));
	case PSET_SETATTR:
		return (pset_setattr((psetid_t)arg1, (uint_t)arg2));
	case PSET_GETATTR:
		return (pset_getattr((psetid_t)arg1, (uint_t *)arg2));
	case PSET_ASSIGN_FORCED:
		return (pset_assign((psetid_t)arg1,
		    (processorid_t)arg2, (psetid_t *)arg3, 1));
	default:
		return (set_errno(EINVAL));
	}
}
示例#2
0
/****** shepherd_binding/bind_shepherd_to_pset() *******************************
*  NAME
*     bind_shepherd_to_pset() -- Binds the current process to a processor set. 
*
*  SYNOPSIS
*     static bool bind_shepherd_to_pset(int pset_id) 
*
*  FUNCTION
*     Binds the current shepherd process to an existing processor set. 
*
*  INPUTS
*     int pset_id - Existing processor set id. 
*
*  RESULT
*     static bool - true in case the process was bound false otherwise 
*
*  NOTES
*     MT-NOTE: bind_shepherd_to_pset() is MT safe 
*
*******************************************************************************/
static bool bind_shepherd_to_pset(int pset_id) 
{
   /* try to bind current process to processor set */
   if (pset_bind((psetid_t)pset_id, P_PID, P_MYID, NULL) != 0) {
      /* binding was not successful */
      return false;
   }

   /* successfully bound current process to processor set */
   return true;
}
示例#3
0
/****** shepherd/pset/set_processor_range() ***********************************
*  NAME
*     set_processor_range() -- sets processor range according to string 
*
*  SYNOPSIS
*     int set_processor_range(char *crange, 
*                             int proc_set_num, 
*                             char *err_str) 
*
*  FUNCTION
*     Sets processor range according to string specification.
*     The unique processor set number will be stored in the file
*     "processor_set_number" located in the current working directory.
*
*     Format:
*        n|[n][-[m]],...  , n,m  being int >= 0.
*        no blanks are allowed in between (this is supposed to be 
*        handled by the queue configuration parsing routine)
*
*  INPUTS
*     char *crange     - String specifier of the range. Will be 
*                        modified via strtok internally.
*     int proc_set_num - The base for a unique processor set number.
*                        This number is already supposed to be unique.
*                        for the job (currently the job_id).
*                        set_processor_range() manipulates it to make
*                        sure that it is a unique processor set number. 
*     char *err_str    - The error message string to be used by the
*                        calling routine retuns value != PROC_SET_OK 
*                        Also used for trace messages internally.
*                        Passed to invoked subroutines.
*
*  RESULT
*     int - error state
*        PROC_SET_OK      - Ok
*        PROC_SET_ERROR   - A critical error occurred; either during 
*                           execution of sysmp() calls or as returned 
*                           from range2proc_vec().
*        PROC_SET_WARNING - A non-critical error occurred (e.g. the 
*                           procedure is executed as unpriveliged user)
******************************************************************************/
static int set_processor_range(char *crange, int proc_set_num, char *err_str) 
{
#if defined(__sgi) || defined(ALPHA) 
   int ret;
#endif
   FILE *fp;
#if defined(__sgi) || defined(ALPHA)
   sbv_t proc_vec;
#endif

#if defined(__sgi) || defined(ALPHA)
   if ((ret=range2proc_vec(crange, &proc_vec, err_str)))
      return ret;
#endif

#if defined(ALPHA)
   /* It is not possible to bind processor #0 to other psets than pset #0
    * So if we get a pset with #0 contained in the range we do nothing. 
    * The process gets not bound to a processor but it is guaranteed
    * that no other job will get processor #0 exclusively. It is upon 
    * the administrator to prevent overlapping of the psets in different
    * queues 
    */
   if (!(proc_vec & 1)) { /* processor #0 not contained */
      if ((proc_set_num = create_pset())<0) {
         print_pset_error(proc_set_num); /* prints error to stdout */
         shepherd_trace("MPPS_CREATE: failed to setup a new processor set");
         return PROC_SET_ERROR;
      }

      if (assign_cpu_to_pset(proc_vec, proc_set_num, 0)<0) {
         print_pset_error(proc_set_num); /* prints error to stdout */
         shepherd_trace("MPPS_CREATE: failed assigning processors to processor set");
         return PROC_SET_ERROR;
      }
   } else {
      /* use default pset (id #0) */
      proc_set_num = 0;
   }
#elif defined(SOLARIS64) || defined(SOLARISAMD64)
   /*
    * We do not create a processor set here
    * The system administrator is responsible to do this
    * We read one id from crange. This is the processor-set id we should use.
    */
   if (crange) {
      char *tok, *next;

      if ((tok=strtok(crange, " \t\n"))) {
         proc_set_num = (int) strtol(tok, &next, 10);
         if (next == tok) {
            sprintf(err_str, "wrong processor set id format: %20.20s", crange);
            shepherd_trace(err_str);
            return PROC_SET_ERROR;
         }
      } 
   }
#endif

   /* dump to file for later use */
   if ((fp = fopen("processor_set_number","w"))) {
      fprintf(fp,"%d\n",proc_set_num);
      FCLOSE(fp);
   } else {
      shepherd_trace("MPPS_CREATE: failed creating file processor_set_number");
      return PROC_SET_ERROR;
   }

#if defined(ALPHA)
   /* Now let's assign ourselves to the previously created processor set */
   if (proc_set_num) {
      pid_t pid_list[1];
      pid_list[0] = getpid();
      if (assign_pid_to_pset(pid_list, 1, proc_set_num, PSET_EXCLUSIVE)<0) {
         print_pset_error(proc_set_num); /* prints error to stdout */
         shepherd_trace("MPPS_CREATE: failed assigning processors to processor set");
         return PROC_SET_ERROR;
      }
   }
#elif defined(SOLARIS64) || defined(SOLARISAMD64)
   if (proc_set_num) {
      int local_ret;

      sprintf(err_str,"pset_bind: try to use processorset %d", proc_set_num);
      shepherd_trace(err_str);
      if (pset_bind(proc_set_num, P_PID, P_MYID, NULL)) {
         switch (errno) {
         case EFAULT:
            shepherd_trace("pset_bind: The location pointed to by opset was not"
               " NULL and not writable by the user");
            local_ret = PROC_SET_ERROR;
            break;
         case EINVAL:
            shepherd_trace("pset_bind: invalid processor set was specified");
            local_ret = PROC_SET_ERROR;
            break;
         case EPERM:
            shepherd_trace("pset_bind: The effective user of the calling "
               "process is not super-user");
            local_ret = PROC_SET_ERROR;
            break;
         default:
            sprintf(err_str,"pset_bind: unexpected error - errno=%d", errno);
            shepherd_trace(err_str);
            local_ret = PROC_SET_ERROR;
            break;
         }
         return local_ret;
      }
   }
#endif

   return PROC_SET_OK;
FCLOSE_ERROR:
   shepherd_trace("MPPS_CREATE: failed creating file processor_set_number");
   return PROC_SET_ERROR;
}
示例#4
0
static int
cpustat(void)
{
	cpc_setgrp_t	*accum;
	cpc_set_t	*start;
	int		c, i, retval;
	int		lwps = 0;
	psetid_t	mypset, cpupset;
	char		*errstr;
	cpc_buf_t	**data1, **data2, **scratch;
	int		nreqs;
	kstat_ctl_t	*kc;

	ncpus = (int)sysconf(_SC_NPROCESSORS_CONF);
	if ((gstate = calloc(ncpus, sizeof (*gstate))) == NULL) {
		(void) fprintf(stderr, gettext(
		    "%s: out of heap\n"), opts->pgmname);
		return (1);
	}

	max_chip_id = sysconf(_SC_CPUID_MAX);
	if ((chip_designees = malloc(max_chip_id * sizeof (int))) == NULL) {
		(void) fprintf(stderr, gettext(
		    "%s: out of heap\n"), opts->pgmname);
		return (1);
	}
	for (i = 0; i < max_chip_id; i++)
		chip_designees[i] = -1;

	if (smt) {
		if ((kc = kstat_open()) == NULL) {
			(void) fprintf(stderr, gettext(
			    "%s: kstat_open() failed: %s\n"), opts->pgmname,
			    strerror(errno));
			return (1);
		}
	}

	if (opts->dosoaker)
		if (priocntl(0, 0, PC_GETCID, &fxinfo) == -1) {
			(void) fprintf(stderr, gettext(
			    "%s: couldn't get FX scheduler class: %s\n"),
			    opts->pgmname, strerror(errno));
			return (1);
		}

	/*
	 * Only include processors that are participating in the system
	 */
	for (c = 0, i = 0; i < ncpus; c++) {
		switch (p_online(c, P_STATUS)) {
		case P_ONLINE:
		case P_NOINTR:
			if (smt) {

				gstate[i].chip_id = get_chipid(kc, c);
				if (gstate[i].chip_id != -1 &&
				    chip_designees[gstate[i].chip_id] == -1)
					chip_designees[gstate[i].chip_id] = c;
			}

			gstate[i++].cpuid = c;
			break;
		case P_OFFLINE:
		case P_POWEROFF:
		case P_FAULTED:
		case P_SPARE:
			gstate[i++].cpuid = -1;
			break;
		default:
			gstate[i++].cpuid = -1;
			(void) fprintf(stderr,
			    gettext("%s: cpu%d in unknown state\n"),
			    opts->pgmname, c);
			break;
		case -1:
			break;
		}
	}

	/*
	 * Examine the processor sets; if we're in one, only attempt
	 * to report on the set we're in.
	 */
	if (pset_bind(PS_QUERY, P_PID, P_MYID, &mypset) == -1) {
		errstr = strerror(errno);
		(void) fprintf(stderr, gettext("%s: pset_bind - %s\n"),
		    opts->pgmname, errstr);
	} else {
		for (i = 0; i < ncpus; i++) {
			struct tstate *this = &gstate[i];

			if (this->cpuid == -1)
				continue;

			if (pset_assign(PS_QUERY,
			    this->cpuid, &cpupset) == -1) {
				errstr = strerror(errno);
				(void) fprintf(stderr,
				    gettext("%s: pset_assign - %s\n"),
				    opts->pgmname, errstr);
				continue;
			}

			if (mypset != cpupset)
				this->cpuid = -1;
		}
	}

	if (opts->dotitle)
		print_title(opts->master);
	zerotime();

	for (i = 0; i < ncpus; i++) {
		struct tstate *this = &gstate[i];

		if (this->cpuid == -1)
			continue;
		this->sgrp = cpc_setgrp_clone(opts->master);
		if (this->sgrp == NULL) {
			this->cpuid = -1;
			continue;
		}
		if (thr_create(NULL, 0, gtick, this,
		    THR_BOUND|THR_NEW_LWP, &this->tid) == 0)
			lwps++;
		else {
			(void) fprintf(stderr,
			    gettext("%s: cannot create thread for cpu%d\n"),
			    opts->pgmname, this->cpuid);
			this->status = 4;
		}
	}

	if (lwps != 0)
		for (i = 0; i < ncpus; i++)
			(void) thr_join(gstate[i].tid, NULL, NULL);

	if ((accum = cpc_setgrp_clone(opts->master)) == NULL) {
		(void) fprintf(stderr, gettext("%s: out of heap\n"),
		    opts->pgmname);
		return (1);
	}

	retval = 0;
	for (i = 0; i < ncpus; i++) {
		struct tstate *this = &gstate[i];

		if (this->cpuid == -1)
			continue;
		cpc_setgrp_accum(accum, this->sgrp);
		cpc_setgrp_free(this->sgrp);
		this->sgrp = NULL;
		if (this->status != 0)
			retval = 1;
	}

	cpc_setgrp_reset(accum);
	start = cpc_setgrp_getset(accum);
	do {
		nreqs = cpc_setgrp_getbufs(accum, &data1, &data2, &scratch);
		print_total(lwps, *data1, nreqs, cpc_setgrp_getname(accum));
	} while (cpc_setgrp_nextset(accum) != start);

	cpc_setgrp_free(accum);
	accum = NULL;

	free(gstate);
	return (retval);
}
示例#5
0
int
pr_pset_bind(struct ps_prochandle *Pr, int pset, idtype_t idtype, id_t id,
             int *opset)
{
    sysret_t rval;			/* return value */
    argdes_t argd[5];		/* arg descriptors */
    argdes_t *adp = &argd[0];	/* first argument */
    int error;

    if (Pr == NULL)		/* no subject process */
        return (pset_bind(pset, idtype, id, opset));

    adp->arg_value = PSET_BIND;	/* PSET_BIND */
    adp->arg_object = NULL;
    adp->arg_type = AT_BYVAL;
    adp->arg_inout = AI_INPUT;
    adp->arg_size = 0;
    adp++;

    adp->arg_value = pset;		/* pset */
    adp->arg_object = NULL;
    adp->arg_type = AT_BYVAL;
    adp->arg_inout = AI_INPUT;
    adp->arg_size = 0;
    adp++;

    adp->arg_value = idtype;	/* idtype */
    adp->arg_object = NULL;
    adp->arg_type = AT_BYVAL;
    adp->arg_inout = AI_INPUT;
    adp->arg_size = 0;
    adp++;

    adp->arg_value = id;		/* id */
    adp->arg_object = NULL;
    adp->arg_type = AT_BYVAL;
    adp->arg_inout = AI_INPUT;
    adp->arg_size = 0;
    adp++;

    if (opset == NULL) {
        adp->arg_value = 0;	/* opset */
        adp->arg_object = NULL;
        adp->arg_type = AT_BYVAL;
        adp->arg_inout = AI_INPUT;
        adp->arg_size = 0;
    } else {
        adp->arg_value = 0;
        adp->arg_object = opset;
        adp->arg_type = AT_BYREF;
        adp->arg_inout = AI_INOUT;
        adp->arg_size = sizeof (int);
    }

    error = Psyscall(Pr, &rval, SYS_pset, 5, &argd[0]);

    if (error) {
        errno = (error < 0)? ENOSYS : error;
        return (-1);
    }
    return (rval.sys_rval1);
}