Ejemplo n.º 1
0
int GPTL_PAPIsetoption (const int counter,  /* PAPI counter (or option) */
			const int val)      /* true or false for enable or disable */
{
  int n;       /* loop index */
  int ret;     /* return code */
  int numidx;  /* numerator index */
  int idx;     /* derived counter index */
  char eventname[PAPI_MAX_STR_LEN]; /* returned from PAPI_event_code_to_name */

  /*
  ** First, check for option which is not an actual counter
  */

  switch (counter) {
  case GPTLverbose:
  /* don't printf here--that'd duplicate what's in gptl.c */
    verbose = (bool) val;
    return 0;
  case GPTLmultiplex:
    enable_multiplexing = (bool) val;
    if (verbose)
      printf ("GPTL_PAPIsetoption: boolean enable_multiplexing = %d\n", val);
    return 0;
  case GPTLnarrowprint:
    narrowprint = (bool) val;
    if (verbose)
      printf ("GPTL_PAPIsetoption: boolean narrowprint = %d\n", val);
    return 0;
  case GPTLpersec:
    persec = (bool) val;
    if (verbose)
      printf ("GPTL_PAPIsetoption: boolean persec = %d\n", val);
    return 0;
  default:
    break;
  }

  /* 
  ** If val is false, return an error if the event has already been enabled.
  ** Otherwise just warn that attempting to disable a PAPI-based event
  ** that has already been enabled doesn't work--for now it's just a no-op
  */

  if (! val) {
    if (already_enabled (counter))
      return GPTLerror ("GPTL_PAPIsetoption: already enabled counter %d cannot be disabled\n",
			counter);
    else
      if (verbose)
	printf ("GPTL_PAPIsetoption: 'disable' %d currently is just a no-op\n", counter);
    return 0;
  }

  /* If the event has already been enabled for printing, exit */

  if (already_enabled (counter))
    return GPTLerror ("GPTL_PAPIsetoption: counter %d has already been enabled\n", 
		      counter);

  /* 
  ** Initialize PAPI if it hasn't already been done.
  ** From here on down we can assume the intent is to enable (not disable) an option
  */

  if (GPTL_PAPIlibraryinit () < 0)
    return GPTLerror ("GPTL_PAPIsetoption: PAPI library init error\n");

  /* Ensure max nevents won't be exceeded */

  if (nevents+1 > MAX_AUX)
    return GPTLerror ("GPTL_PAPIsetoption: %d is too many events. Can be increased in private.h\n",
		      nevents+1);

  /* Check derived events */

  switch (counter) {
  case GPTL_IPC:
    if ( ! canenable2 (PAPI_TOT_INS, PAPI_TOT_CYC))
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_IPC unavailable\n");

    idx = getderivedidx (GPTL_IPC);
    pr_event[nevents].event    = derivedtable[idx];
    pr_event[nevents].numidx   = enable (PAPI_TOT_INS);
    pr_event[nevents].denomidx = enable (PAPI_TOT_CYC);
    if (verbose)
      printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_TOT_INS / PAPI_TOT_CYC\n", 
	      pr_event[nevents].event.namestr);
    ++nevents;
    return 0;
  case GPTL_CI:
    idx = getderivedidx (GPTL_CI);
    if (canenable2 (PAPI_FP_OPS, PAPI_LST_INS)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_FP_OPS);
      pr_event[nevents].denomidx = enable (PAPI_LST_INS);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_FP_OPS / PAPI_LST_INS\n", 
		pr_event[nevents].event.namestr);
    } else if (canenable2 (PAPI_FP_OPS, PAPI_L1_DCA)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_FP_OPS);
      pr_event[nevents].denomidx = enable (PAPI_L1_DCA);
#ifdef DEBUG
      printf ("GPTL_PAPIsetoption: pr_event %d is derived and will be PAPI event %d / %d\n", 
	      nevents, pr_event[nevents].numidx, pr_event[nevents].denomidx);
#endif
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_FP_OPS / PAPI_L1_DCA\n", 
		pr_event[nevents].event.namestr);
    } else {
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_CI unavailable\n");
    }
    ++nevents;
    return 0;
  case GPTL_FPC:
    if ( ! canenable2 (PAPI_FP_OPS, PAPI_TOT_CYC))
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_FPC unavailable\n");

    idx = getderivedidx (GPTL_FPC);
    pr_event[nevents].event    = derivedtable[idx];
    pr_event[nevents].numidx   = enable (PAPI_FP_OPS);
    pr_event[nevents].denomidx = enable (PAPI_TOT_CYC);
    if (verbose)
      printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_FP_OPS / PAPI_TOT_CYC\n", 
	      pr_event[nevents].event.namestr);
    ++nevents;
    return 0;
  case GPTL_FPI:
    if ( ! canenable2 (PAPI_FP_OPS, PAPI_TOT_INS))
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_FPI unavailable\n");

    idx = getderivedidx (GPTL_FPI);
    pr_event[nevents].event    = derivedtable[idx];
    pr_event[nevents].numidx   = enable (PAPI_FP_OPS);
    pr_event[nevents].denomidx = enable (PAPI_TOT_INS);
    if (verbose)
      printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_FP_OPS / PAPI_TOT_INS\n", 
	      pr_event[nevents].event.namestr);
    ++nevents;
    return 0;
  case GPTL_LSTPI:
    idx = getderivedidx (GPTL_LSTPI);
    if (canenable2 (PAPI_LST_INS, PAPI_TOT_INS)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_LST_INS);
      pr_event[nevents].denomidx = enable (PAPI_TOT_INS);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_LST_INS / PAPI_TOT_INS\n", 
		pr_event[nevents].event.namestr);
    } else if (canenable2 (PAPI_L1_DCA, PAPI_TOT_INS)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_L1_DCA);
      pr_event[nevents].denomidx = enable (PAPI_TOT_INS);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_L1_DCA / PAPI_TOT_INS\n", 
		pr_event[nevents].event.namestr);
    } else {
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_LSTPI unavailable\n");
    }
    ++nevents;
    return 0;
  case GPTL_DCMRT:
    if ( ! canenable2 (PAPI_L1_DCM, PAPI_L1_DCA))
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_DCMRT unavailable\n");

    idx = getderivedidx (GPTL_DCMRT);
    pr_event[nevents].event    = derivedtable[idx];
    pr_event[nevents].numidx   = enable (PAPI_L1_DCM);
    pr_event[nevents].denomidx = enable (PAPI_L1_DCA);
    if (verbose)
      printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_L1_DCM / PAPI_L1_DCA\n", 
	      pr_event[nevents].event.namestr);
    ++nevents;
    return 0;
  case GPTL_LSTPDCM:
    idx = getderivedidx (GPTL_LSTPDCM);
    if (canenable2 (PAPI_LST_INS, PAPI_L1_DCM)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_LST_INS);
      pr_event[nevents].denomidx = enable (PAPI_L1_DCM);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_LST_INS / PAPI_L1_DCM\n", 
		pr_event[nevents].event.namestr);
    } else if (canenable2 (PAPI_L1_DCA, PAPI_L1_DCM)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_L1_DCA);
      pr_event[nevents].denomidx = enable (PAPI_L1_DCM);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_L1_DCA / PAPI_L1_DCM\n", 
		pr_event[nevents].event.namestr);
    } else {
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_LSTPDCM unavailable\n");
    }
    ++nevents;
    return 0;
    /*
    ** For L2 counts, use TC* instead of DC* to avoid PAPI derived events
    */
  case GPTL_L2MRT:
    if ( ! canenable2 (PAPI_L2_TCM, PAPI_L2_TCA))
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_L2MRT unavailable\n");

    idx = getderivedidx (GPTL_L2MRT);
    pr_event[nevents].event    = derivedtable[idx];
    pr_event[nevents].numidx   = enable (PAPI_L2_TCM);
    pr_event[nevents].denomidx = enable (PAPI_L2_TCA);
    if (verbose)
      printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_L2_TCM / PAPI_L2_TCA\n", 
	      pr_event[nevents].event.namestr);
    ++nevents;
    return 0;
  case GPTL_LSTPL2M:
    idx = getderivedidx (GPTL_LSTPL2M);
    if (canenable2 (PAPI_LST_INS, PAPI_L2_TCM)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_LST_INS);
      pr_event[nevents].denomidx = enable (PAPI_L2_TCM);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_LST_INS / PAPI_L2_TCM\n", 
		pr_event[nevents].event.namestr);
    } else if (canenable2 (PAPI_L1_DCA, PAPI_L2_TCM)) {
      pr_event[nevents].event    = derivedtable[idx];
      pr_event[nevents].numidx   = enable (PAPI_L1_DCA);
      pr_event[nevents].denomidx = enable (PAPI_L2_TCM);
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_L1_DCA / PAPI_L2_TCM\n", 
		pr_event[nevents].event.namestr);
    } else {
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_LSTPL2M unavailable\n");
    }
    ++nevents;
    return 0;
  case GPTL_L3MRT:
    if ( ! canenable2 (PAPI_L3_TCM, PAPI_L3_TCR))
      return GPTLerror ("GPTL_PAPIsetoption: GPTL_L3MRT unavailable\n");

    idx = getderivedidx (GPTL_L3MRT);
    pr_event[nevents].event    = derivedtable[idx];
    pr_event[nevents].numidx   = enable (PAPI_L3_TCM);
    pr_event[nevents].denomidx = enable (PAPI_L3_TCR);
    if (verbose)
      printf ("GPTL_PAPIsetoption: enabling derived event %s = PAPI_L3_TCM / PAPI_L3_TCR\n", 
	      pr_event[nevents].event.namestr);
    ++nevents;
    return 0;
  default:
    break;
  }

  /* Check PAPI presets */

  for (n = 0; n < npapientries; n++) {
    if (counter == papitable[n].counter) {
      if ((numidx = papievent_is_enabled (counter)) >= 0) {
	pr_event[nevents].event  = papitable[n];
	pr_event[nevents].numidx = numidx;
	pr_event[nevents].denomidx = -1;     /* flag says not derived (no denominator) */
      } else if (canenable (counter)) {
	pr_event[nevents].event  = papitable[n];
	pr_event[nevents].numidx = enable (counter);
	pr_event[nevents].denomidx = -1;     /* flag says not derived (no denominator) */
      } else {
	return GPTLerror ("GPTL_PAPIsetoption: Can't enable event \n", 
			  papitable[n].longstr);
      }
      if (verbose)
	printf ("GPTL_PAPIsetoption: enabling PAPI preset event %s\n", 
		pr_event[nevents].event.namestr);
      ++nevents;
      return 0;
    }
  }

  /*
  ** Check native events last: If PAPI_event_code_to_name fails, give up
  */
  
  if ((ret = PAPI_event_code_to_name (counter, eventname)) != PAPI_OK)
    return GPTLerror ("GPTL_PAPIsetoption: name not found for counter %d: PAPI_strerror: %s\n", 
		      counter, PAPI_strerror (ret));

  /*
  ** A table with predefined names of various lengths does not exist for
  ** native events. Just truncate eventname.
  */

  if ((numidx = papievent_is_enabled (counter)) >= 0) {
    pr_event[nevents].event.counter = counter;

    pr_event[nevents].event.namestr = (char *) GPTLallocate (12+1);
    strncpy (pr_event[nevents].event.namestr, eventname, 12);
    pr_event[nevents].event.namestr[12] = '\0';

    pr_event[nevents].event.str16 = (char *) GPTLallocate (16+1);
    strncpy (pr_event[nevents].event.str16, eventname, 16);
    pr_event[nevents].event.str16[16] = '\0';

    pr_event[nevents].event.longstr = (char *) GPTLallocate (PAPI_MAX_STR_LEN);
    strncpy (pr_event[nevents].event.longstr, eventname, PAPI_MAX_STR_LEN);

    pr_event[nevents].numidx = numidx;
    pr_event[nevents].denomidx = -1;     /* flag says not derived (no denominator) */
  } else if (canenable (counter)) {
    pr_event[nevents].event.counter = counter;

    pr_event[nevents].event.namestr = (char *) GPTLallocate (12+1);
    strncpy (pr_event[nevents].event.namestr, eventname, 12);
    pr_event[nevents].event.namestr[12] = '\0';

    pr_event[nevents].event.str16 = (char *) GPTLallocate (16+1);
    strncpy (pr_event[nevents].event.str16, eventname, 16);
    pr_event[nevents].event.str16[16] = '\0';

    pr_event[nevents].event.longstr = (char *) GPTLallocate (PAPI_MAX_STR_LEN);
    strncpy (pr_event[nevents].event.longstr, eventname, PAPI_MAX_STR_LEN);

    pr_event[nevents].numidx = enable (counter);
    pr_event[nevents].denomidx = -1;     /* flag says not derived (no denominator) */
  } else {
    return GPTLerror ("GPTL_PAPIsetoption: Can't enable event %s\n", eventname);
  }

  if (verbose)
    printf ("GPTL_PAPIsetoption: enabling native event %s\n", pr_event[nevents].event.longstr);

  ++nevents;
  return 0;
}
Ejemplo n.º 2
0
static streamscall __hot_put int
ptem_wput(queue_t *q, mblk_t *mp)
{
	struct ptem *p = PTEM_PRIV(q);

	/* fast path */
	if (likely(mp->b_datap->db_type == M_DATA)) {
	      m_data:
		/* free zero-length messages */
		if (msgdsize(mp) != 0) {
			if ((p->flags & PTEM_OUTPUT_STOPPED)
			    || (q->q_first != NULL)
			    || (q->q_flag & QSVCBUSY)
			    || (!bcanputnext(q, mp->b_band))) {
				/* Note, the only reason for failinng putq() is the lack of a queue 
				   band, in which case the band is empty and no loss of order will
				   result from putting it to the next queue. */
				if (putq(q, mp))
					return (0);
			}
			putnext(q, mp);
			return (0);
		}
		freemsg(mp);
		return (0);
	}

	switch (mp->b_datap->db_type) {
	case M_DATA:
		goto m_data;
	case M_IOCTL:
	{
		struct iocblk *ioc = (struct iocblk *) mp->b_rptr;

		/* The Stream head is set to recognized all transparent terminal input-output
		   controls and pass them downstream as though they were I_STR input-output
		   controls.  There is also the opportunity to register input-output controls with
		   the Stream head using the TIOC_REPLY message. */
		if (unlikely(ioc->ioc_count == TRANSPARENT))
			goto do_it;

		switch (ioc->ioc_cmd) {
		case TCSETAW:
		case TCSETAF:
		case TCSETSW:
		case TCSETSF:
		case TCSBRK:
			/* These need to wait for the output to drain before being processed, queue 
			   them. */
			putq(q, mp);
			break;
		default:
			/* Process others immediately, regardless of whether there is any data or
			   other messages in queue. */
			goto do_it;
		}
		break;
	}
	case M_DELAY:
	case M_READ:
		freemsg(mp);
		break;
	case M_STOP:
		if (canenable(q)) {
			noenable(q);
			p->flags |= PTEM_OUTPUT_STOPPED;
		}
		putnext(q, mp);
		break;
	case M_START:
		if (!canenable(q)) {
			p->flags &= ~PTEM_OUTPUT_STOPPED;
			enableok(q);
			qenable(q);
		}
		putnext(q, mp);
		break;
	case M_STOPI:
	case M_STARTI:
		/* We have no read side queue so we cannot queue in this direction.  Tell master so 
		   that pckt(4) can tell master not to send anything more. */
		putnext(q, mp);
		break;
	default:
	      do_it:
		if (ptem_w_msg(q, mp) && !putq(q, mp))
			freemsg(mp);
		break;
	}
	return (0);
}