提交 74d195cd 编写于 作者: Z Zhou Yaoyang

Adding GEM5 utils

上级 3d7415d3
......@@ -3,6 +3,7 @@
!*/
!Makefile*
!*.[cSh]
!*.cpp
!.gitignore
!README.md
!runall.sh
/*
* Copyright (c) 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2013 Andreas Sandberg
* Copyright (c) 2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Nathan Binkert
* Chris Emmons
* Andreas Sandberg
* Sascha Bischoff
*/
#ifndef __BASE_OUTPUT_HH__
#define __BASE_OUTPUT_HH__
#include <ios>
#include <map>
#include <string>
class OutputDirectory;
class OutputStream
{
public:
virtual ~OutputStream();
/** Get the output underlying output stream */
std::ostream *stream() const { return _stream; };
/**
* Can the file be recreated if the output directory is moved?
*
* @return true if the file will be created in the new location,
* false otherwise.
*/
virtual bool recreateable() const { return false; }
/** Get the file name in the output directory */
const std::string &name() const { return _name; }
protected:
friend class OutputDirectory;
/** Wrap an existing stream */
OutputStream(const std::string &name,
std::ostream *stream);
/* Prevent copying */
OutputStream(const OutputStream &f);
/** Re-create the in a new location if recreateable. */
virtual void relocate(const OutputDirectory &dir);
/** Name in output directory */
const std::string _name;
/** Underlying output stream */
std::ostream *const _stream;
};
template<class StreamType>
class OutputFile
: public OutputStream
{
public:
typedef StreamType stream_type_t;
virtual ~OutputFile();
/**
* Can the file be recreated if the output directory is moved?
*
* @return true if the file will be created in the new location,
* false otherwise.
*/
bool recreateable() const override { return _recreateable; }
protected:
friend class OutputDirectory;
OutputFile(const OutputDirectory &dir,
const std::string &name,
std::ios_base::openmode mode,
bool recreateable);
/* Prevent copying */
OutputFile(const OutputFile<StreamType> &f);
/** Re-create the file in a new location if it is relocatable. */
void relocate(const OutputDirectory &dir) override;
/** File mode when opened */
const std::ios_base::openmode _mode;
/** Can the file be recreated in a new location? */
const bool _recreateable;
/** Pointer to the file stream */
stream_type_t *const _fstream;
};
/** Interface for creating files in a gem5 output directory. */
class OutputDirectory
{
private:
/** File names and associated stream handles */
typedef std::map<std::string, OutputStream *> file_map_t;
/** Output subdirectories */
typedef std::map<std::string, OutputDirectory *> dir_map_t;
/** Open file streams within this directory */
file_map_t files;
/** Output sub-directories */
dir_map_t dirs;
/** Name of this directory */
std::string dir;
/** System-specific path separator character */
static const char PATH_SEPARATOR = '/';
static OutputStream stdout;
static OutputStream stderr;
protected:
/**
* Determines whether given file name corresponds to standard output
* streams.
*
* @param name name of file to check
* @return output stream for standard output or error stream if name
* corresponds to one or the other; NULL otherwise
*/
static OutputStream *checkForStdio(const std::string &name);
public:
/** Constructor. */
OutputDirectory();
/** Constructor. */
OutputDirectory(const std::string &name);
/** Destructor. */
~OutputDirectory();
/**
* Returns relative file names prepended with name of this directory.
* Returns absolute file names unaltered.
*
* @param name file name to prepend with directory name
* @return file name prepended with base directory name or unaltered
* absolute file name
*/
std::string resolve(const std::string &name) const;
/**
* Sets name of this directory.
* @param dir name of this directory
*/
void setDirectory(const std::string &dir);
/**
* Gets name of this directory.
* @return name of this directory
*/
const std::string &directory() const;
/**
* Creates a file in this directory (optionally compressed).
*
* Will open a file as a compressed stream if filename ends in .gz, unless
* explicitly disabled.
*
* Relative output paths will result in the creation of a
* recreateable (see OutputFile) output file in the current output
* directory. Files created with an absolute path will not be
* recreateable.
*
* @param name name of file to create (without this directory's name
* leading it)
* @param binary true to create a binary file; false otherwise
* @param no_gz true to disable opening the file as a gzip compressed output
* stream; false otherwise
* @return OutputStream instance representing the created file
*/
OutputStream *create(const std::string &name,
bool binary = false,
bool no_gz = false);
/**
* Open a file in this directory (optionally compressed).
*
* Will open a file as a compressed stream if filename ends in .gz, unless
* explicitly disabled.
*
* @param filename file to open
* @param mode attributes to open file with
* @param recreateable Set to true if the file can be recreated in a new
* location.
* @param no_gz true to disable opening the file as a gzip compressed output
* stream; false otherwise
* @return OutputStream instance representing the opened file
*/
OutputStream *open(const std::string &name,
std::ios_base::openmode mode,
bool recreateable = true,
bool no_gz = false);
/**
* Closes an output file and free the corresponding OutputFile.
*
* The output file must have been opened by the same
* OutputDirectory instance as the one closing it, or sim will
* fail.
*
* @param file OutputStream instance in this OutputDirectory.
*/
void close(OutputStream *file);
/**
* Finds stream associated with an open file or stdout/stderr.
*
* @param name of file
* @return stream to specified file or NULL if file does not exist
*/
OutputStream *find(const std::string &name) const;
OutputStream *findOrCreate(const std::string &name, bool binary = false);
/**
* Determines whether a file name corresponds to a file in this directory.
* @param name name of file to evaluate
* @return true iff file has been opened in this directory or exists on the
* file system within this directory
*/
bool isFile(const std::string &name) const;
/**
* Test if a path is absolute.
*/
static inline bool isAbsolute(const std::string &name) {
return name[0] == PATH_SEPARATOR;
}
/**
* Creates a subdirectory within this directory.
* @param name name of subdirectory
* @return the new subdirectory's name suffixed with a path separator
*/
OutputDirectory *createSubdirectory(const std::string &name);
/**
* Removes a specified file or subdirectory.
*
* Will cause sim to fail for most errors. However, it will only warn the
* user if a directory could not be removed. This is in place to
* accommodate slow file systems where file deletions within a subdirectory
* may not be recognized quickly enough thereby causing the subsequent call
* to remove the directory to fail (seemingly unempty directory).
*
* @param name name of file or subdirectory to remove; name should not
* be prepended with the name of this directory object
* @param recursive set to true to attempt to recursively delete a
* subdirectory and its contents
*/
void remove(const std::string &name, bool recursive=false);
};
extern OutputDirectory simout;
#endif // __BASE_OUTPUT_HH__
/*
* Copyright (c) 2012-2014 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Dam Sunwoo
* Curtis Dunham
*/
#ifndef __CPU_SIMPLE_PROBES_SIMPOINT_HH__
#define __CPU_SIMPLE_PROBES_SIMPOINT_HH__
#include <unordered_map>
#include <base/output.h>
namespace SimPointNS {
using Addr = uint64_t;
/**
* Probe for SimPoints BBV generation
*/
/**
* Start and end address of basic block for SimPoint profiling.
* This structure is used to look up the hash table of BBVs.
* - first: PC of first inst in basic block
* - second: PC of last inst in basic block
*/
typedef std::pair<Addr, Addr> BasicBlockRange;
}
/** Overload hash function for BasicBlockRange type */
namespace std {
using SimPointNS::BasicBlockRange;
using SimPointNS::Addr;
template<>
struct hash<BasicBlockRange>
{
public:
size_t operator()(const BasicBlockRange &bb) const {
return hash<Addr>()(bb.first + bb.second);
}
};
}
namespace SimPointNS {
class SimPoint
{
public:
SimPoint();
virtual ~SimPoint();
virtual void init();
/**
* Profile basic blocks for SimPoints.
* Called at every macro inst to increment basic block inst counts and
* to profile block if end of block.
*/
void profile(Addr pc, bool is_control, bool is_last_uop);
private:
/** SimPoint profiling interval size in instructions */
static constexpr uint64_t intervalSize = 200 * 1000 * 1000;
/** Inst count in current basic block */
uint64_t intervalCount;
/** Excess inst count from previous interval*/
uint64_t intervalDrift;
/** Pointer to SimPoint BBV output stream */
OutputStream *simpointStream;
/** Basic Block information */
struct BBInfo
{
/** Unique ID */
uint64_t id;
/** Num of static insts in BB */
uint64_t insts;
/** Accumulated dynamic inst count executed by BB */
uint64_t count;
};
/** Hash table containing all previously seen basic blocks */
::std::unordered_map<BasicBlockRange, BBInfo> bbMap;
/** Currently executing basic block */
BasicBlockRange currentBBV;
/** inst count in current basic block */
uint64_t currentBBVInstCount;
};
}
#endif // __CPU_SIMPLE_PROBES_SIMPOINT_HH__
......@@ -26,6 +26,15 @@
#define panic(...) Assert(0, __VA_ARGS__)
#define xpanic(...) \
do { \
printf("\33[1;31m"); \
printf(__VA_ARGS__); \
printf("\33[0m\n"); \
assert(0); \
} while (0)
#define TODO() panic("please implement me")
#endif
/*
* A C++ I/O streams interface to the zlib gz* functions
*
* by Ludwig Schwardt <schwardt@sun.ac.za>
* original version by Kevin Ruland <kevin@rodin.wustl.edu>
*
* This version is standard-compliant and compatible with gcc 3.x.
*/
#ifndef ZFSTREAM_H
#define ZFSTREAM_H
#include <istream> // not iostream, since we don't need cin/cout
#include <ostream>
#include "zlib.h"
/*****************************************************************************/
/**
* @brief Gzipped file stream buffer class.
*
* This class implements basic_filebuf for gzipped files. It doesn't yet support
* seeking (allowed by zlib but slow/limited), putback and read/write access
* (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
* file streambuf.
*/
class gzfilebuf : public std::streambuf
{
public:
// Default constructor.
gzfilebuf();
// Destructor.
virtual
~gzfilebuf();
/**
* @brief Set compression level and strategy on the fly.
* @param comp_level Compression level (see zlib.h for allowed values)
* @param comp_strategy Compression strategy (see zlib.h for allowed values)
* @return Z_OK on success, Z_STREAM_ERROR otherwise.
*
* Unfortunately, these parameters cannot be modified separately, as the
* previous zfstream version assumed. Since the strategy is seldom changed,
* it can default and setcompression(level) then becomes like the old
* setcompressionlevel(level).
*/
int
setcompression(int comp_level,
int comp_strategy = Z_DEFAULT_STRATEGY);
/**
* @brief Check if file is open.
* @return True if file is open.
*/
bool
is_open() const { return (file != NULL); }
/**
* @brief Open gzipped file.
* @param name File name.
* @param mode Open mode flags.
* @return @c this on success, NULL on failure.
*/
gzfilebuf*
open(const char* name,
std::ios_base::openmode mode);
/**
* @brief Attach to already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags.
* @return @c this on success, NULL on failure.
*/
gzfilebuf*
attach(int fd,
std::ios_base::openmode mode);
/**
* @brief Close gzipped file.
* @return @c this on success, NULL on failure.
*/
gzfilebuf*
close();
protected:
/**
* @brief Convert ios open mode int to mode string used by zlib.
* @return True if valid mode flag combination.
*/
bool
open_mode(std::ios_base::openmode mode,
char* c_mode) const;
/**
* @brief Number of characters available in stream buffer.
* @return Number of characters.
*
* This indicates number of characters in get area of stream buffer.
* These characters can be read without accessing the gzipped file.
*/
virtual std::streamsize
showmanyc();
/**
* @brief Fill get area from gzipped file.
* @return First character in get area on success, EOF on error.
*
* This actually reads characters from gzipped file to stream
* buffer. Always buffered.
*/
virtual int_type
underflow();
/**
* @brief Write put area to gzipped file.
* @param c Extra character to add to buffer contents.
* @return Non-EOF on success, EOF on error.
*
* This actually writes characters in stream buffer to
* gzipped file. With unbuffered output this is done one
* character at a time.
*/
virtual int_type
overflow(int_type c = traits_type::eof());
/**
* @brief Installs external stream buffer.
* @param p Pointer to char buffer.
* @param n Size of external buffer.
* @return @c this on success, NULL on failure.
*
* Call setbuf(0,0) to enable unbuffered output.
*/
virtual std::streambuf*
setbuf(char_type* p,
std::streamsize n);
/**
* @brief Flush stream buffer to file.
* @return 0 on success, -1 on error.
*
* This calls underflow(EOF) to do the job.
*/
virtual int
sync();
//
// Some future enhancements
//
// virtual int_type uflow();
// virtual int_type pbackfail(int_type c = traits_type::eof());
// virtual pos_type
// seekoff(off_type off,
// std::ios_base::seekdir way,
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
// virtual pos_type
// seekpos(pos_type sp,
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
private:
/**
* @brief Allocate internal buffer.
*
* This function is safe to call multiple times. It will ensure
* that a proper internal buffer exists if it is required. If the
* buffer already exists or is external, the buffer pointers will be
* reset to their original state.
*/
void
enable_buffer();
/**
* @brief Destroy internal buffer.
*
* This function is safe to call multiple times. It will ensure
* that the internal buffer is deallocated if it exists. In any
* case, it will also reset the buffer pointers.
*/
void
disable_buffer();
/**
* Underlying file pointer.
*/
gzFile file;
/**
* Mode in which file was opened.
*/
std::ios_base::openmode io_mode;
/**
* @brief True if this object owns file descriptor.
*
* This makes the class responsible for closing the file
* upon destruction.
*/
bool own_fd;
/**
* @brief Stream buffer.
*
* For simplicity this remains allocated on the free store for the
* entire life span of the gzfilebuf object, unless replaced by setbuf.
*/
char_type* buffer;
/**
* @brief Stream buffer size.
*
* Defaults to system default buffer size (typically 8192 bytes).
* Modified by setbuf.
*/
std::streamsize buffer_size;
/**
* @brief True if this object owns stream buffer.
*
* This makes the class responsible for deleting the buffer
* upon destruction.
*/
bool own_buffer;
};
/*****************************************************************************/
/**
* @brief Gzipped file input stream class.
*
* This class implements ifstream for gzipped files. Seeking and putback
* is not supported yet.
*/
class gzifstream : public std::istream
{
public:
// Default constructor
gzifstream();
/**
* @brief Construct stream on gzipped file to be opened.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::in).
*/
explicit
gzifstream(const char* name,
std::ios_base::openmode mode = std::ios_base::in);
/**
* @brief Construct stream on already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::in).
*/
explicit
gzifstream(int fd,
std::ios_base::openmode mode = std::ios_base::in);
/**
* Obtain underlying stream buffer.
*/
gzfilebuf*
rdbuf() const
{ return const_cast<gzfilebuf*>(&sb); }
/**
* @brief Check if file is open.
* @return True if file is open.
*/
bool
is_open() { return sb.is_open(); }
/**
* @brief Open gzipped file.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::in).
*
* Stream will be in state good() if file opens successfully;
* otherwise in state fail(). This differs from the behavior of
* ifstream, which never sets the state to good() and therefore
* won't allow you to reuse the stream for a second file unless
* you manually clear() the state. The choice is a matter of
* convenience.
*/
void
open(const char* name,
std::ios_base::openmode mode = std::ios_base::in);
/**
* @brief Attach to already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::in).
*
* Stream will be in state good() if attach succeeded; otherwise
* in state fail().
*/
void
attach(int fd,
std::ios_base::openmode mode = std::ios_base::in);
/**
* @brief Close gzipped file.
*
* Stream will be in state fail() if close failed.
*/
void
close();
private:
/**
* Underlying stream buffer.
*/
gzfilebuf sb;
};
/*****************************************************************************/
/**
* @brief Gzipped file output stream class.
*
* This class implements ofstream for gzipped files. Seeking and putback
* is not supported yet.
*/
class gzofstream : public std::ostream
{
public:
// Default constructor
gzofstream();
/**
* @brief Construct stream on gzipped file to be opened.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::out).
*/
explicit
gzofstream(const char* name,
std::ios_base::openmode mode = std::ios_base::out);
/**
* @brief Construct stream on already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::out).
*/
explicit
gzofstream(int fd,
std::ios_base::openmode mode = std::ios_base::out);
/**
* Obtain underlying stream buffer.
*/
gzfilebuf*
rdbuf() const
{ return const_cast<gzfilebuf*>(&sb); }
/**
* @brief Check if file is open.
* @return True if file is open.
*/
bool
is_open() { return sb.is_open(); }
/**
* @brief Open gzipped file.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::out).
*
* Stream will be in state good() if file opens successfully;
* otherwise in state fail(). This differs from the behavior of
* ofstream, which never sets the state to good() and therefore
* won't allow you to reuse the stream for a second file unless
* you manually clear() the state. The choice is a matter of
* convenience.
*/
void
open(const char* name,
std::ios_base::openmode mode = std::ios_base::out);
/**
* @brief Attach to already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::out).
*
* Stream will be in state good() if attach succeeded; otherwise
* in state fail().
*/
void
attach(int fd,
std::ios_base::openmode mode = std::ios_base::out);
/**
* @brief Close gzipped file.
*
* Stream will be in state fail() if close failed.
*/
void
close();
private:
/**
* Underlying stream buffer.
*/
gzfilebuf sb;
};
/*****************************************************************************/
/**
* @brief Gzipped file output stream manipulator class.
*
* This class defines a two-argument manipulator for gzofstream. It is used
* as base for the setcompression(int,int) manipulator.
*/
template<typename T1, typename T2>
class gzomanip2
{
public:
// Allows insertor to peek at internals
template <typename Ta, typename Tb>
friend gzofstream&
operator<<(gzofstream&,
const gzomanip2<Ta,Tb>&);
// Constructor
gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
T1 v1,
T2 v2);
private:
// Underlying manipulator function
gzofstream&
(*func)(gzofstream&, T1, T2);
// Arguments for manipulator function
T1 val1;
T2 val2;
};
/*****************************************************************************/
// Manipulator function thunks through to stream buffer
inline gzofstream&
setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
{
(gzs.rdbuf())->setcompression(l, s);
return gzs;
}
// Manipulator constructor stores arguments
template<typename T1, typename T2>
inline
gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
T1 v1,
T2 v2)
: func(f), val1(v1), val2(v2)
{ }
// Insertor applies underlying manipulator function to stream
template<typename T1, typename T2>
inline gzofstream&
operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
{ return (*m.func)(s, m.val1, m.val2); }
// Insert this onto stream to simplify setting of compression level
inline gzomanip2<int,int>
setcompression(int l, int s = Z_DEFAULT_STRATEGY)
{ return gzomanip2<int,int>(&setcompression, l, s); }
#endif // ZFSTREAM_H
/*
* Copyright (c) 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2013 Andreas Sandberg
* Copyright (c) 2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Nathan Binkert
* Chris Emmons
* Andreas Sandberg
* Sascha Bischoff
*/
#include "base/output.h"
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream3/zfstream.h>
#include <cassert>
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <fstream>
#include <debug.h>
#include <iostream>
using namespace std;
OutputDirectory simout;
OutputStream::OutputStream(const std::string &name, std::ostream *stream)
: _name(name), _stream(stream)
{
}
OutputStream::~OutputStream()
{
}
void
OutputStream::relocate(const OutputDirectory &dir)
{
}
template<class StreamType>
OutputFile<StreamType>::OutputFile(const OutputDirectory &dir,
const std::string &name,
std::ios_base::openmode mode,
bool recreateable)
: OutputStream(name, new stream_type_t()),
_mode(mode), _recreateable(recreateable),
_fstream(static_cast<stream_type_t *>(_stream))
{
_fstream->open(dir.resolve(_name).c_str(), _mode);
assert(_fstream->is_open());
}
template<class StreamType>
OutputFile<StreamType>::~OutputFile()
{
if (_fstream->is_open())
_fstream->close();
}
template<class StreamType>
void
OutputFile<StreamType>::relocate(const OutputDirectory &dir)
{
if (_recreateable) {
_fstream->close();
_fstream->open(dir.resolve(_name).c_str(), _mode);
}
}
OutputStream OutputDirectory::stdout("stdout", &cout);
OutputStream OutputDirectory::stderr("stderr", &cerr);
/**
* @file This file manages creating / deleting output files for the simulator.
*/
OutputDirectory::OutputDirectory()
{}
OutputDirectory::OutputDirectory(const std::string &name)
{
setDirectory(name);
}
OutputDirectory::~OutputDirectory()
{
for (auto& f: files) {
if (f.second)
delete f.second;
}
}
OutputStream *
OutputDirectory::checkForStdio(const string &name)
{
if (name == "cerr" || name == "stderr")
return &stderr;
if (name == "cout" || name == "stdout")
return &stdout;
return NULL;
}
void
OutputDirectory::close(OutputStream *file)
{
auto i = files.find(file->name());
if (i == files.end())
xpanic("Attempted to close an unregistred file stream");
files.erase(i);
delete file;
}
void
OutputDirectory::setDirectory(const string &d)
{
const string old_dir(dir);
dir = d;
// guarantee that directory ends with a path separator
if (dir[dir.size() - 1] != PATH_SEPARATOR)
dir += PATH_SEPARATOR;
// Try to create the directory. If it already exists, that's ok;
// otherwise, fail if we couldn't create it.
if ((mkdir(dir.c_str(), 0755) != 0) && (errno != EEXIST))
xpanic("Failed to create new output subdirectory '%s'\n", dir);
// Check if we need to recreate anything
if (!old_dir.empty()) {
// Recreate output files
for (file_map_t::iterator i = files.begin(); i != files.end(); ++i) {
i->second->relocate(*this);
}
// Relocate sub-directories
for (dir_map_t::iterator i = dirs.begin(); i != dirs.end(); ++i) {
i->second->setDirectory(dir + PATH_SEPARATOR + i->first);
}
}
}
const string &
OutputDirectory::directory() const
{
if (dir.empty())
xpanic("Output directory not set!");
return dir;
}
string
OutputDirectory::resolve(const string &name) const
{
return !isAbsolute(name) ? dir + name : name;
}
OutputStream *
OutputDirectory::create(const string &name, bool binary, bool no_gz)
{
OutputStream *file = checkForStdio(name);
if (file)
return file;
const ios_base::openmode mode(
ios::trunc | (binary ? ios::binary : (ios::openmode)0));
const bool recreateable(!isAbsolute(name));
return open(name, mode, recreateable, no_gz);
}
OutputStream *
OutputDirectory::open(const std::string &name,
ios_base::openmode mode,
bool recreateable,
bool no_gz)
{
OutputStream *os;
if (!no_gz && name.find(".gz", name.length() - 3) < name.length()) {
// Although we are creating an output stream, we still need to pass the
// correct mode for gzofstream as this used directly to set the file
// mode.
mode |= std::ios::out;
os = new OutputFile<gzofstream>(*this, name, mode, recreateable);
} else {
os = new OutputFile<ofstream>(*this, name, mode, recreateable);
}
files[name] = os;
return os;
}
OutputStream *
OutputDirectory::find(const string &name) const
{
OutputStream *file = checkForStdio(name);
if (file)
return file;
auto i = files.find(name);
if (i != files.end())
return (*i).second;
return NULL;
}
OutputStream *
OutputDirectory::findOrCreate(const std::string &name, bool binary)
{
OutputStream *os(find(name));
if (os)
return os;
else
return create(name, binary);
}
bool
OutputDirectory::isFile(const string &name) const
{
// definitely a file if in our data structure
if (find(name) != NULL) return true;
struct stat st_buf;
int st = stat(name.c_str(), &st_buf);
return (st == 0) && S_ISREG(st_buf.st_mode);
}
OutputDirectory *
OutputDirectory::createSubdirectory(const string &name)
{
const string new_dir = resolve(name);
if (new_dir.find(directory()) == string::npos)
xpanic("Attempting to create subdirectory not in m5 output dir\n");
OutputDirectory *dir(new OutputDirectory(new_dir));
dirs[name] = dir;
return dir;
}
void
OutputDirectory::remove(const string &name, bool recursive)
{
const string fname = resolve(name);
if (fname.find(directory()) == string::npos)
xpanic("Attempting to remove file/dir not in output dir\n");
if (isFile(fname)) {
// close and release file if we have it open
auto i = files.find(fname);
if (i != files.end()) {
delete i->second;
files.erase(i);
}
if (::remove(fname.c_str()) != 0)
xpanic("Could not erase file '%s'\n", fname);
} else {
// assume 'name' is a directory
if (recursive) {
DIR *subdir = opendir(fname.c_str());
// silently ignore removal request for non-existent directory
if ((!subdir) && (errno == ENOENT))
return;
// fail on other errors
if (!subdir) {
perror("opendir");
xpanic("Error opening directory for recursive removal '%s'\n",
fname);
}
struct dirent *de = readdir(subdir);
while (de != NULL) {
// ignore files starting with a '.'; user must delete those
// manually if they really want to
if (de->d_name[0] != '.')
remove(name + PATH_SEPARATOR + de->d_name, recursive);
de = readdir(subdir);
}
closedir(subdir);
}
// try to force recognition that we deleted the files in the directory
sync();
if (::remove(fname.c_str()) != 0) {
perror("Warning! 'remove' failed. Could not erase directory.");
}
}
}
//
// Created by zyy on 2020/11/16.
//
#include "checkpoint/serializer.h"
#include <cinttypes>
#include <iostream>
#include <zlib.h>
#include <limits>
#include <memory/paddr.h>
using namespace std;
void Serializer::serializePMem() {
uint8_t *pmem = getPmem();
string filename = taskName + "." + phaseName + "." + weightIndicator + ".gz";
string filepath = outputPath + "/" +filename;
gzFile compressed_mem = gzopen(filepath.c_str(), "wb");
if (compressed_mem == nullptr) {
cerr << "Failed to open " << filepath << endl;
panic("Can't open physical memory checkpoint file!\n");
} else {
cout << "Opening " << filepath << " as checkpoint output file" << endl;
}
uint64_t pass_size = 0;
for (uint64_t written = 0; written < PMEM_SIZE; written += pass_size) {
pass_size = numeric_limits<int>::max() < ((int64_t) PMEM_SIZE - (int64_t) written) ?
numeric_limits<int>::max() : ((int64_t) PMEM_SIZE - (int64_t) written);
if (gzwrite(compressed_mem, pmem + written, (uint32_t) pass_size) != (int) pass_size) {
panic("Write failed on physical memory checkpoint file\n");
}
}
if (gzclose(compressed_mem)){
panic("Close failed on physical memory checkpoint file\n");
}
}
Serializer serializer;
\ No newline at end of file
/*
* Copyright (c) 2012-2014 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Dam Sunwoo
* Curtis Dunham
*/
#include <debug.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include "checkpoint/simpoint.h"
namespace SimPointNS
{
SimPoint::SimPoint()
: intervalCount(0),
intervalDrift(0),
simpointStream(nullptr),
currentBBV(0, 0),
currentBBVInstCount(0) {
simpointStream = simout.create("simpoint_bbv", false);
if (!simpointStream)
xpanic("unable to open SimPoint profile_file");
}
SimPoint::~SimPoint() {
simout.close(simpointStream);
}
void
SimPoint::init() {}
void
SimPoint::profile(Addr pc, bool is_control, bool is_last_uop) {
if (!is_last_uop)
return;
if (!currentBBVInstCount)
currentBBV.first = pc;
++intervalCount;
++currentBBVInstCount;
// If inst is control inst, assume end of basic block.
if (is_control) {
currentBBV.second = pc;
auto map_itr = bbMap.find(currentBBV);
if (map_itr == bbMap.end()) {
// If a new (previously unseen) basic block is found,
// add a new unique id, record num of insts and insert into bbMap.
BBInfo info;
info.id = bbMap.size() + 1;
info.insts = currentBBVInstCount;
info.count = currentBBVInstCount;
bbMap.insert(::std::make_pair(currentBBV, info));
} else {
// If basic block is seen before, just increment the count by the
// number of insts in basic block.
BBInfo &info = map_itr->second;
info.count += currentBBVInstCount;
}
currentBBVInstCount = 0;
// Reached end of interval if the sum of the current inst count
// (intervalCount) and the excessive inst count from the previous
// interval (intervalDrift) is greater than/equal to the interval size.
if (intervalCount + intervalDrift >= intervalSize) {
// summarize interval and display BBV info
std::vector<std::pair<uint64_t, uint64_t> > counts;
for (auto map_itr = bbMap.begin(); map_itr != bbMap.end();
++map_itr) {
BBInfo &info = map_itr->second;
if (info.count != 0) {
counts.push_back(std::make_pair(info.id, info.count));
info.count = 0;
}
}
std::sort(counts.begin(), counts.end());
// Print output BBV info
*simpointStream->stream() << "T";
for (auto cnt_itr = counts.begin(); cnt_itr != counts.end();
++cnt_itr) {
*simpointStream->stream() << ":" << cnt_itr->first
<< ":" << cnt_itr->second << " ";
}
*simpointStream->stream() << "\n";
intervalDrift = (intervalCount + intervalDrift) - intervalSize;
intervalCount = 0;
}
}
}
}
\ No newline at end of file
/*
* A C++ I/O streams interface to the zlib gz* functions
*
* by Ludwig Schwardt <schwardt@sun.ac.za>
* original version by Kevin Ruland <kevin@rodin.wustl.edu>
*
* This version is standard-compliant and compatible with gcc 3.x.
*/
#include "iostream3/zfstream.h"
#include <cstring> // for strcpy, strcat, strlen (mode strings)
#include <cstdio> // for BUFSIZ
// Internal buffer sizes (default and "unbuffered" versions)
#define BIGBUFSIZE BUFSIZ
#define SMALLBUFSIZE 1
/*****************************************************************************/
// Default constructor
gzfilebuf::gzfilebuf()
: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
{
// No buffers to start with
this->disable_buffer();
}
// Destructor
gzfilebuf::~gzfilebuf()
{
// Sync output buffer and close only if responsible for file
// (i.e. attached streams should be left open at this stage)
this->sync();
if (own_fd)
this->close();
// Make sure internal buffer is deallocated
this->disable_buffer();
}
// Set compression level and strategy
int
gzfilebuf::setcompression(int comp_level,
int comp_strategy)
{
return gzsetparams(file, comp_level, comp_strategy);
}
// Open gzipped file
gzfilebuf*
gzfilebuf::open(const char *name,
std::ios_base::openmode mode)
{
// Fail if file already open
if (this->is_open())
return NULL;
// Don't support simultaneous read/write access (yet)
if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
return NULL;
// Build mode string for gzopen and check it [27.8.1.3.2]
char char_mode[6] = "\0\0\0\0\0";
if (!this->open_mode(mode, char_mode))
return NULL;
// Attempt to open file
if ((file = gzopen(name, char_mode)) == NULL)
return NULL;
// On success, allocate internal buffer and set flags
this->enable_buffer();
io_mode = mode;
own_fd = true;
return this;
}
// Attach to gzipped file
gzfilebuf*
gzfilebuf::attach(int fd,
std::ios_base::openmode mode)
{
// Fail if file already open
if (this->is_open())
return NULL;
// Don't support simultaneous read/write access (yet)
if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
return NULL;
// Build mode string for gzdopen and check it [27.8.1.3.2]
char char_mode[6] = "\0\0\0\0\0";
if (!this->open_mode(mode, char_mode))
return NULL;
// Attempt to attach to file
if ((file = gzdopen(fd, char_mode)) == NULL)
return NULL;
// On success, allocate internal buffer and set flags
this->enable_buffer();
io_mode = mode;
own_fd = false;
return this;
}
// Close gzipped file
gzfilebuf*
gzfilebuf::close()
{
// Fail immediately if no file is open
if (!this->is_open())
return NULL;
// Assume success
gzfilebuf* retval = this;
// Attempt to sync and close gzipped file
if (this->sync() == -1)
retval = NULL;
if (gzclose(file) < 0)
retval = NULL;
// File is now gone anyway (postcondition [27.8.1.3.8])
file = NULL;
own_fd = false;
// Destroy internal buffer if it exists
this->disable_buffer();
return retval;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Convert int open mode to mode string
bool
gzfilebuf::open_mode(std::ios_base::openmode mode,
char* c_mode) const
{
bool testb = mode & std::ios_base::binary;
bool testi = mode & std::ios_base::in;
bool testo = mode & std::ios_base::out;
bool testt = mode & std::ios_base::trunc;
bool testa = mode & std::ios_base::app;
// Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
// Original zfstream hardcoded the compression level to maximum here...
// Double the time for less than 1% size improvement seems
// excessive though - keeping it at the default level
// To change back, just append "9" to the next three mode strings
if (!testi && testo && !testt && !testa)
strcpy(c_mode, "w");
if (!testi && testo && !testt && testa)
strcpy(c_mode, "a");
if (!testi && testo && testt && !testa)
strcpy(c_mode, "w");
if (testi && !testo && !testt && !testa)
strcpy(c_mode, "r");
// No read/write mode yet
// if (testi && testo && !testt && !testa)
// strcpy(c_mode, "r+");
// if (testi && testo && testt && !testa)
// strcpy(c_mode, "w+");
// Mode string should be empty for invalid combination of flags
if (strlen(c_mode) == 0)
return false;
if (testb)
strcat(c_mode, "b");
return true;
}
// Determine number of characters in internal get buffer
std::streamsize
gzfilebuf::showmanyc()
{
// Calls to underflow will fail if file not opened for reading
if (!this->is_open() || !(io_mode & std::ios_base::in))
return -1;
// Make sure get area is in use
if (this->gptr() && (this->gptr() < this->egptr()))
return std::streamsize(this->egptr() - this->gptr());
else
return 0;
}
// Fill get area from gzipped file
gzfilebuf::int_type
gzfilebuf::underflow()
{
// If something is left in the get area by chance, return it
// (this shouldn't normally happen, as underflow is only supposed
// to be called when gptr >= egptr, but it serves as error check)
if (this->gptr() && (this->gptr() < this->egptr()))
return traits_type::to_int_type(*(this->gptr()));
// If the file hasn't been opened for reading, produce error
if (!this->is_open() || !(io_mode & std::ios_base::in))
return traits_type::eof();
// Attempt to fill internal buffer from gzipped file
// (buffer must be guaranteed to exist...)
int bytes_read = gzread(file, buffer, buffer_size);
// Indicates error or EOF
if (bytes_read <= 0)
{
// Reset get area
this->setg(buffer, buffer, buffer);
return traits_type::eof();
}
// Make all bytes read from file available as get area
this->setg(buffer, buffer, buffer + bytes_read);
// Return next character in get area
return traits_type::to_int_type(*(this->gptr()));
}
// Write put area to gzipped file
gzfilebuf::int_type
gzfilebuf::overflow(int_type c)
{
// Determine whether put area is in use
if (this->pbase())
{
// Double-check pointer range
if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
return traits_type::eof();
// Add extra character to buffer if not EOF
if (!traits_type::eq_int_type(c, traits_type::eof()))
{
*(this->pptr()) = traits_type::to_char_type(c);
this->pbump(1);
}
// Number of characters to write to file
int bytes_to_write = this->pptr() - this->pbase();
// Overflow doesn't fail if nothing is to be written
if (bytes_to_write > 0)
{
// If the file hasn't been opened for writing, produce error
if (!this->is_open() || !(io_mode & std::ios_base::out))
return traits_type::eof();
// If gzipped file won't accept all bytes written to it, fail
if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
return traits_type::eof();
// Reset next pointer to point to pbase on success
this->pbump(-bytes_to_write);
}
}
// Write extra character to file if not EOF
else if (!traits_type::eq_int_type(c, traits_type::eof()))
{
// If the file hasn't been opened for writing, produce error
if (!this->is_open() || !(io_mode & std::ios_base::out))
return traits_type::eof();
// Impromptu char buffer (allows "unbuffered" output)
char_type last_char = traits_type::to_char_type(c);
// If gzipped file won't accept this character, fail
if (gzwrite(file, &last_char, 1) != 1)
return traits_type::eof();
}
// If you got here, you have succeeded (even if c was EOF)
// The return value should therefore be non-EOF
if (traits_type::eq_int_type(c, traits_type::eof()))
return traits_type::not_eof(c);
else
return c;
}
// Assign new buffer
std::streambuf*
gzfilebuf::setbuf(char_type* p,
std::streamsize n)
{
// First make sure stuff is sync'ed, for safety
if (this->sync() == -1)
return NULL;
// If buffering is turned off on purpose via setbuf(0,0), still allocate one...
// "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
// least a buffer of size 1 (very inefficient though, therefore make it bigger?)
// This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
if (!p || !n)
{
// Replace existing buffer (if any) with small internal buffer
this->disable_buffer();
buffer = NULL;
buffer_size = 0;
own_buffer = true;
this->enable_buffer();
}
else
{
// Replace existing buffer (if any) with external buffer
this->disable_buffer();
buffer = p;
buffer_size = n;
own_buffer = false;
this->enable_buffer();
}
return this;
}
// Write put area to gzipped file (i.e. ensures that put area is empty)
int
gzfilebuf::sync()
{
return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Allocate internal buffer
void
gzfilebuf::enable_buffer()
{
// If internal buffer required, allocate one
if (own_buffer && !buffer)
{
// Check for buffered vs. "unbuffered"
if (buffer_size > 0)
{
// Allocate internal buffer
buffer = new char_type[buffer_size];
// Get area starts empty and will be expanded by underflow as need arises
this->setg(buffer, buffer, buffer);
// Setup entire internal buffer as put area.
// The one-past-end pointer actually points to the last element of the buffer,
// so that overflow(c) can safely add the extra character c to the sequence.
// These pointers remain in place for the duration of the buffer
this->setp(buffer, buffer + buffer_size - 1);
}
else
{
// Even in "unbuffered" case, (small?) get buffer is still required
buffer_size = SMALLBUFSIZE;
buffer = new char_type[buffer_size];
this->setg(buffer, buffer, buffer);
// "Unbuffered" means no put buffer
this->setp(0, 0);
}
}
else
{
// If buffer already allocated, reset buffer pointers just to make sure no
// stale chars are lying around
this->setg(buffer, buffer, buffer);
this->setp(buffer, buffer + buffer_size - 1);
}
}
// Destroy internal buffer
void
gzfilebuf::disable_buffer()
{
// If internal buffer exists, deallocate it
if (own_buffer && buffer)
{
// Preserve unbuffered status by zeroing size
if (!this->pbase())
buffer_size = 0;
delete[] buffer;
buffer = NULL;
this->setg(0, 0, 0);
this->setp(0, 0);
}
else
{
// Reset buffer pointers to initial state if external buffer exists
this->setg(buffer, buffer, buffer);
if (buffer)
this->setp(buffer, buffer + buffer_size - 1);
else
this->setp(0, 0);
}
}
/*****************************************************************************/
// Default constructor initializes stream buffer
gzifstream::gzifstream()
: std::istream(NULL), sb()
{ this->init(&sb); }
// Initialize stream buffer and open file
gzifstream::gzifstream(const char* name,
std::ios_base::openmode mode)
: std::istream(NULL), sb()
{
this->init(&sb);
this->open(name, mode);
}
// Initialize stream buffer and attach to file
gzifstream::gzifstream(int fd,
std::ios_base::openmode mode)
: std::istream(NULL), sb()
{
this->init(&sb);
this->attach(fd, mode);
}
// Open file and go into fail() state if unsuccessful
void
gzifstream::open(const char* name,
std::ios_base::openmode mode)
{
if (!sb.open(name, mode | std::ios_base::in))
this->setstate(std::ios_base::failbit);
else
this->clear();
}
// Attach to file and go into fail() state if unsuccessful
void
gzifstream::attach(int fd,
std::ios_base::openmode mode)
{
if (!sb.attach(fd, mode | std::ios_base::in))
this->setstate(std::ios_base::failbit);
else
this->clear();
}
// Close file
void
gzifstream::close()
{
if (!sb.close())
this->setstate(std::ios_base::failbit);
}
/*****************************************************************************/
// Default constructor initializes stream buffer
gzofstream::gzofstream()
: std::ostream(NULL), sb()
{ this->init(&sb); }
// Initialize stream buffer and open file
gzofstream::gzofstream(const char* name,
std::ios_base::openmode mode)
: std::ostream(NULL), sb()
{
this->init(&sb);
this->open(name, mode);
}
// Initialize stream buffer and attach to file
gzofstream::gzofstream(int fd,
std::ios_base::openmode mode)
: std::ostream(NULL), sb()
{
this->init(&sb);
this->attach(fd, mode);
}
// Open file and go into fail() state if unsuccessful
void
gzofstream::open(const char* name,
std::ios_base::openmode mode)
{
if (!sb.open(name, mode | std::ios_base::out))
this->setstate(std::ios_base::failbit);
else
this->clear();
}
// Attach to file and go into fail() state if unsuccessful
void
gzofstream::attach(int fd,
std::ios_base::openmode mode)
{
if (!sb.attach(fd, mode | std::ios_base::out))
this->setstate(std::ios_base::failbit);
else
this->clear();
}
// Close file
void
gzofstream::close()
{
if (!sb.close())
this->setstate(std::ios_base::failbit);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册