source: libwandio/wandio.c @ 10f924c

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 10f924c was 10f924c, checked in by Shane Alcock <salcock@…>, 7 years ago

Fixed broken -fvisibility check in configure

  • Added a m4 script that does this properly rather than our hax gcc version check.
  • Tidied up CFLAGS in configure so we aren't adding the same sets of flags multiple times
  • Created a wandio_internal.h file for storing global variables that shouldn't be made public

Thanks to Alistair King, whose patch to try and make this work for
non-gcc systems brought my attention to just how broken this was :)

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
5 * New Zealand.
6 *
7 * Authors: Daniel Lawson
8 *          Perry Lorier
9 *          Shane Alcock
10 *         
11 * All rights reserved.
12 *
13 * This code has been developed by the University of Waikato WAND
14 * research group. For further information please see http://www.wand.net.nz/
15 *
16 * libtrace is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * libtrace is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with libtrace; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 *
30 * $Id$
31 *
32 */
33
34
35#include "config.h"
36#include "wandio_internal.h"
37#include "wandio.h"
38#include <stdlib.h>
39#include <assert.h>
40#include <errno.h>
41#include <inttypes.h>
42#include <string.h>
43
44/* This file contains the implementation of the libtrace IO API, which format
45 * modules should use to open, read from, write to, seek and close trace files.
46 */
47
48struct compression_type compression_type[]  = {
49        { "GZ",         "gz",   WANDIO_COMPRESS_ZLIB    },
50        { "BZ2",        "bz2",  WANDIO_COMPRESS_BZ2     },
51        { "LZO",        "lzo",  WANDIO_COMPRESS_LZO     },
52        { "NONE",       "",     WANDIO_COMPRESS_NONE    }
53};
54
55int keep_stats = 0;
56int force_directio_write = 0;
57int force_directio_read = 0;
58int use_autodetect = 1;
59unsigned int use_threads = -1;
60unsigned int max_buffers = 50;
61
62uint64_t read_waits = 0;
63uint64_t write_waits = 0;
64
65/** Parse an option.
66 * stats -- Show summary stats
67 * directwrite -- bypass the diskcache on write
68 * directread -- bypass the diskcache on read
69 * noautodetect -- disable autodetection of file compression, assume all files
70 *                 are uncompressed
71 * nothreads -- Don't use threads
72 * threads=n -- Use a maximum of 'n' threads for thread farms
73 */
74static void do_option(const char *option)
75{
76        if (*option == '\0') 
77                ;
78        else if (strcmp(option,"stats") == 0)
79                keep_stats = 1;
80        /*
81        else if (strcmp(option,"directwrite") == 0)
82                force_directio_write = 1;
83        else if (strcmp(option,"directread") == 0)
84                force_directio_read  = 1;
85        */
86        else if (strcmp(option,"nothreads") == 0)
87                use_threads = 0;
88        else if (strcmp(option,"noautodetect") == 0)
89                use_autodetect = 0;
90        else if (strncmp(option,"threads=",8) == 0)
91                use_threads = atoi(option+8);
92        else if (strncmp(option,"buffers=",8) == 0)
93                max_buffers = atoi(option+8);
94        else {
95                fprintf(stderr,"Unknown libtraceio debug option '%s'\n", option);
96        }
97}
98
99static void parse_env(void)
100{
101        const char *str = getenv("LIBTRACEIO");
102        char option[1024];
103        const char *ip;
104        char *op;
105
106        if (!str)
107                return;
108
109        for(ip=str, op=option; *ip!='\0' && op < option+sizeof(option); ++ip) {
110                if (*ip == ',') {
111                        *op='\0';
112                        do_option(option);
113                        op=option;
114                }
115                else
116                        *(op++) = *ip;
117        }
118        *op='\0';
119        do_option(option);
120}
121
122
123#define READ_TRACE 0
124#define WRITE_TRACE 0
125#define PIPELINE_TRACE 0
126
127#if PIPELINE_TRACE
128#define DEBUG_PIPELINE(x) fprintf(stderr,"PIPELINE: %s\n",x)
129#else
130#define DEBUG_PIPELINE(x)
131#endif
132
133static io_t *create_io_reader(const char *filename, int autodetect)
134{
135
136        /* Use a peeking reader to look at the start of the trace file and
137         * determine what type of compression may have been used to write
138         * the file */
139
140        DEBUG_PIPELINE("stdio");
141        DEBUG_PIPELINE("peek");
142        io_t *io = peek_open(stdio_open(filename));
143        char buffer[1024];
144        int len;
145        if (!io)
146                return NULL;
147        len = wandio_peek(io, buffer, sizeof(buffer));
148        /* Auto detect gzip compressed data -- if autodetect is false,
149         * instead we just assume uncompressed.
150         */
151
152        if (autodetect) {
153                if (len>=3 && buffer[0] == '\037' && buffer[1] == '\213' &&
154                                buffer[2] == 0x08) { 
155#if HAVE_LIBZ
156                        DEBUG_PIPELINE("zlib");
157                        io = zlib_open(io);
158#else
159                        fprintf(stderr, "File %s is gzip compressed but libtrace has not been built with zlib support!\n", filename);
160                        return NULL;
161#endif
162                }
163                /* Auto detect compress(1) compressed data (gzip can read this) */
164                if (len>=2 && buffer[0] == '\037' && buffer[1] == '\235') {
165#if HAVE_LIBZ
166                        DEBUG_PIPELINE("zlib");
167                        io = zlib_open(io);
168#else
169                        fprintf(stderr, "File %s is compress(1) compressed but libtrace has not been built with zlib support!\n", filename);
170                        return NULL;
171#endif
172                }
173
174                /* Auto detect bzip compressed data */
175                if (len>=3 && buffer[0] == 'B' && buffer[1] == 'Z' && buffer[2] == 'h') { 
176#if HAVE_LIBBZ2
177                        DEBUG_PIPELINE("bzip");
178                        io = bz_open(io);
179#else
180                        fprintf(stderr, "File %s is bzip compressed but libtrace has not been built with bzip2 support!\n", filename);
181                        return NULL;
182#endif
183                }
184        }       
185        /* Now open a threaded, peekable reader using the appropriate module
186         * to read the data */
187
188        if (use_threads) {
189                DEBUG_PIPELINE("thread");
190                io = thread_open(io);
191        }
192       
193        DEBUG_PIPELINE("peek");
194        return peek_open(io);
195}
196
197DLLEXPORT io_t *wandio_create(const char *filename) {
198        parse_env();
199        return create_io_reader(filename, use_autodetect);
200}
201
202DLLEXPORT io_t *wandio_create_uncompressed(const char *filename) {
203        parse_env();
204        return create_io_reader(filename, 0);
205}
206
207
208DLLEXPORT off_t wandio_tell(io_t *io)
209{
210        if (!io->source->tell) {
211                errno = -ENOSYS;
212                return -1;
213        }
214        return io->source->tell(io);
215}
216
217DLLEXPORT off_t wandio_seek(io_t *io, off_t offset, int whence)
218{
219        if (!io->source->seek) {
220                errno = -ENOSYS;
221                return -1;
222        }
223        return io->source->seek(io,offset,whence);
224}
225
226DLLEXPORT off_t wandio_read(io_t *io, void *buffer, off_t len)
227{ 
228        off_t ret;
229        ret=io->source->read(io,buffer,len); 
230#if READ_TRACE
231        fprintf(stderr,"%p: read(%s): %d bytes = %d\n",io,io->source->name, (int)len,(int)ret);
232#endif
233        return ret;
234}
235
236DLLEXPORT off_t wandio_peek(io_t *io, void *buffer, off_t len)
237{
238        off_t ret;
239        assert(io->source->peek); /* If this fails, it means you're calling
240                                   * peek on something that doesn't support
241                                   * peeking.   Push a peek_open() on the io
242                                   * first.
243                                   */
244        ret=io->source->peek(io, buffer, len);
245#if READ_TRACE
246        fprintf(stderr,"%p: peek(%s): %d bytes = %d\n",io,io->source->name, (int)len, (int)ret);
247#endif
248        return ret;
249}
250
251DLLEXPORT void wandio_destroy(io_t *io)
252{ 
253        if (!io)
254                return;
255       
256        if (keep_stats) 
257                fprintf(stderr,"LIBTRACEIO STATS: %"PRIu64" blocks on read\n", read_waits);
258        io->source->close(io); 
259}
260
261DLLEXPORT iow_t *wandio_wcreate(const char *filename, int compress_type, int compression_level, int flags)
262{
263        iow_t *iow;
264        parse_env();
265
266        assert ( compression_level >= 0 && compression_level <= 9 );
267        assert (compress_type != WANDIO_COMPRESS_MASK);
268
269        iow=stdio_wopen(filename, flags);
270        if (!iow)
271                return NULL;
272
273        /* We prefer zlib if available, otherwise we'll use bzip. If neither
274         * are present, guess we'll just have to write uncompressed */
275#if HAVE_LIBZ
276        if (compression_level != 0 && 
277            compress_type == WANDIO_COMPRESS_ZLIB) {
278                iow = zlib_wopen(iow,compression_level);
279        }
280#endif
281#if HAVE_LIBLZO2
282        else if (compression_level != 0 && 
283            compress_type == WANDIO_COMPRESS_LZO) {
284                iow = lzo_wopen(iow,compression_level);
285        }
286#endif
287#if HAVE_LIBBZ2
288        else if (compression_level != 0 && 
289            compress_type == WANDIO_COMPRESS_BZ2) {
290                iow = bz_wopen(iow,compression_level);
291        }
292#endif
293        /* Open a threaded writer */
294        if (use_threads)
295                return thread_wopen(iow);
296        else
297                return iow;
298}
299
300DLLEXPORT off_t wandio_wwrite(iow_t *iow, const void *buffer, off_t len)
301{
302#if WRITE_TRACE
303        fprintf(stderr,"wwrite(%s): %d bytes\n",iow->source->name, (int)len);
304#endif
305        return iow->source->write(iow,buffer,len);     
306}
307
308DLLEXPORT void wandio_wdestroy(iow_t *iow)
309{
310        iow->source->close(iow);
311        if (keep_stats) 
312                fprintf(stderr,"LIBTRACEIO STATS: %"PRIu64" blocks on write\n", write_waits);
313}
314
Note: See TracBrowser for help on using the repository browser.