Merged with tip.
[cacao.git] / contrib / vmlog / vmlog.h
1 /* vmlog - high-speed logging for free VMs                  */
2 /* Copyright (C) 2006 Edwin Steiner <edwin.steiner@gmx.net> */
3
4 /* This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #ifndef _VMLOG_H_
20 #define _VMLOG_H_
21
22 #define VMLOG_PAD_TO_8
23
24 #include <limits.h>
25
26 /*** constants *******************************************************/
27
28 /* CAUTION: these are indices into the vmlog_tag_definitions table! */
29 #define VMLOG_TAG_ENTER  0
30 #define VMLOG_TAG_LEAVE  1
31 #define VMLOG_TAG_THROW  2
32 #define VMLOG_TAG_CATCH  3
33 #define VMLOG_TAG_UNWND  4
34 #define VMLOG_TAG_SIGNL  5
35 #define VMLOG_TAG_UNROL  6
36 #define VMLOG_TAG_REROL  7
37
38 /*** memory management macros ****************************************/
39
40 #ifndef VMLOG_NEW
41 #define VMLOG_NEW(type)                (type*)malloc(sizeof(type))
42 #endif
43
44 #ifndef VMLOG_FREE
45 #define VMLOG_FREE(type,ptr)           free(ptr)
46 #endif
47
48 #ifndef VMLOG_NEW_ARRAY
49 #define VMLOG_NEW_ARRAY(type,n)        (type*)malloc(sizeof(type)*(n))
50 #endif
51
52 #ifndef VMLOG_FREE_ARRAY
53 #define VMLOG_FREE_ARRAY(type,n,ptr)   free(ptr)
54 #endif
55
56 /*** struct typedefs *************************************************/
57
58 typedef struct vmlog_tag_definition vmlog_tag_definition;
59 typedef struct vmlog_hash_entry vmlog_hash_entry;
60 typedef struct vmlog_hash_table vmlog_hash_table;
61 typedef struct vmlog_string_entry vmlog_string_entry;
62 typedef struct vmlog_log_entry vmlog_log_entry;
63 typedef struct vmlog_thread_log vmlog_thread_log;
64 typedef struct vmlog_file vmlog_file;
65 typedef struct vmlog_frame vmlog_frame;
66 typedef struct vmlog_ringbuf vmlog_ringbuf;
67 typedef struct vmlog_log vmlog_log;
68 typedef struct vmlog_options vmlog_options;
69
70 /*** integer types ***************************************************/
71
72 typedef long long vmlog_fofs_t;
73 typedef long long vmlog_seq_t;
74 #define VMLOG_SEQ_FMT   "%lld"
75 #define VMLOG_SEQ_FMT_W "%10lld"
76 #ifdef LLONG_MAX
77 #define VMLOG_SEQ_MAX LLONG_MAX
78 #else
79 #define VMLOG_SEQ_MAX 9223372036854775807LL
80 #endif
81
82 #ifndef VMLOG_HAVE_PTRINT
83 typedef int ptrint; /* XXX */
84 #endif
85
86 /*** enums ***********************************************************/
87
88 typedef enum {
89         vmlogRead,
90         vmlogAppend,
91         vmlogTruncateAppend
92 } vmlog_fmode;
93
94 /*** function types **************************************************/
95
96 typedef void (*vmlog_hash_entry_destructor)(vmlog_hash_entry *entry);
97 typedef void (*vmlog_log_function)(vmlog_log *vml,void *threadid,
98                                    const char *name,int namelen);
99
100 /*** structs *********************************************************/
101
102 struct vmlog_tag_definition {
103         char             *name;
104         char             *fixname;
105         int               depth;
106 };
107
108 struct vmlog_hash_entry {
109         unsigned int      hash;
110         int               len;
111         int               index;
112         void             *data;
113         vmlog_hash_entry *hashlink;
114 };
115
116 struct vmlog_hash_table {
117         int               size;
118         int               nentries;
119         vmlog_hash_entry *table;
120 };
121
122 struct vmlog_string_entry {
123         vmlog_fofs_t ofs;
124         int          len;
125 #if defined(VMLOG_PAD_TO_8)
126         int          dummy;
127 #endif
128 };
129
130 struct vmlog_log_entry {
131         int          tag:8;
132         int          index:24;
133 };
134
135 struct vmlog_file {
136         int          fd;
137         char        *fname;
138         int          fnamelen;
139         vmlog_fofs_t ofs;
140         vmlog_fofs_t size;
141 };
142
143 struct vmlog_frame {
144         int                index;
145         vmlog_seq_t        seq;
146 };
147
148 struct vmlog_thread_log {
149         void              *threadid;
150         int                threadidx;
151         int                depth;
152         int                ignoredepth;
153         vmlog_file         logfile;
154         vmlog_log_entry   *logbuf;
155         vmlog_log_entry   *logbufend;
156         vmlog_log_entry   *logbufptr;
157         int                logbufcap;
158         vmlog_frame       *frames;
159         int                framescap;
160         vmlog_seq_t        seq;
161 };
162
163 struct vmlog_log {
164         vmlog_hash_table   threadhash;
165         vmlog_hash_table   stringhash;
166         vmlog_file         idxfile;
167         vmlog_file         strfile;
168         char              *prefix;
169         int                prefixlen;
170         int                ignorelistlen;
171 };
172
173 struct vmlog_ringbuf {
174         vmlog_file         file;
175         vmlog_log_entry   *buf;
176         vmlog_log_entry   *bufend;
177         vmlog_log_entry   *start;
178         vmlog_log_entry   *end;
179         vmlog_log_entry   *cur;
180         int                bufsize;
181         vmlog_seq_t        seq;
182
183         int                debug_availbefore;
184         int                debug_availafter;
185 };
186
187 struct vmlog_options {
188         char              *progname;
189         char              *prefix;
190         char              *stringprefix;
191         char              *ignoreprefix;
192 };
193
194 /*** variables *******************************************************/
195
196 extern vmlog_tag_definition vmlog_tag_definitions[];
197
198 /*** public functions ************************************************/
199
200 /* constructor / destructor */
201 vmlog_log * vmlog_log_new(const char *prefix,int truncate);
202 void vmlog_log_free(vmlog_log *vml);
203
204 /* configuration */
205 void vmlog_log_load_ignorelist(vmlog_log *vml,const char *prefix);
206
207 /* logging */
208 void vmlog_log_enter(vmlog_log *vml,void *threadid,const char *name,int namelen);
209 void vmlog_log_leave(vmlog_log *vml,void *threadid,const char *name,int namelen);
210 void vmlog_log_throw(vmlog_log *vml,void *threadid,const char *name,int namelen);
211 void vmlog_log_catch(vmlog_log *vml,void *threadid,const char *name,int namelen);
212 void vmlog_log_unwnd(vmlog_log *vml,void *threadid,const char *name,int namelen);
213 void vmlog_log_signl(vmlog_log *vml,void *threadid,const char *name,int namelen);
214 void vmlog_log_unrol(vmlog_log *vml,void *threadid,const char *name,int namelen);
215 void vmlog_log_rerol(vmlog_log *vml,void *threadid,const char *name,int namelen);
216
217 /* tag definitions */
218 int vmlog_tag_from_name(const char *name,int namelen);
219
220 /* thread logging */
221 vmlog_thread_log *vmlog_thread_log_new(vmlog_log *vml,void *threadid,int index);
222 void vmlog_thread_log_free(vmlog_thread_log *tlog);
223 vmlog_frame * vmlog_thread_log_enter(vmlog_thread_log *tlog,int index,vmlog_seq_t seq);
224 vmlog_frame * vmlog_thread_log_leave(vmlog_thread_log *tlog,int index,vmlog_seq_t seq);
225 void vmlog_thread_log_append(vmlog_thread_log *tlog,vmlog_log_entry *logent);
226
227 /* string/index handling */
228 int vmlog_get_string_index(vmlog_log *vml,const char *data,int len);
229 void vmlog_load_stringhash(vmlog_log *vml,const char *prefix);
230
231 /* string helpers */
232 char *vmlog_concat3(const char *a,const char *b,const char *c,int *plen);
233 char *vmlog_concat4len(const char *a,int alen,const char *b,int blen,
234                        const char *c,int clen,const char *d,int dlen,int *plen);
235
236 /* error reporting */
237 void vmlog_set_progname(const char *progname);
238 void vmlog_die(const char *fmt,...);
239 void vmlog_warn(const char *fmt,...);
240 void vmlog_die_usage(const char *usage,int error);
241
242 /* file handling */
243 void vmlog_file_open(vmlog_file *file,const char *fname,vmlog_fmode fmode);
244 void vmlog_file_close(vmlog_file *file);
245 void vmlog_file_append(vmlog_file *file,const void *data,int len);
246 void * vmlog_file_mmap(const char *fname,int *plen);
247 void vmlog_file_munmap(void *m,int len);
248 void vmlog_file_stat(vmlog_file *file);
249 void vmlog_file_seek(vmlog_file *file,vmlog_fofs_t ofs);
250
251 /* log entry ring buffer */
252 vmlog_ringbuf * vmlog_ringbuf_new(const char *fname,int bufsize);
253 void vmlog_ringbuf_free(vmlog_ringbuf *ring);
254 void vmlog_ringbuf_seek(vmlog_ringbuf *ring,vmlog_seq_t seq);
255 int vmlog_ringbuf_fill(vmlog_ringbuf *ring,int len);
256 vmlog_log_entry * vmlog_ringbuf_next(vmlog_ringbuf *ring,int prefetch);
257 vmlog_log_entry * vmlog_ringbuf_prev(vmlog_ringbuf *ring,int prefetch);
258
259 /* option parsing */
260 vmlog_options *vmlog_opt_new(void);
261 void vmlog_opt_set_prefix(vmlog_options *opts, const char *arg);
262 void vmlog_opt_set_stringprefix(vmlog_options *opts, const char *arg);
263 void vmlog_opt_set_ignoreprefix(vmlog_options *opts, const char *arg);
264 int vmlog_opt_parse_seq(const char *arg,int len,vmlog_seq_t *seq);
265 int vmlog_opt_parse_range(const char *arg,vmlog_seq_t *start,vmlog_seq_t *end);
266 vmlog_options *vmlog_opt_parse_cmd_line(int *pargc,char **argv);
267 void vmlog_opt_free(vmlog_options *opts);
268
269 /*** memory allocation helpers ***************************************/
270
271 /* allocate, check, and zero memory */
272 #define VMLOG_XZNEW(var,type) \
273         do { var = VMLOG_NEW(type); \
274              if (!(var)) vmlog_die("out of memory"); \
275              memset((var),0,sizeof(type)); \
276         } while (0)
277
278 /* allocate, check, and zero memory for array */
279 #define VMLOG_XZNEW_ARRAY(var,type,n) \
280         do { var = VMLOG_NEW_ARRAY(type,n); \
281              if (!(var)) vmlog_die("out of memory"); \
282              memset((var),0,(n)*sizeof(type)); \
283         } while (0)
284
285 #endif
286
287 /* vim: noet ts=8 sw=8
288  */