summaryrefslogtreecommitdiffstats
path: root/runtime/docs/html/print_8c-source.html
blob: c020fff3a60365108938d0576b34b6c4b6030bb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>SystemTap: print.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.1 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
<h1>print.c</h1><div class="fragment"><pre class="fragment">00001 <span class="preprocessor">#ifndef _PRINT_C_ </span><span class="comment">/* -*- linux-c -*- */</span>
00002 <span class="preprocessor">#define _PRINT_C_</span>
00003 <span class="preprocessor"></span>
00004 <span class="preprocessor">#include &lt;linux/config.h&gt;</span>
00005 
00006 <span class="preprocessor">#include "<a class="code" href="io_8c.html">io.c</a>"</span>
00007 <span class="comment"></span>
00008 <span class="comment">/** @file print.c</span>
00009 <span class="comment"> * @addtogroup print Print Buffer</span>
00010 <span class="comment"> * Print Buffer Functions.</span>
00011 <span class="comment"> * The print buffer is for collecting output to send to the user daemon.</span>
00012 <span class="comment"> * This is a per-cpu static buffer.  The buffer is sent when</span>
00013 <span class="comment"> * _stp_print_flush() is called.</span>
00014 <span class="comment"> *</span>
00015 <span class="comment"> * The reason to do this is to allow multiple small prints to be combined then</span>
00016 <span class="comment"> * timestamped and sent together to stpd. It could flush automatically on newlines,</span>
00017 <span class="comment"> * but what about stack traces which span many lines?  So try this and see how it works for us.</span>
00018 <span class="comment"> * @{</span>
00019 <span class="comment"> */</span>
00020 <span class="comment"></span>
00021 <span class="comment">/** Size of buffer, not including terminating NULL */</span>
<a name="l00022"></a><a class="code" href="group__print.html#ga8">00022</a> <span class="preprocessor">#define STP_PRINT_BUF_LEN 8000</span>
00023 <span class="preprocessor"></span>
00024 <span class="keyword">static</span> <span class="keywordtype">int</span> _stp_pbuf_len[NR_CPUS];
00025 
00026 <span class="preprocessor">#ifdef STP_NETLINK_ONLY</span>
00027 <span class="preprocessor"></span><span class="preprocessor">#define STP_PRINT_BUF_START 0</span>
00028 <span class="preprocessor"></span><span class="keyword">static</span> <span class="keywordtype">char</span> _stp_pbuf[NR_CPUS][<a class="code" href="group__print.html#ga8">STP_PRINT_BUF_LEN</a> + 1];
00029 
00030 <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga2">_stp_print_flush</a> (<span class="keywordtype">void</span>)
00031 {
00032         <span class="keywordtype">int</span> cpu = smp_processor_id();
00033         <span class="keywordtype">char</span> *buf = &amp;_stp_pbuf[cpu][0];
00034         <span class="keywordtype">int</span> len = _stp_pbuf_len[cpu];
00035 
00036         <span class="keywordflow">if</span> (len == 0)
00037                 <span class="keywordflow">return</span>;
00038 
00039         <span class="keywordflow">if</span> ( app.logging == 0) {
00040                 _stp_pbuf_len[cpu] = 0;
00041                 <span class="keywordflow">return</span>;
00042         }
00043         
00044         <span class="comment">/* enforce newline at end  */</span>
00045         <span class="keywordflow">if</span> (buf[len - 1] != <span class="charliteral">'\n'</span>) {
00046                 buf[len++] = <span class="charliteral">'\n'</span>;
00047                 buf[len] = <span class="charliteral">'\0'</span>;
00048         }
00049         
00050         send_reply (STP_REALTIME_DATA, buf, len + 1, stpd_pid);
00051         _stp_pbuf_len[cpu] = 0;
00052 }
00053 
00054 <span class="preprocessor">#else </span><span class="comment">/* ! STP_NETLINK_ONLY */</span>
00055 <span class="comment">/* size of timestamp, in bytes, including space */</span>
00056 <span class="preprocessor">#define TIMESTAMP_SIZE 19</span>
00057 <span class="preprocessor"></span><span class="preprocessor">#define STP_PRINT_BUF_START (TIMESTAMP_SIZE + 1)</span>
00058 <span class="preprocessor"></span><span class="keyword">static</span> <span class="keywordtype">char</span> _stp_pbuf[NR_CPUS][<a class="code" href="group__print.html#ga8">STP_PRINT_BUF_LEN</a> + STP_PRINT_BUF_START + 1];
00059 <span class="comment"></span>
00060 <span class="comment">/** Send the print buffer now.</span>
00061 <span class="comment"> * Output accumulates in the print buffer until this is called.</span>
00062 <span class="comment"> * Size is limited by length of print buffer, #STP_PRINT_BUF_LEN.</span>
00063 <span class="comment"> */</span>
00064 
<a name="l00065"></a><a class="code" href="group__print.html#ga2">00065</a> <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga2">_stp_print_flush</a> (<span class="keywordtype">void</span>)
00066 {
00067         <span class="keywordtype">int</span> cpu = smp_processor_id();
00068         <span class="keywordtype">char</span> *buf = &amp;_stp_pbuf[cpu][0];
00069         <span class="keywordtype">char</span> *ptr = buf + STP_PRINT_BUF_START;
00070         <span class="keyword">struct </span>timeval tv;
00071 
00072         <span class="keywordflow">if</span> (_stp_pbuf_len[cpu] == 0)
00073                 <span class="keywordflow">return</span>;
00074         
00075         <span class="comment">/* enforce newline at end  */</span>
00076         <span class="keywordflow">if</span> (ptr[_stp_pbuf_len[cpu]-1] != <span class="charliteral">'\n'</span>) {
00077                 ptr[_stp_pbuf_len[cpu]++] = <span class="charliteral">'\n'</span>;
00078                 ptr[_stp_pbuf_len[cpu]] = <span class="charliteral">'\0'</span>;
00079         }
00080         
00081         do_gettimeofday(&amp;tv);
00082         scnprintf (buf, TIMESTAMP_SIZE+1, <span class="stringliteral">"[%li.%06li] "</span>, tv.tv_sec, tv.tv_usec);
00083         buf[TIMESTAMP_SIZE] = <span class="charliteral">' '</span>;
00084         relayapp_write(buf, _stp_pbuf_len[cpu] + TIMESTAMP_SIZE + 2);
00085         _stp_pbuf_len[cpu] = 0;
00086 }
00087 <span class="preprocessor">#endif </span><span class="comment">/* STP_NETLINK_ONLY */</span>
00088 <span class="comment"></span>
00089 <span class="comment">/** Print into the print buffer.</span>
00090 <span class="comment"> * Like printf, except output goes to the print buffer.</span>
00091 <span class="comment"> * Safe because overflowing the buffer is not allowed.</span>
00092 <span class="comment"> * Size is limited by length of print buffer, #STP_PRINT_BUF_LEN.</span>
00093 <span class="comment"> * </span>
00094 <span class="comment"> * @param fmt A printf-style format string followed by a </span>
00095 <span class="comment"> * variable number of args.</span>
00096 <span class="comment"> * @sa _stp_print_flush()</span>
00097 <span class="comment"> */</span>
00098 
<a name="l00099"></a><a class="code" href="group__print.html#ga3">00099</a> <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga3">_stp_printf</a> (<span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...)
00100 {
00101         <span class="keywordtype">int</span> num;
00102         va_list args;
00103         <span class="keywordtype">int</span> cpu = smp_processor_id();
00104         <span class="keywordtype">char</span> *buf = &amp;_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu];
00105         va_start(args, fmt);
00106         num = vscnprintf(buf, <a class="code" href="group__print.html#ga8">STP_PRINT_BUF_LEN</a> - _stp_pbuf_len[cpu], fmt, args);
00107         va_end(args);
00108         <span class="keywordflow">if</span> (num &gt; 0)
00109                 _stp_pbuf_len[cpu] += num;
00110 }
00111 <span class="comment"></span>
00112 <span class="comment">/** Print into the print buffer.</span>
00113 <span class="comment"> * Use this if your function already has a va_list.</span>
00114 <span class="comment"> * You probably want _stp_printf().</span>
00115 <span class="comment"> */</span>
00116 
<a name="l00117"></a><a class="code" href="group__print.html#ga4">00117</a> <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga4">_stp_vprintf</a> (<span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, va_list args)
00118 {
00119         <span class="keywordtype">int</span> num;
00120         <span class="keywordtype">int</span> cpu = smp_processor_id();
00121         <span class="keywordtype">char</span> *buf = &amp;_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu];
00122         num = vscnprintf(buf, <a class="code" href="group__print.html#ga8">STP_PRINT_BUF_LEN</a> -_stp_pbuf_len[cpu], fmt, args);
00123         <span class="keywordflow">if</span> (num &gt; 0)
00124                 _stp_pbuf_len[cpu] += num;
00125 }
00126 <span class="comment"></span>
00127 <span class="comment">/** Write a C string into the print buffer.</span>
00128 <span class="comment"> * Copies a string into a print buffer.</span>
00129 <span class="comment"> * Safe because overflowing the buffer is not allowed.</span>
00130 <span class="comment"> * Size is limited by length of print buffer, #STP_PRINT_BUF_LEN.</span>
00131 <span class="comment"> * This is more efficient than using _stp_printf() if you don't</span>
00132 <span class="comment"> * need fancy formatting.</span>
00133 <span class="comment"> *</span>
00134 <span class="comment"> * @param str A C string.</span>
00135 <span class="comment"> * @sa _stp_print</span>
00136 <span class="comment"> */</span>
00137 
<a name="l00138"></a><a class="code" href="group__print.html#ga5">00138</a> <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga5">_stp_print_cstr</a> (<span class="keyword">const</span> <span class="keywordtype">char</span> *str)
00139 {
00140         <span class="keywordtype">int</span> cpu = smp_processor_id();
00141         <span class="keywordtype">char</span> *buf = &amp;_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu];
00142         <span class="keywordtype">int</span> num = strlen (str);
00143         <span class="keywordflow">if</span> (num &gt; <a class="code" href="group__print.html#ga8">STP_PRINT_BUF_LEN</a> - _stp_pbuf_len[cpu])
00144                 num = <a class="code" href="group__print.html#ga8">STP_PRINT_BUF_LEN</a> - _stp_pbuf_len[cpu];
00145         strncpy (buf, str, num+1);
00146         _stp_pbuf_len[cpu] += num;
00147 }
00148 <span class="comment"></span>
00149 <span class="comment">/** Clear the scratch buffer.</span>
00150 <span class="comment"> * This function should be called before anything is written to </span>
00151 <span class="comment"> * the scratch buffer.  Output will accumulate in the buffer</span>
00152 <span class="comment"> * until this function is called again.  </span>
00153 <span class="comment"> * @returns A pointer to the buffer.</span>
00154 <span class="comment"> */</span>
00155 
<a name="l00156"></a><a class="code" href="group__print.html#ga6">00156</a> <span class="keywordtype">char</span> *<a class="code" href="group__print.html#ga6">_stp_print_clear</a> (<span class="keywordtype">void</span>)
00157 {
00158         <span class="keywordtype">int</span> cpu = smp_processor_id();
00159         _stp_pbuf_len[cpu] = 0;
00160         <span class="keywordflow">return</span> &amp;_stp_pbuf[cpu][STP_PRINT_BUF_START];
00161 }
00162 
00163 <span class="preprocessor">#include "<a class="code" href="string_8c.html">string.c</a>"</span>
00164 <span class="comment"></span>
00165 <span class="comment">/** Write a String into the print buffer.</span>
00166 <span class="comment"> * Copies a String into a print buffer.</span>
00167 <span class="comment"> * Safe because overflowing the buffer is not allowed.</span>
00168 <span class="comment"> * Size is limited by length of print buffer, #STP_PRINT_BUF_LEN.</span>
00169 <span class="comment"> * This is more efficient than using _stp_printf() if you don't</span>
00170 <span class="comment"> * need fancy formatting.</span>
00171 <span class="comment"> *</span>
00172 <span class="comment"> * @param str A String.</span>
00173 <span class="comment"> * @sa _stp_print</span>
00174 <span class="comment"> */</span>
00175 
<a name="l00176"></a><a class="code" href="group__print.html#ga7">00176</a> <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga7">_stp_print_string</a> (String str)
00177 {
00178         <span class="keywordflow">if</span> (str-&gt;len)
00179                 <a class="code" href="group__print.html#ga5">_stp_print_cstr</a> (str-&gt;buf);
00180 }
00181 <span class="comment"></span>
00182 <span class="comment">/** Write a String or C string into the print buffer.</span>
00183 <span class="comment"> * This macro selects the proper function to call.</span>
00184 <span class="comment"> * @param str A String or C string (char *)</span>
00185 <span class="comment"> * @sa _stp_print_cstr _stp_print_string</span>
00186 <span class="comment"> */</span>
00187 
<a name="l00188"></a><a class="code" href="group__print.html#ga11">00188</a> <span class="preprocessor">#define _stp_print(str)                                                 \</span>
00189 <span class="preprocessor">        ({                                                              \</span>
00190 <span class="preprocessor">          if (__builtin_types_compatible_p (typeof (str), char[])) {    \</span>
00191 <span class="preprocessor">                  char *x = (char *)str;                                \</span>
00192 <span class="preprocessor">                  _stp_print_cstr(x);                                   \</span>
00193 <span class="preprocessor">          } else {                                                      \</span>
00194 <span class="preprocessor">                  String x = (String)str;                               \</span>
00195 <span class="preprocessor">                  _stp_print_string(x);                                 \</span>
00196 <span class="preprocessor">          }                                                             \</span>
00197 <span class="preprocessor">  })</span>
00198 <span class="preprocessor"></span><span class="comment"></span>
00199 <span class="comment">/** @} */</span>
00200 <span class="preprocessor">#endif </span><span class="comment">/* _PRINT_C_ */</span>
</pre></div></body></html>