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; }
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); }