Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /branches/MSVC/src/logging.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1663 - (show annotations) (download) (as text)
Tue May 19 18:09:18 2015 UTC (9 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 13567 byte(s)
Remove <sys/time.h> where not needed at all or when compiling with
Microsoft C compiler (in which case add a replacement gettimeofday
function) [inspired by patches from Oliver Eichler].

1 /***************************************
2 Functions to handle logging functions.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2015 Andrew M. Bishop
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***************************************/
21
22
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28
29 #if defined(_MSC_VER)
30
31 #include <WinSock2.h>
32
33 static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
34
35 int gettimeofday(struct timeval * tp, struct timezone * tzp)
36 {
37 FILETIME file_time;
38 SYSTEMTIME system_time;
39 ULARGE_INTEGER ularge;
40
41 GetSystemTime(&system_time);
42 SystemTimeToFileTime(&system_time, &file_time);
43 ularge.LowPart = file_time.dwLowDateTime;
44 ularge.HighPart = file_time.dwHighDateTime;
45
46 tp->tv_sec = (long) ((ularge.QuadPart - EPOCH) / 10000000L);
47 tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
48 return 0;
49 }
50
51 #else
52
53 #include <sys/time.h>
54
55 #endif
56
57 #include "logging.h"
58
59
60 /* Global variables */
61
62 /*+ The option to print the output in a way that allows logging to a file. +*/
63 int option_loggable=0;
64
65 /*+ The option to print elapsed time with the output. +*/
66 int option_logtime=0;
67
68 /*+ The option to print memory usage with the output. +*/
69 int option_logmemory=0;
70
71
72 /* Local data types */
73
74 /*+ A structure to contain the list of allocated memory. +*/
75 struct mallocinfo
76 {
77 void *address; /*+ The address of the allocated memory. +*/
78 size_t size; /*+ The size of the allocated memory. +*/
79 };
80
81
82 /* Local functions */
83
84 static void vfprintf_first(FILE *file,const char *format,va_list ap);
85 static void vfprintf_middle(FILE *file,const char *format,va_list ap);
86 static void vfprintf_last(FILE *file,const char *format,va_list ap);
87
88 static void fprintf_elapsed_time(FILE *file,struct timeval *start);
89 static void fprintf_max_memory(FILE *file,size_t max_alloc,size_t max_mmap);
90
91
92 /* Local variables */
93
94 /*+ The time that program_start() was called. +*/
95 static struct timeval program_start_time;
96
97 /*+ The time that printf_first() was called. +*/
98 static struct timeval function_start_time;
99
100 /*+ The list of allocated memory. +*/
101 static struct mallocinfo *mallocedmem;
102
103 /*+ The number of allocated memory blocks. +*/
104 static int nmallocedmem=0;
105
106 /*+ The length of the string printed out last time. +*/
107 static int printed_length=0;
108
109 /*+ The maximum amount of memory allocated and memory mapped since starting the program. +*/
110 static size_t program_max_alloc=0,program_max_mmap=0;
111
112 /*+ The maximum amount of memory allocated and memory mapped since starting the function. +*/
113 static size_t function_max_alloc=0,function_max_mmap=0;
114
115 /*+ The current amount of memory allocated and memory mapped. +*/
116 static size_t current_alloc=0,current_mmap=0;
117
118
119 /*++++++++++++++++++++++++++++++++++++++
120 Record the time that the program started.
121 ++++++++++++++++++++++++++++++++++++++*/
122
123 void printf_program_start(void)
124 {
125 gettimeofday(&program_start_time,NULL);
126
127 program_max_alloc=program_max_mmap=0;
128 }
129
130
131 /*++++++++++++++++++++++++++++++++++++++
132 Record the time that the program started.
133 ++++++++++++++++++++++++++++++++++++++*/
134
135 void printf_program_end(void)
136 {
137 if(option_logtime || option_logmemory)
138 {
139 if(option_logtime)
140 fprintf_elapsed_time(stdout,&program_start_time);
141
142 if(option_logmemory)
143 fprintf_max_memory(stdout,program_max_alloc,program_max_mmap);
144
145 printf("Finish Program\n");
146
147 if(option_logtime==2)
148 printf("[ m:ss.micros] ");
149 else if(option_logtime==1)
150 printf("[ m:ss.mil] ");
151
152 if(option_logmemory)
153 printf("[RAM,FILE MB] ");
154
155 if(option_logtime)
156 printf("elapsed time");
157
158 if(option_logmemory)
159 {
160 if(option_logtime)
161 printf(", ");
162 printf("maximum memory");
163 }
164
165 printf("\n");
166
167 fflush(stdout);
168 }
169 }
170
171
172 /*++++++++++++++++++++++++++++++++++++++
173 Print the first message in an overwriting sequence (to stdout).
174
175 const char *format The format string.
176
177 ... The other arguments.
178 ++++++++++++++++++++++++++++++++++++++*/
179
180 void printf_first(const char *format, ...)
181 {
182 va_list ap;
183
184 if(option_logtime)
185 gettimeofday(&function_start_time,NULL);
186
187 if(option_logmemory)
188 {
189 function_max_alloc=current_alloc;
190 function_max_mmap=current_mmap;
191 }
192
193 if(option_loggable)
194 return;
195
196 va_start(ap,format);
197
198 vfprintf_first(stdout,format,ap);
199
200 va_end(ap);
201 }
202
203
204 /*++++++++++++++++++++++++++++++++++++++
205 Print the middle message in an overwriting sequence (to stdout).
206
207 const char *format The format string.
208
209 ... The other arguments.
210 ++++++++++++++++++++++++++++++++++++++*/
211
212 void printf_middle(const char *format, ...)
213 {
214 va_list ap;
215
216 if(option_loggable)
217 return;
218
219 va_start(ap,format);
220
221 vfprintf_middle(stdout,format,ap);
222
223 va_end(ap);
224 }
225
226
227 /*++++++++++++++++++++++++++++++++++++++
228 Print the last message in an overwriting sequence (to stdout).
229
230 const char *format The format string.
231
232 ... The other arguments.
233 ++++++++++++++++++++++++++++++++++++++*/
234
235 void printf_last(const char *format, ...)
236 {
237 va_list ap;
238
239 va_start(ap,format);
240
241 vfprintf_last(stdout,format,ap);
242
243 va_end(ap);
244 }
245
246
247 /*++++++++++++++++++++++++++++++++++++++
248 Print the first message in an overwriting sequence to a specified file.
249
250 FILE *file The file to write to.
251
252 const char *format The format string.
253
254 ... The other arguments.
255 ++++++++++++++++++++++++++++++++++++++*/
256
257 void fprintf_first(FILE *file,const char *format, ...)
258 {
259 va_list ap;
260
261 if(option_logtime)
262 gettimeofday(&function_start_time,NULL);
263
264 if(option_logmemory)
265 {
266 function_max_alloc=current_alloc;
267 function_max_mmap=current_mmap;
268 }
269
270 if(option_loggable)
271 return;
272
273 va_start(ap,format);
274
275 vfprintf_first(file,format,ap);
276
277 va_end(ap);
278 }
279
280
281 /*++++++++++++++++++++++++++++++++++++++
282 Print the middle message in an overwriting sequence to a specified file.
283
284 FILE *file The file to write to.
285
286 const char *format The format string.
287
288 ... The other arguments.
289 ++++++++++++++++++++++++++++++++++++++*/
290
291 void fprintf_middle(FILE *file,const char *format, ...)
292 {
293 va_list ap;
294
295 if(option_loggable)
296 return;
297
298 va_start(ap,format);
299
300 vfprintf_middle(file,format,ap);
301
302 va_end(ap);
303 }
304
305
306 /*++++++++++++++++++++++++++++++++++++++
307 Print the last message in an overwriting sequence to a specified file.
308
309 FILE *file The file to write to.
310
311 const char *format The format string.
312
313 ... The other arguments.
314 ++++++++++++++++++++++++++++++++++++++*/
315
316 void fprintf_last(FILE *file,const char *format, ...)
317 {
318 va_list ap;
319
320 va_start(ap,format);
321
322 vfprintf_last(file,format,ap);
323
324 va_end(ap);
325 }
326
327
328 /*++++++++++++++++++++++++++++++++++++++
329 Record the memory allocations (record the amount in use).
330
331 void *address The address that has been allocated.
332
333 size_t size The size of the memory that has been allocated.
334 ++++++++++++++++++++++++++++++++++++++*/
335
336 void log_malloc(void *address,size_t size)
337 {
338 int i;
339
340 if(!option_logmemory)
341 return;
342
343 /* Store the information about the allocated memory */
344
345 for(i=0;i<nmallocedmem;i++)
346 if(mallocedmem[i].address==address)
347 {
348 size=size-mallocedmem[i].size;
349 mallocedmem[i].size+=size;
350 break;
351 }
352
353 if(i==nmallocedmem)
354 {
355 mallocedmem=(struct mallocinfo*)realloc((void*)mallocedmem,(nmallocedmem+1)*sizeof(struct mallocinfo));
356
357 mallocedmem[nmallocedmem].address=address;
358 mallocedmem[nmallocedmem].size=size;
359
360 nmallocedmem++;
361 }
362
363 /* Increase the sum of allocated memory */
364
365 current_alloc+=size;
366
367 if(current_alloc>function_max_alloc)
368 function_max_alloc=current_alloc;
369
370 if(current_alloc>program_max_alloc)
371 program_max_alloc=current_alloc;
372 }
373
374
375 /*++++++++++++++++++++++++++++++++++++++
376 Record the memory de-allocations.
377
378 void *address The address that has been freed.
379 ++++++++++++++++++++++++++++++++++++++*/
380
381 void log_free(void *address)
382 {
383 size_t size=0;
384 int i;
385
386 if(!option_logmemory)
387 return;
388
389 /* Remove the information about the allocated memory */
390
391 for(i=0;i<nmallocedmem;i++)
392 if(mallocedmem[i].address==address)
393 {
394 size=mallocedmem[i].size;
395 break;
396 }
397
398 logassert(i!=nmallocedmem,"Memory freed with log_free() was not allocated with log_[cm]alloc()");
399
400 nmallocedmem--;
401
402 if(nmallocedmem>i)
403 memmove(&mallocedmem[i],&mallocedmem[i+1],(nmallocedmem-i)*sizeof(struct mallocinfo));
404
405 /* Reduce the sum of allocated memory */
406
407 current_alloc-=size;
408 }
409
410
411 /*++++++++++++++++++++++++++++++++++++++
412 Record the amount of memory that has been mapped into files.
413
414 size_t size The size of the file that has been mapped.
415 ++++++++++++++++++++++++++++++++++++++*/
416
417 void log_mmap(size_t size)
418 {
419 if(!option_logmemory)
420 return;
421
422 current_mmap+=size;
423
424 if(current_mmap>function_max_mmap)
425 function_max_mmap=current_mmap;
426
427 if(current_mmap>program_max_mmap)
428 program_max_mmap=current_mmap;
429 }
430
431
432 /*++++++++++++++++++++++++++++++++++++++
433 Record the amount of memory that has been unmapped from files.
434
435 size_t size The size of the file that has been unmapped.
436 ++++++++++++++++++++++++++++++++++++++*/
437
438 void log_munmap(size_t size)
439 {
440 if(!option_logmemory)
441 return;
442
443 current_mmap-=size;
444 }
445
446
447 /*++++++++++++++++++++++++++++++++++++++
448 Do the work to print the first message in an overwriting sequence.
449
450 FILE *file The file to write to.
451
452 const char *format The format string.
453
454 va_list ap The other arguments.
455 ++++++++++++++++++++++++++++++++++++++*/
456
457 static void vfprintf_first(FILE *file,const char *format,va_list ap)
458 {
459 int retval;
460
461 if(option_logtime)
462 fprintf_elapsed_time(file,&function_start_time);
463
464 if(option_logmemory)
465 fprintf_max_memory(file,function_max_alloc,function_max_mmap);
466
467 retval=vfprintf(file,format,ap);
468 fflush(file);
469
470 if(retval>0)
471 printed_length=retval;
472 }
473
474
475 /*++++++++++++++++++++++++++++++++++++++
476 Do the work to print the middle message in an overwriting sequence.
477
478 FILE *file The file to write to.
479
480 const char *format The format string.
481
482 va_list ap The other arguments.
483 ++++++++++++++++++++++++++++++++++++++*/
484
485 static void vfprintf_middle(FILE *file,const char *format,va_list ap)
486 {
487 int retval;
488
489 fputc('\r',file);
490
491 if(option_logtime)
492 fprintf_elapsed_time(file,&function_start_time);
493
494 if(option_logmemory)
495 fprintf_max_memory(file,function_max_alloc,function_max_mmap);
496
497 retval=vfprintf(file,format,ap);
498 fflush(file);
499
500 if(retval>0)
501 {
502 int new_printed_length=retval;
503
504 while(retval++<printed_length)
505 fputc(' ',file);
506
507 printed_length=new_printed_length;
508 }
509 }
510
511
512 /*++++++++++++++++++++++++++++++++++++++
513 Do the work to print the last message in an overwriting sequence.
514
515 FILE *file The file to write to.
516
517 const char *format The format string.
518
519 va_list ap The other arguments.
520 ++++++++++++++++++++++++++++++++++++++*/
521
522 static void vfprintf_last(FILE *file,const char *format,va_list ap)
523 {
524 int retval;
525
526 if(!option_loggable)
527 fputc('\r',file);
528
529 if(option_logtime)
530 fprintf_elapsed_time(file,&function_start_time);
531
532 if(option_logmemory)
533 fprintf_max_memory(file,function_max_alloc,function_max_mmap);
534
535 retval=vfprintf(file,format,ap);
536
537 if(retval>0)
538 while(retval++<printed_length)
539 fputc(' ',file);
540
541 fputc('\n',file);
542 fflush(file);
543 }
544
545
546 /*++++++++++++++++++++++++++++++++++++++
547 Print the elapsed time without a following newline.
548
549 FILE *file The file to print to.
550
551 struct timeval *start The start time from which the elapsed time is to be printed.
552 ++++++++++++++++++++++++++++++++++++++*/
553
554 static void fprintf_elapsed_time(FILE *file,struct timeval *start)
555 {
556 struct timeval finish,elapsed;
557
558 gettimeofday(&finish,NULL);
559
560 elapsed.tv_sec =finish.tv_sec -start->tv_sec;
561 elapsed.tv_usec=finish.tv_usec-start->tv_usec;
562 if(elapsed.tv_usec<0)
563 {
564 elapsed.tv_sec -=1;
565 elapsed.tv_usec+=1000000;
566 }
567
568 if(option_logtime==2)
569 fprintf(file,"[%2ld:%02ld.%06ld] ",elapsed.tv_sec/60,elapsed.tv_sec%60,elapsed.tv_usec);
570 else
571 fprintf(file,"[%2ld:%02ld.%03ld] ",elapsed.tv_sec/60,elapsed.tv_sec%60,elapsed.tv_usec/1000);
572 }
573
574
575 /*++++++++++++++++++++++++++++++++++++++
576 Print the maximum used memory without a following newline.
577
578 FILE *file The file to print to.
579
580 size_t max_alloc The maximum amount of allocated memory.
581
582 size_t max_mmap The maximum amount of memory mapped memory.
583 ++++++++++++++++++++++++++++++++++++++*/
584
585 static void fprintf_max_memory(FILE *file,size_t max_alloc,size_t max_mmap)
586 {
587 fprintf(file,"[%3zu, %3zu MB] ",max_alloc/(1024*1024),max_mmap/(1024*1024));
588 }
589
590
591 /*++++++++++++++++++++++++++++++++++++++
592 Log a fatal error and exit
593
594 const char *message The error message.
595
596 const char *file The file in which the error occured.
597
598 int line The line number in the file at which the error occured.
599 ++++++++++++++++++++++++++++++++++++++*/
600
601 void _logassert(const char *message,const char *file,int line)
602 {
603 fprintf(stderr,"Routino Fatal Error (%s:%d): %s\n",file,line,message);
604
605 exit(EXIT_FAILURE);
606 }