changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: add dtracy.h

changeset 6879: 4c688bc1d170
parent 6878: bbfa4ca306a8
child 6880: 3aa5b6f3982c
author: aiju
date: Sat, 10 Nov 2018 20:01:19 +0000
files: sys/include/dtracy.h
description: add dtracy.h
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/include/dtracy.h
     1.4@@ -0,0 +1,245 @@
     1.5+#pragma lib "libdtracy.a"
     1.6+#pragma src "/sys/src/libdtracy"
     1.7+
     1.8+/*
     1.9+	triggered probes run in "probe context", which involves grabbing a per-CPU lock using dtmachlock/dtmachunlock.
    1.10+	everything else in the library assumes that the calling code has grabbed a global lock (which is done in 9/port/devtracy.c).
    1.11+*/
    1.12+
    1.13+enum {
    1.14+	DTSTRMAX = 256,
    1.15+	DTRECMAX = 1024,
    1.16+};
    1.17+
    1.18+typedef struct DTName DTName;
    1.19+typedef struct DTProbe DTProbe;
    1.20+typedef struct DTExprState DTExprState;
    1.21+typedef struct DTAct DTAct;
    1.22+typedef struct DTActGr DTActGr;
    1.23+typedef struct DTClause DTClause;
    1.24+typedef struct DTEnab DTEnab;
    1.25+typedef struct DTChan DTChan;
    1.26+typedef struct DTExpr DTExpr;
    1.27+typedef struct DTProvider DTProvider;
    1.28+typedef struct DTBuf DTBuf;
    1.29+
    1.30+struct DTName {
    1.31+	char *provider;
    1.32+	char *function;
    1.33+	char *name;
    1.34+};
    1.35+
    1.36+/*
    1.37+	we assign all pairs (probe,action-group) (called an enabling or DTEnab) a unique ID.
    1.38+	we could also use probe IDs and action group IDs but using a single 32-bit ID for both is more flexible/efficient.
    1.39+*/
    1.40+struct DTEnab {
    1.41+	u32int epid;
    1.42+	DTActGr *gr;
    1.43+	DTEnab *probnext, *probprev;
    1.44+	DTEnab *channext;
    1.45+	DTProbe *prob;
    1.46+};
    1.47+
    1.48+/* probes are never freed */
    1.49+struct DTProbe {
    1.50+	int nenable;
    1.51+	DTName;
    1.52+	DTEnab enablist;
    1.53+	DTProvider *prov;
    1.54+	void *aux; /* for the provider */
    1.55+	DTProbe *provnext;
    1.56+};
    1.57+
    1.58+struct DTProvider {
    1.59+	char *name;
    1.60+	/*
    1.61+		provide() is called when the user asks for a probe that doesn't exist.
    1.62+		provide() should call dtpnew() to create probes.
    1.63+		it can use the DTName as a hint or just create all probes that it knows about.
    1.64+		the provider has to ensure not to create the same probe multiple times.
    1.65+	*/
    1.66+	void (*provide)(DTProvider *, DTName);
    1.67+	int (*enable)(DTProbe *); /* enable the probe. return >= 0 for success and < 0 for failure */
    1.68+	void (*disable)(DTProbe *); /* disable the probe */
    1.69+	
    1.70+	/* for the library, not the provider */
    1.71+	DTProbe *probes;
    1.72+};
    1.73+
    1.74+/*
    1.75+	the dtracy vm is a simple RISC machine with (currently) 16 64-bit registers.
    1.76+	all operations are 64-bit.
    1.77+
    1.78+	instruction encoding:
    1.79+	31:24 opcode
    1.80+	23:16 a
    1.81+	15:8 b
    1.82+	7:0 c
    1.83+*/
    1.84+
    1.85+enum {
    1.86+	/* Rc = Ra (op) Rb */
    1.87+	DTE_ADD = 0x00,
    1.88+	DTE_SUB = 0x01,
    1.89+	DTE_MUL = 0x02,
    1.90+	DTE_SDIV = 0x03,
    1.91+	DTE_SMOD = 0x04,
    1.92+	DTE_UDIV = 0x05,
    1.93+	DTE_UMOD = 0x06,
    1.94+	DTE_AND = 0x07,
    1.95+	DTE_OR = 0x08,
    1.96+	DTE_XOR = 0x09,
    1.97+	DTE_XNOR = 0x0A,
    1.98+	DTE_LSL = 0x0B, /* logical shift left */
    1.99+	DTE_LSR = 0x0C, /* logical shift right */
   1.100+	DTE_ASR = 0x0D, /* arithmetic shift right */
   1.101+	DTE_SEQ = 0x10, /* set if equal */
   1.102+	DTE_SNE = 0x11, /* set if not equal */
   1.103+	DTE_SLT = 0x12, /* set if less than */
   1.104+	DTE_SLE = 0x13, /* set if less or equal */
   1.105+	
   1.106+	/* immediate operations, const = 10 top bits of ab, sign extended and shifted left by 6 bottom bits */
   1.107+	DTE_LDI = 0x20, /* Rc = const */
   1.108+	DTE_XORI = 0x21, /* Rc = Rc ^ const */
   1.109+
   1.110+	/* if(Ra (op) Rb) PC += c; */
   1.111+	DTE_BEQ = 0x30,
   1.112+	DTE_BNE = 0x31,
   1.113+	DTE_BLT = 0x32,
   1.114+	DTE_BLE = 0x33,
   1.115+	
   1.116+	DTE_LDV = 0x40, /* R[b] = Var[a] */
   1.117+	
   1.118+	DTE_ZXT = 0x50, /* R[c] = lower b bits of R[a], zero extended, 0 < b <= 64 */
   1.119+	DTE_SXT = 0x51, /* R[c] = lower b bits of R[a], sign extended, 0 < b <= 64 */
   1.120+	
   1.121+	DTE_RET = 0xF0, /* RET Ra */
   1.122+};
   1.123+#define DTE(op,a,b,c) ((op)<<24|(a)<<16|(b)<<8|(c))
   1.124+
   1.125+struct DTExpr {
   1.126+	int n;
   1.127+	u32int *b;
   1.128+};
   1.129+
   1.130+/* an action is an expression, plus info about what to do with the result */
   1.131+struct DTAct {
   1.132+	enum {
   1.133+		ACTTRACE, /* record the result. size is the number of bytes used. 0 <= size <= 8 */
   1.134+		ACTTRACESTR, /* take the result to be a pointer to a null-terminated string. store it as zero-padded char[size]. */
   1.135+	} type;
   1.136+	DTExpr *p;
   1.137+	int size;
   1.138+};
   1.139+
   1.140+/* an action group is an optional predicate and a set of actions. */
   1.141+struct DTActGr {
   1.142+	u32int id;
   1.143+	int ref;
   1.144+	DTExpr *pred; /* if non-nil and evaluates to 0, skip the actions. */
   1.145+	int nact;
   1.146+	DTAct *acts;
   1.147+	DTChan *chan;
   1.148+	int reclen; /* record size, including 12-byte header */
   1.149+};
   1.150+
   1.151+/* a clause list probe wildcard expressions and an action group. only used during set-up. */
   1.152+struct DTClause {
   1.153+	int nprob;
   1.154+	char **probs;
   1.155+	DTActGr *gr;
   1.156+};
   1.157+
   1.158+enum { DTBUFSZ = 65536 };
   1.159+struct DTBuf {
   1.160+	int wr;
   1.161+	uchar data[DTBUFSZ];
   1.162+};
   1.163+
   1.164+/* a chan is the kernel representation of a client. */
   1.165+struct DTChan {
   1.166+	enum {
   1.167+		DTCSTOP,
   1.168+		DTCGO,
   1.169+		DTCFAULT,
   1.170+	} state;
   1.171+	char errstr[64];
   1.172+	u32int epidalloc; /* lowest unused EPID */
   1.173+	
   1.174+	/* we have 2 buffers per cpu, one for writing and one for reading. dtcread() swaps them if empty. */
   1.175+	DTBuf **wrbufs;
   1.176+	DTBuf **rdbufs;
   1.177+	
   1.178+	/* list of enablings. */
   1.179+	DTEnab *enab;
   1.180+};
   1.181+
   1.182+void dtinit(int);
   1.183+void dtsync(void);
   1.184+
   1.185+/* probe functions */
   1.186+DTProbe *dtpnew(DTName, DTProvider *, void *aux);
   1.187+int dtpmatch(DTName, DTProbe ***);
   1.188+void dtptrigger(DTProbe *, int, uvlong, uvlong, uvlong, uvlong);
   1.189+
   1.190+/* expression functions */
   1.191+int dteverify(DTExpr *);
   1.192+int dtefmt(Fmt *);
   1.193+#pragma varargck type "I" u32int
   1.194+
   1.195+/* action group functions */
   1.196+void dtgpack(Fmt *, DTActGr *);
   1.197+char *dtgunpack(char *, DTActGr **);
   1.198+int dtgverify(DTActGr *);
   1.199+void dtgfree(DTActGr *);
   1.200+
   1.201+/* clause functions */
   1.202+void dtclpack(Fmt *, DTClause *);
   1.203+char *dtclunpack(char *, DTClause **);
   1.204+void dtclfree(DTClause *);
   1.205+
   1.206+/* chan functions */
   1.207+DTChan *dtcnew(void);
   1.208+void dtcfree(DTChan *);
   1.209+int dtcaddgr(DTChan *, DTName, DTActGr *);
   1.210+int dtcaddcl(DTChan *, DTClause *);
   1.211+int dtcread(DTChan *, void *, int);
   1.212+void dtcreset(DTChan *);
   1.213+void dtcrun(DTChan *, int);
   1.214+
   1.215+extern DTProvider *dtproviders[];
   1.216+extern int dtnmach;
   1.217+
   1.218+/* helper */
   1.219+char *dtstrdup(char *);
   1.220+
   1.221+/* these functions are provided by the kernel interface */
   1.222+uvlong dttime(void); /* return current timestamp */
   1.223+void *dtrealloc(void *, ulong);
   1.224+void dtfree(void *);
   1.225+void *dtmalloc(ulong);
   1.226+void dtmachlock(int); /* lock the per-cpu lock */
   1.227+void dtmachunlock(int); /* unlock the per-cpu lock */
   1.228+void dtcoherence(void); /* memory barrier */
   1.229+uvlong dtgetvar(int); /* return the value of a variable */
   1.230+int dtpeek(uvlong, void*, int); /* safe memmemove(). returns -1 on error. */
   1.231+
   1.232+enum {
   1.233+	DTV_ARG0,
   1.234+	DTV_ARG1,
   1.235+	DTV_ARG2,
   1.236+	DTV_ARG3,
   1.237+	DTV_ARG4,
   1.238+	DTV_ARG5,
   1.239+	DTV_ARG6,
   1.240+	DTV_ARG7,
   1.241+	DTV_ARG8,
   1.242+	DTV_ARG9,
   1.243+	DTV_PID,
   1.244+	DTV_MACHNO,
   1.245+	DTV_TIME,
   1.246+	DTV_PROBE,
   1.247+	DTNVARS,
   1.248+};
   1.249+extern char *dtvarnames[DTNVARS];