1111
1212typedef enum {
1313 STATE_ON_CPU = 0 ,
14- STATE_OFF_CPU_WAITING = 1 ,
15- STATE_OFF_CPU_IO = 2 ,
16- STATE_OFF_CPU_SEMOP = 3 ,
17- STATE_OFF_CPU_BLOCKED = 4 ,
18- STATE_OFF_CPU_DEAD = 5 ,
19- STATE_MAX = 6
14+ STATE_OFF_CPU_WAITING ,
15+ STATE_OFF_CPU_SEMOP ,
16+ STATE_OFF_CPU_BLOCKED ,
17+ STATE_OFF_CPU_IO_READ ,
18+ STATE_OFF_CPU_IO_WRITE ,
19+ STATE_OFF_CPU_DEAD ,
20+ STATE_MAX
2021} state_t ;
2122
2223#define STATE_METADATA (_state , _str , _color ) \
@@ -31,18 +32,20 @@ BEGIN
3132 printf ("\t\"title\": \"PostgreSQL statemap on %s, by process ID\",\n" ,
3233 `utsname .nodename );
3334 printf ("\t\"host\": \"%s\",\n" , `utsname .nodename );
35+ printf ("\t\"entityKind\": \"Process\",\n" );
3436 printf ("\t\"states\": {\n" );
3537
3638 STATE_METADATA (STATE_ON_CPU , "on-cpu" , "#DAF7A6" )
3739 STATE_METADATA (STATE_OFF_CPU_WAITING , "off-cpu-waiting" , "#f9f9f9" )
38- STATE_METADATA (STATE_OFF_CPU_BLOCKED , "off-cpu-blocked" , "#C70039" )
3940 STATE_METADATA (STATE_OFF_CPU_SEMOP , "off-cpu-semop" , "#FF5733" )
40- STATE_METADATA (STATE_OFF_CPU_IO , "off-cpu-io" , "#FFC300" )
41- STATE_METADATA (STATE_OFF_CPU_DEAD , "off-cpu-dead" , "#581845" )
41+ STATE_METADATA (STATE_OFF_CPU_BLOCKED , "off-cpu-blocked" , "#C70039" )
42+ STATE_METADATA (STATE_OFF_CPU_IO_READ , "off-cpu-io-read" , "#FFC300" )
43+ STATE_METADATA (STATE_OFF_CPU_IO_WRITE , "off-cpu-io-write" , "#338AFF" )
44+ STATE_METADATA (STATE_OFF_CPU_DEAD , "off-cpu-dead" , "#E0E0E0" )
4245
46+ printf ("\t},\n" );
4347 printf ("\"data\": [\n" );
4448 start = timestamp ;
45- exit (0 );
4649}
4750
4851sched :::wakeup
@@ -54,25 +57,32 @@ sched:::wakeup
5457 args [1 ]-> pr_pid );
5558}
5659
57- zio_wait :entry
60+ syscall ::read :entry
61+ /execname == "postgres" /
62+ {
63+ self -> state = STATE_OFF_CPU_IO_READ ;
64+ }
65+
66+ syscall ::write :entry
5867/execname == "postgres" /
5968{
60- self -> state = STATE_OFF_CPU_IO ;
69+ self -> state = STATE_OFF_CPU_IO_WRITE ;
6170}
6271
63- zio_wait :return
72+ syscall ::read :return ,
73+ syscall ::write :return
6474/execname == "postgres" /
6575{
6676 self -> state = STATE_ON_CPU ;
6777}
6878
69- syscall ::semop :entry
79+ fbt ::semop :entry
7080/execname == "postgres" /
7181{
7282 self -> state = STATE_OFF_CPU_SEMOP ;
7383}
7484
75- syscall ::semop :return
85+ fbt ::semop :return
7686/execname == "postgres" /
7787{
7888 self -> state = STATE_ON_CPU ;
@@ -82,7 +92,7 @@ sched:::off-cpu
8292/execname == "postgres" /
8393{
8494 printf ("{ \"time\": \"%d\", \"entity\": \"%d\", " ,
85- timestamp - start , tid );
95+ timestamp - start , pid );
8696
8797 printf ("\"state\": %d },\n" , self -> state != STATE_ON_CPU ?
8898 self -> state : curthread -> t_flag & T_WAKEABLE ?
@@ -94,10 +104,48 @@ sched:::on-cpu
94104{
95105 self -> state = STATE_ON_CPU ;
96106 printf ("{ \"time\": \"%d\", \"entity\": \"%d\", " ,
97- timestamp - start , tid );
107+ timestamp - start , pid );
98108 printf ("\"state\": %d },\n" , self -> state );
99109}
100110
111+ proc :::exit
112+ /execname == "postgres" /
113+ {
114+ self -> exiting = pid ;
115+ }
116+
117+ sched :::off - cpu
118+ /execname != "postgres" && self -> exiting /
119+ {
120+ printf ("{ \"time\": \"%d\", \"entity\": \"%d\", " ,
121+ timestamp - start , self -> exiting );
122+
123+ printf ("\"state\": %d },\n" , STATE_OFF_CPU_DEAD );
124+ self -> exiting = 0 ;
125+ self -> state = 0 ;
126+ }
127+
128+ /*
129+ * This is -- to put it mildly -- very specific to the implementation of
130+ * PostgreSQL: if the process is long-running, it lifts argv[0] out of the
131+ * address space, and -- iff it matches the form "postgres: [description]
132+ * process", sets the description for the process to be [description].
133+ */
134+ sched :::on - cpu
135+ /execname == "postgres" &&
136+ timestamp - curthread -> t_procp -> p_mstart > 1000000000 &&
137+ !seen [pid ]/
138+ {
139+ seen [pid ] = 1 ;
140+ this -> arg = * (uintptr_t * )copyin (curthread -> t_procp -> p_user .u_argv , 8 );
141+ this -> index = index (this -> process = copyinstr (this -> arg ), " process" );
142+
143+ if (this -> index > 0 && index (this -> process , "postgres: " ) == 0 ) {
144+ printf ("{ \"entity\": \"%d\", \"description\": \"%s\" },\n" ,
145+ pid , substr (this -> process , 10 , this -> index - 10 ));
146+ }
147+ }
148+
101149tick - 1 sec
102150/timestamp - start > 60 * 1000000000 /
103151{
0 commit comments