summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-04-14 23:32:47 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-04-14 23:32:47 -0400
commitbc15693803e84200237e6d342e2517f1d9408884 (patch)
treeca6911b31303ca6538643ed9c7f7e3d5d68e0256
parent5fccfad62365fdeab9bbe2487760542becc2b5bb (diff)
make sched_trace independent from liblitmus and the kernel
This is in preparation of integration with libcairo, which isn't available as a 64bit build on Flare. This change will also allow us to use sched_trace tools on systems that do not have a properly configured kernel lying around (e.g., department machines).
-rw-r--r--SConstruct32
-rw-r--r--include/sched_trace.h127
-rw-r--r--src/cairo_test.c41
-rw-r--r--src/util.c133
4 files changed, 314 insertions, 19 deletions
diff --git a/SConstruct b/SConstruct
index fa9db86..18c040c 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,13 +1,11 @@
1# ##################################################################### 1# #####################################################################
2# User configuration. 2# User configuration.
3LITMUS_KERNEL = '../litmus2008' 3# -- Nothing to configure at the moment.
4LIBLITMUS = '../liblitmus2008'
5 4
6# ##################################################################### 5# #####################################################################
7# Internal configuration. 6# Internal configuration.
8DEBUG_FLAGS = '-Wall -g -Wdeclaration-after-statement' 7DEBUG_FLAGS = '-Wall -g -Wdeclaration-after-statement'
9INCLUDE_DIRS = 'include/ %s/include/ %s/include/' % (LITMUS_KERNEL, LIBLITMUS) 8INCLUDE_DIRS = 'include/'
10
11# ##################################################################### 9# #####################################################################
12# Build configuration. 10# Build configuration.
13from os import uname 11from os import uname
@@ -18,25 +16,21 @@ if os != 'Linux':
18 print 'Error: Building sched_trace tools is only supported on Linux.' 16 print 'Error: Building sched_trace tools is only supported on Linux.'
19 Exit(1) 17 Exit(1)
20 18
21if arch not in ('sparc64', 'i686'): 19# base config
22 print 'Error: Building sched_trace tools is only supported on i686 and sparc64.' 20env = Environment(
23 Exit(1)
24
25st = Environment(
26 CC = 'gcc', 21 CC = 'gcc',
27 CPPPATH = Split(INCLUDE_DIRS),
28 CCFLAGS = Split(DEBUG_FLAGS), 22 CCFLAGS = Split(DEBUG_FLAGS),
29 LIBS = 'st', 23 CPPPATH = Split(INCLUDE_DIRS),
30 LIBPATH = LIBLITMUS
31) 24)
32 25
33if arch == 'sparc64': 26# Link with libcairo. For now without sched_trace support.
34 # build 64 bit sparc v9 binaries 27cairo = env.Clone()
35 v9 = Split('-mcpu=v9 -m64') 28cairo.ParseConfig('pkg-config --cflags --libs cairo')
36 st.Append(CCFLAGS = v9, LINKFLAGS = v9)
37 29
38# ##################################################################### 30# #####################################################################
39# Targets: sched_trace tools 31# Targets: sched_trace tools
40common = ['src/load.c', 'src/eheap.c'] 32common = ['src/load.c', 'src/eheap.c', 'src/util.c']
41st.Program('st_convert', ['src/st2pl.c'] + common) 33env.Program('st_convert', ['src/st2pl.c'] + common)
42st.Program('st_show', ['src/showst.c'] + common) 34env.Program('st_show', ['src/showst.c'] + common)
35
36cairo.Program('cairo_test', ['src/cairo_test.c'])
diff --git a/include/sched_trace.h b/include/sched_trace.h
new file mode 100644
index 0000000..8bdd253
--- /dev/null
+++ b/include/sched_trace.h
@@ -0,0 +1,127 @@
1#ifndef __SCHED_TRACE_H_
2#define __SCHED_TRACE_H_
3
4#include <stdint.h>
5
6typedef uint8_t u8;
7typedef uint32_t u32;
8typedef uint16_t u16;
9typedef uint64_t u64;
10
11/* A couple of notes about the format:
12 *
13 * - make sure it is in sync with the kernel
14 * - all times in nanoseconds
15 * - endianess issues are the problem of the app
16 */
17
18struct st_trace_header {
19 u8 type; /* Of what type is this record? */
20 u8 cpu; /* On which CPU was it recorded? */
21 u16 pid; /* PID of the task. */
22 u32 job; /* The job sequence number. */
23};
24
25#define ST_NAME_LEN 16
26struct st_name_data {
27 char cmd[ST_NAME_LEN];/* The name of the executable of this process. */
28};
29
30struct st_param_data { /* regular params */
31 u32 wcet;
32 u32 period;
33 u32 phase;
34 u8 partition;
35 u8 __unused[3];
36};
37
38struct st_release_data { /* A job is was/is going to be released. */
39 u64 release; /* What's the release time? */
40 u64 deadline; /* By when must it finish? */
41};
42
43struct st_assigned_data { /* A job was asigned to a CPU. */
44 u64 when;
45 u8 target; /* Where should it execute? */
46 u8 __unused[3];
47};
48
49struct st_switch_to_data { /* A process was switched to on a given CPU. */
50 u64 when; /* When did this occur? */
51 u32 exec_time; /* Time the current job has executed. */
52
53};
54
55struct st_switch_away_data { /* A process was switched away from on a given CPU. */
56 u64 when;
57 u64 exec_time;
58};
59
60struct st_completion_data { /* A job completed. */
61 u64 when;
62 u8 forced:1; /* Set to 1 if job overran and kernel advanced to the
63 * next task automatically; set to 0 otherwise.
64 */
65 u8 __uflags:7;
66 u8 __unused[3];
67};
68
69struct st_block_data { /* A task blocks. */
70 u64 when;
71 u64 __unused;
72};
73
74struct st_resume_data { /* A task resumes. */
75 u64 when;
76 u64 __unused;
77};
78
79struct st_sys_release_data {
80 u64 when;
81 u64 release;
82};
83
84#define DATA(x) struct st_ ## x ## _data x;
85
86typedef enum {
87 ST_NAME = 1, /* Start at one, so that we can spot
88 * uninitialized records. */
89 ST_PARAM,
90 ST_RELEASE,
91 ST_ASSIGNED,
92 ST_SWITCH_TO,
93 ST_SWITCH_AWAY,
94 ST_COMPLETION,
95 ST_BLOCK,
96 ST_RESUME,
97 ST_SYS_RELEASE,
98} st_event_record_type_t;
99
100struct st_event_record {
101 struct st_trace_header hdr;
102 union {
103 u64 raw[2];
104
105 DATA(name);
106 DATA(param);
107 DATA(release);
108 DATA(assigned);
109 DATA(switch_to);
110 DATA(switch_away);
111 DATA(completion);
112 DATA(block);
113 DATA(resume);
114 DATA(sys_release);
115
116 } data;
117};
118
119#undef DATA
120
121const char* event2name(unsigned int id);
122u64 event_time(struct st_event_record* rec);
123
124void print_event(struct st_event_record *rec);
125void print_all(struct st_event_record *rec, unsigned int count);
126
127#endif
diff --git a/src/cairo_test.c b/src/cairo_test.c
new file mode 100644
index 0000000..9c3683a
--- /dev/null
+++ b/src/cairo_test.c
@@ -0,0 +1,41 @@
1#include <stdio.h>
2#include <stdlib.h>
3
4#include <cairo.h>
5
6static double in2pts(double in)
7{
8 /* 72 pts per inch */
9 return in * 72;
10}
11
12static double cm2in(double cm)
13{
14 /* 1in = 2.54 cm */
15 return cm / 2.54;
16}
17
18static double cm2pts(double cm)
19{
20 return in2pts(cm2in(cm));
21}
22
23void cairo_test(void)
24{
25 cairo_surface_t *surface;
26 cairo_t *cr;
27
28 surface = cairo_pdf_surface_create("test.pdf", cm2pts(10), cm2pts(10));
29 cr = cairo_create(surface);
30 cairo_set_source_rgb(cr, 1.0, 0.3, 0.7);
31 cairo_rectangle(cr, cm2pts(0.25), cm2pts(0.25), cm2pts(0.5), cm2pts(0.5));
32 cairo_fill(cr);
33 cairo_destroy(cr);
34 cairo_surface_destroy(surface);
35}
36
37int main (int argc, char** argv)
38{
39 cairo_test();
40 return 0;
41}
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..b603c4a
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,133 @@
1#include <stdio.h>
2#include <stdlib.h>
3
4
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/mman.h>
8#include <fcntl.h>
9#include <unistd.h>
10
11#include "sched_trace.h"
12
13static const char* event_names[] = {
14 "INVALID",
15 "NAME",
16 "PARAM",
17 "RELEASE",
18 "ASSIGNED",
19 "SWITCH_TO",
20 "SWITCH_FROM",
21 "COMPLETION",
22 "BLOCK",
23 "RESUME",
24 "SYS_RELEASE",
25 "INVALID"
26};
27
28#define ST_INVALID (ST_SYS_RELEASE + 1)
29
30
31const char* event2name(unsigned int id)
32{
33 if (id >= ST_INVALID)
34 id = ST_INVALID;
35 return event_names[id];
36}
37
38
39u64 event_time(struct st_event_record* rec)
40{
41 u64 when;
42 switch (rec->hdr.type) {
43 /* the time stamp is encoded in the first payload u64 */
44 case ST_RELEASE:
45 case ST_ASSIGNED:
46 case ST_SWITCH_TO:
47 case ST_SWITCH_AWAY:
48 case ST_COMPLETION:
49 case ST_BLOCK:
50 case ST_RESUME:
51 case ST_SYS_RELEASE:
52 when = rec->data.raw[0];
53 break;
54 default:
55 /* stuff that doesn't have a time stamp should occur "early" */
56 when = 0;
57 break;
58 };
59 return when;
60}
61
62void print_header(struct st_trace_header* hdr)
63{
64 printf("%-14s %5u/%-5u on CPU%3u ",
65 event2name(hdr->type),
66 hdr->pid, hdr->job,
67 hdr->cpu);
68}
69
70typedef void (*print_t)(struct st_event_record* rec);
71
72static void print_nothing(struct st_event_record* _)
73{
74}
75
76static void print_raw(struct st_event_record* rec)
77{
78 printf(" type=%u", rec->hdr.type);
79}
80
81static void print_name(struct st_event_record* rec)
82{
83 /* terminate in all cases */
84 rec->data.name.cmd[ST_NAME_LEN - 1] = 0;
85 printf("%s", rec->data.name.cmd);
86}
87
88static void print_param(struct st_event_record* rec)
89{
90 printf("T=(cost:%6.2fms, period:%6.2fms, phase:%6.2fms), part=%d",
91 rec->data.param.wcet / 1000000.0,
92 rec->data.param.period / 1000000.0,
93 rec->data.param.phase / 1000000.0,\
94 rec->data.param.partition);
95}
96
97static void print_time_data2(struct st_event_record* rec)
98{
99 printf("%6.2fms", rec->data.raw[1] / 1000000.0);
100}
101
102static print_t print_detail[] = {
103 print_raw, /* invalid */
104 print_name, /* NAME */
105 print_param, /* PARAM */
106 print_time_data2, /* RELEASE */
107 print_nothing, /* ASSIGNED */
108 print_nothing, /* SWITCH_TO */
109 print_nothing, /* SWITCH_FROM */
110 print_nothing, /* COMPLETION */
111 print_nothing, /* BLOCK */
112 print_nothing, /* RESUME */
113 print_time_data2, /* SYS_RELEASE */
114 print_raw, /* invalid */
115};
116
117void print_event(struct st_event_record *rec)
118{
119 unsigned int id = rec->hdr.type;
120
121 if (id >= ST_INVALID)
122 id = ST_INVALID;
123 print_header(&rec->hdr);
124 print_detail[id](rec);
125 printf("\n");
126}
127
128void print_all(struct st_event_record *rec, unsigned int count)
129{
130 unsigned int i;
131 for (i = 0; i < count; i++)
132 print_event(&rec[i]);
133}