ソースを参照

multiple probes

Tobias Waldekranz.com 8 年 前
コミット
4010352e86
共有6 個のファイルを変更した160 個の追加30 個の削除を含む
  1. 28 0
      global.c
  2. 4 0
      node.h
  3. 116 25
      ply.c
  4. 4 0
      ply.h
  5. 5 4
      sym.c
  6. 3 1
      sym.h

+ 28 - 0
global.c

@@ -63,6 +63,31 @@ type_t t_quantize_func = {
63 63
 
64 64
 type_t *ts_quantize[] = { &t_u64_64, &t_quantize_t, &t_quantize_func, NULL };
65 65
 
66
+
67
+/* time */
68
+
69
+type_t t_time_t = {
70
+	.ttype = T_TYPEDEF,
71
+
72
+	.t.tdef = {
73
+		.name = "__ply_time_t",
74
+		.type = &t_u32,
75
+	},
76
+};
77
+
78
+type_t t_time_func = {
79
+	.ttype = T_FUNC,
80
+
81
+	.t.func = {
82
+		.name = "time",
83
+		.type = &t_time_t,
84
+		.args = NULL,
85
+	},
86
+};
87
+
88
+type_t *ts_time[] = { &t_time_t, &t_time_func, NULL };
89
+
90
+
66 91
 int global_resolve(prog_t *prog, node_t *n)
67 92
 {
68 93
 	type_t **ts = NULL;
@@ -75,6 +100,9 @@ int global_resolve(prog_t *prog, node_t *n)
75 100
 	} else if (!strcmp(n->ident, "quantize")) {
76 101
 		ts = ts_quantize;
77 102
 		t = &t_quantize_func;
103
+	} else if (!strcmp(n->ident, "time")) {
104
+		ts = ts_time;
105
+		t = &t_time_func;
78 106
 	} else {
79 107
 		return -ENOENT;
80 108
 	}

+ 4 - 0
node.h

@@ -12,6 +12,10 @@ typedef struct node node_t;
12 12
 typedef enum keyword {
13 13
 	KW_SUBSCRIPT = '[',
14 14
 	KW_ASSIGN = '=',
15
+	KW_ADD = '+',
16
+	KW_SUB = '-',
17
+	KW_MUL = '*',
18
+	KW_DIV = '/',
15 19
 } keyword_t;
16 20
 
17 21
 typedef enum ntype {

+ 116 - 25
ply.c

@@ -38,7 +38,7 @@ void provider_register(provider_t *prov)
38 38
 
39 39
 typedef struct pass pass_t;
40 40
 struct pass {
41
-	int (*run)(pass_t *, prog_t *);
41
+	int (*run)(pass_t *, ctx_t *);
42 42
 	walk_fn pre;
43 43
 	walk_fn post;
44 44
 };
@@ -47,19 +47,29 @@ struct pass {
47 47
 symtab_t globals = { .sym = NULL, .len = 0 };
48 48
 symtab_t locals = { .sym = NULL, .len = 0 };
49 49
 
50
-prog_t *prog_get(void)
50
+ctx_t *ctx_get(void)
51 51
 {
52
+	ctx_t *ctx;
52 53
 	prog_t *prog;
53 54
 
54
-	prog = calloc(1, sizeof(*prog));
55
+	ctx = calloc(1, sizeof(*ctx));
56
+	ctx->globals = calloc(1, sizeof(*ctx->globals));
57
+
58
+	ctx->progs = calloc(3, sizeof(*ctx->progs));
55 59
 
56
-	prog->locals = &locals;
57
-	prog->globals = &globals;
60
+	/* PROBE0 */
61
+	prog = calloc(1, sizeof(*prog));
62
+	prog->locals = calloc(1, sizeof(*prog->locals));
63
+	prog->globals = ctx->globals;
58 64
 
59
-	/* (@ ([ reads ((pid))) (quantize arg2)) */
60
-	prog->probe = "k:SyS_read"; /* { @reads[pid()] = quantize(arg2) } */
65
+	prog->probe = "k:SyS_read";
66
+	/* { t0 = time(); @reads[pid()] = quantize(arg2) } */
61 67
 	prog->ast =
62
-		node_list(
68
+		node_vlist(
69
+			node_vlist(node_keyword('='),
70
+				   node_ident("t0"),
71
+				   node_list(node_ident("time")),
72
+				   NULL),
63 73
 			node_vlist(node_keyword('='),
64 74
 				   node_vlist(node_keyword('['),
65 75
 					      node_ident("@reads"),
@@ -68,12 +78,42 @@ prog_t *prog_get(void)
68 78
 				   node_vlist(node_ident("quantize"),
69 79
 					      node_ident("arg2"),
70 80
 					      NULL),
81
+				   NULL),
82
+			NULL);
83
+
84
+	prog->provider = provider_get("k");
85
+	prog->provider->probe(prog);
86
+	ctx->progs[0] = prog;
87
+
88
+	/* PROBE1 */
89
+	prog = calloc(1, sizeof(*prog));
90
+	prog->locals = calloc(1, sizeof(*prog->locals));
91
+	prog->globals = ctx->globals;
92
+
93
+	/* TODO: k -> kret */
94
+	prog->probe = "k:SyS_read2"; 
95
+	/* { @times[pid()] = quantize(time() - t0) } */
96
+	prog->ast =
97
+		node_list(
98
+			node_vlist(node_keyword('='),
99
+				   node_vlist(node_keyword('['),
100
+					      node_ident("@times"),
101
+					      node_list(node_ident("pid")),
102
+					      NULL),
103
+				   node_vlist(node_ident("quantize"),
104
+					      node_vlist(node_keyword('-'),
105
+							 node_list(node_ident("time")),
106
+							 node_ident("t0"),
107
+							 NULL),
108
+					      NULL),
71 109
 				   NULL)
72 110
 			);
73 111
 
74 112
 	prog->provider = provider_get("k");
75 113
 	prog->provider->probe(prog);
76
-	return prog;
114
+	ctx->progs[1] = prog;
115
+
116
+	return ctx;
77 117
 }
78 118
 
79 119
 
@@ -142,12 +182,32 @@ int infer_type_keyword(prog_t *prog, node_t *n)
142 182
 		if (!src->type)
143 183
 			return 0;
144 184
 
145
-		if (!dst->type)
146
-			dst->type = src->type;
147
-
148 185
 		/* TODO: assignment is statement for now. do we need
149 186
 		 * c-style assignment expressions? e.g `a = b = 2;` */
150 187
 		n->type = &t_v;
188
+
189
+		if (dst->type)
190
+			return 0;
191
+
192
+		dst->type = src->type;
193
+
194
+		if (dst->ntype != N_IDENT)
195
+			return 0;
196
+
197
+		return sym_add(dst->sym->st, dst->ident, dst->type, NULL);
198
+
199
+	case KW_ADD:
200
+	case KW_SUB:
201
+	case KW_MUL:
202
+	case KW_DIV:
203
+		dst = node_next(n);
204
+		src = node_next(dst);
205
+		assert(dst && src);
206
+
207
+		if (!(src->type && dst->type && type_equal(src->type, dst->type)))
208
+			return 0;
209
+
210
+		n->type = dst->type;
151 211
 		return 0;
152 212
 
153 213
 	default:
@@ -161,8 +221,14 @@ int infer_type_sym(prog_t *prog, node_t *n)
161 221
 {
162 222
 	node_t *parent, *key;
163 223
 
164
-	if (n->sym->type)
224
+	if (n->sym->type) {
225
+		/* the symbol type could have been inferred in another
226
+		 * probe, in that case copy the type to this node. */
227
+		if (!n->type)
228
+			n->type = n->sym->type;
229
+
165 230
 		return 0;
231
+	}
166 232
 
167 233
 	parent = node_up(n);
168 234
 	key = node_next(n);
@@ -203,39 +269,64 @@ int pass_infer_types(node_t *n, void *_prog)
203 269
 	return 0;
204 270
 }
205 271
 
272
+/* int pass_walk(pass_t *pass, prog_t *prog) */
273
+/* { */
274
+/* 	return node_walk(prog->ast, pass->pre, pass->post, prog); */
275
+/* } */
206 276
 
207
-int pass_walk(pass_t *pass, prog_t *prog)
277
+int pass_validate_types(node_t *n, void *_prog)
208 278
 {
209
-	return node_walk(prog->ast, pass->pre, pass->post, prog);
279
+	prog_t *prog = _prog;
280
+
281
+	
282
+	return 0;
283
+}
284
+
285
+int pass_walk(pass_t *pass, ctx_t *ctx)
286
+{
287
+	prog_t **prog;
288
+	int err;
289
+
290
+	for (prog = ctx->progs; *prog; prog++) {
291
+		err = node_walk((*prog)->ast, pass->pre, pass->post, *prog);
292
+		if (err)
293
+			return err;
294
+	}
295
+
296
+	return 0;
210 297
 }
211 298
 
212 299
 pass_t passes[] = {
213 300
 	{ .run = pass_walk, .post = pass_resolve_symbols },
214 301
 	{ .run = pass_walk, .post = pass_infer_types },
215 302
 	{ .run = pass_walk, .post = pass_infer_types },
303
+	{ .run = pass_walk, .post = pass_infer_types },
304
+	{ .run = pass_walk, .post = pass_validate_types },
216 305
 
217 306
 	{ NULL }
218 307
 };
219 308
 
220 309
 int main(void)
221 310
 {
222
-	prog_t *prog = prog_get();
311
+	ctx_t *ctx = ctx_get();
312
+	prog_t **prog;
223 313
 	pass_t *pass;
224 314
 	int err;
225 315
 
226 316
 	for (pass = passes; pass->run; pass++) {
227
-		err = pass->run(pass, prog);
317
+		err = pass->run(pass, ctx);
228 318
 		if (err)
229 319
 			break;
230 320
 	}
231 321
 
232
-	printf("AST\n===\n");
233
-	node_dump(prog->ast, stdout);
234
-	printf("\nLOCALS\n======\n");
235
-	symtab_dump(prog->locals, stdout);
236
-	printf("\nGLOBALS\n=======\n");
237
-	symtab_dump(prog->globals, stdout);
238
-	/* printf("\nTYPES\n=====\n"); */
239
-	/* types_dump_cdecl(stdout); */
322
+	for (prog = ctx->progs; *prog; prog++) {
323
+		printf("\n\e[34m%s\e[0m\n", (*prog)->probe);
324
+		node_dump((*prog)->ast, stdout);
325
+		printf("\n-- locals\n");
326
+		symtab_dump((*prog)->locals, stdout);
327
+	}
328
+
329
+	printf("\n\n-- globals\n");
330
+	symtab_dump(ctx->globals, stdout);
240 331
 	return err;
241 332
 }

+ 4 - 0
ply.h

@@ -20,7 +20,11 @@ struct prog {
20 20
 	void *provider_data;
21 21
 };
22 22
 
23
+typedef struct ctx {
24
+	prog_t **progs;
23 25
 
26
+	symtab_t *globals;
27
+} ctx_t;
24 28
 
25 29
 struct provider {
26 30
 	const char *name;

+ 5 - 4
sym.c

@@ -11,8 +11,8 @@ sym_t *sym_get(symtab_t *st, const char *name)
11 11
 	size_t i;
12 12
 
13 13
 	for (i = 0; i < st->len; i++) {
14
-		if (!strcmp(st->sym[i].name, name))
15
-			return &st->sym[i];
14
+		if (!strcmp(st->sym[i]->name, name))
15
+			return st->sym[i];
16 16
 	}
17 17
 
18 18
 	return NULL;
@@ -37,7 +37,8 @@ int sym_add(symtab_t *st, const char *name, type_t *type, sym_t **new)
37 37
 	st->sym = realloc(st->sym, ++st->len * sizeof(*st->sym));
38 38
 	assert(st->sym);
39 39
 
40
-	sym = &st->sym[st->len-1];
40
+	st->sym[st->len - 1] = calloc(1, sizeof(sym_t));
41
+	sym = st->sym[st->len - 1];
41 42
 	sym->st   = st;
42 43
 	sym->name = name;
43 44
 	sym->type = type;
@@ -59,7 +60,7 @@ void symtab_dump(symtab_t *st, FILE *fp)
59 60
 	size_t i;
60 61
 
61 62
 	for (i = 0; i < st->len; i++) {
62
-		sym_dump(&st->sym[i], fp);
63
+		sym_dump(st->sym[i], fp);
63 64
 		fputc('\n', fp);
64 65
 	}
65 66
 }

+ 3 - 1
sym.h

@@ -12,7 +12,7 @@ typedef struct sym {
12 12
 } sym_t;
13 13
 
14 14
 struct symtab {
15
-	sym_t *sym;
15
+	sym_t **sym;
16 16
 	size_t len;
17 17
 };
18 18
 
@@ -22,4 +22,6 @@ int    sym_add(symtab_t *st, const char *name, type_t *type, sym_t **new);
22 22
 void sym_dump(sym_t *sym, FILE *fp);
23 23
 void symtab_dump(symtab_t *st, FILE *fp);
24 24
 
25
+//#define symtab_foreach(_st, _sym) for((_sym) = (_st)->sym; (_sym) < (_st)->sym[(_st)->len]; (_sym)++)
26
+
25 27
 #endif	/* _PLY_SYM_H */