diff --git a/include/llvm/System/MappedFile.h b/include/llvm/System/MappedFile.h new file mode 100644 index 00000000000..3aa1840319b --- /dev/null +++ b/include/llvm/System/MappedFile.h @@ -0,0 +1,160 @@ +//===- llvm/System/MappedFile.h - MappedFile OS Concept ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the llvm::sys::MappedFile class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYSTEM_MAPPEDFILE_H +#define LLVM_SYSTEM_MAPPEDFILE_H + +#include "llvm/System/Path.h" + +namespace llvm { +namespace sys { + + /// Forward declare a class used for holding platform specific information + /// that needs to be + class MappedFileInfo; + + /// This class provides an abstraction for a memory mapped file in the + /// operating system's filesystem. It provides platform independent operations + /// for mapping a file into memory for both read and write access. This class + /// does not provide facilities for finding the file or operating on paths to + /// files. The sys::Path class is used for that. + /// @since 1.4 + /// @brief An abstraction for memory mapped files. + class MappedFile { + /// @name Types + /// @{ + public: + enum MappingOptions { + READ_ACCESS = 0x0001, ///< Map the file for reading + WRITE_ACCESS = 0x0002, ///< Map the file for write access + EXEC_ACCESS = 0x0004, ///< Map the file for execution access + SHARED_MAPPING = 0x0008, ///< Map the file shared with other processes + }; + /// @} + /// @name Constructors + /// @{ + public: + /// Construct a MappedFile to the \p path in the operating system's file + /// system with the mapping \p options provided. + /// @throws std::string if an error occurs + MappedFile(const Path& path, int options = READ_ACCESS) + : path_(path), options_(options), base_(0), info_(0) { + initialize(); + } + + /// Destruct a MappedFile and release all memory associated with it. + /// @throws std::string if an error occurs + ~MappedFile() { + terminate(); + path_.clear(); + } + + /// @} + /// @name Accessors + /// @{ + public: + /// This function determines if the file is currently mapped or not. + /// @returns true iff the file is mapped into memory, false otherwise + /// @brief Determine if a MappedFile is currently mapped + /// @throws nothing + bool isMapped() const { return base_ != 0; } + + /// This function returns a void* pointer to the base address of the file + /// mapping. This is the memory address of the first byte in the file. + /// Note that although a non-const pointer is returned, the memory might + /// not actually be writable, depending on the MappingOptions used when + /// the MappedFile was opened. + /// @returns The base pointer to the memory mapped file. + /// @brief Obtain the base pointer to the memory mapped file. + /// @throws nothing + void* base() const { return base_; } + + /// This function returns a char* pointer to the base address of the file + /// mapping. This is the memory address of the first byte in the file. + /// Note that although a non-const pointer is returned, the memory might + /// not actually be writable, depending on the MappingOptions used when + /// the MappedFile was opened. + /// @returns The base pointer to the memory mapped file as a char pointer. + /// @brief Obtain the base pointer to the memory mapped file. + /// @throws nothing + char* charBase() const { return reinterpret_cast(base_); } + + /// This function returns a reference to the sys::Path object kept by the + /// MappedFile object. This contains the path to the file that is or + /// will be mapped. + /// @returns sys::Path containing the path name. + /// @brief Returns the mapped file's path as a sys::Path + /// @throws nothing + const sys::Path& path() const { return path_; } + + /// This function returns the number of bytes in the file. + /// @throws std::string if an error occurs + size_t size(); + + /// @} + /// @name Mutators + /// @{ + public: + /// The mapped file is removed from memory. If the file was mapped for + /// write access, the memory contents will be automatically synchronized + /// with the file's disk contents. + /// @brief Remove the file mapping from memory. + void unmap(); + + /// The mapped file is put into memory. + /// @returns The base memory address of the mapped file. + /// @brief Map the file into memory. + void* map(); + + /// This method causes the size of the file, and consequently the size + /// of the mapping to be set. This is logically the same as unmap(), + /// adjust size of the file, map(). Consequently, when calling this + /// function, the caller should not rely on previous results of the + /// map(), base(), or baseChar() members as they may point to invalid + /// areas of memory after this call. + /// @throws std::string if an error occurs + /// @brief Set a full path from a std::string + void size(size_t new_size); + + /// @} + /// @name Implementation + /// @{ + private: + void initialize(); ///< Initialize platform-specific portion + void terminate(); ///< Terminate platform-specific portion + + /// @} + /// @name Data + /// @{ + private: + sys::Path path_; ///< Path to the file. + int options_; ///< Options used to create the mapping + void* base_; ///< Pointer to the base memory address + MappedFileInfo* info_; ///< Platform specific info for the mapping + + /// @} + /// @name Deprecated + /// @{ + private: + ///< Disallow assignment + MappedFile& operator = ( const MappedFile & that ); + ///< Disallow copying + MappedFile(const MappedFile& that); + /// @} + }; +} +} + +// vim: sw=2 + +#endif diff --git a/lib/System/AIX/MappedFile.cpp b/lib/System/AIX/MappedFile.cpp new file mode 100644 index 00000000000..946ebad20d7 --- /dev/null +++ b/lib/System/AIX/MappedFile.cpp @@ -0,0 +1,17 @@ +//===- AIX/MappedFile.cpp - AIX MappedFile Implementation --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the AIX specific implementation of the MappedFile concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/Cygwin/MappedFile.cpp b/lib/System/Cygwin/MappedFile.cpp new file mode 100644 index 00000000000..09a05757fbe --- /dev/null +++ b/lib/System/Cygwin/MappedFile.cpp @@ -0,0 +1,18 @@ +//===- Cygwin/MappedFile.cpp - Cygwin MappedFile Implementation -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Cygwin specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/Darwin/MappedFile.cpp b/lib/System/Darwin/MappedFile.cpp new file mode 100644 index 00000000000..c3f26566d6d --- /dev/null +++ b/lib/System/Darwin/MappedFile.cpp @@ -0,0 +1,18 @@ +//===- Darwin/MappedFile.cpp - Darwin MappedFile Implementation -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Darwin specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/FreeBSD/MappedFile.cpp b/lib/System/FreeBSD/MappedFile.cpp new file mode 100644 index 00000000000..a06691966b8 --- /dev/null +++ b/lib/System/FreeBSD/MappedFile.cpp @@ -0,0 +1,18 @@ +//===- FreeBSD/MappedFile.cpp - FreeBSD MappedFile Impl. --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the FreeBSD specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/Interix/MappedFile.cpp b/lib/System/Interix/MappedFile.cpp new file mode 100644 index 00000000000..1600ea4bcae --- /dev/null +++ b/lib/System/Interix/MappedFile.cpp @@ -0,0 +1,18 @@ +//===- Interix/MappedFile.cpp - Interix MappedFile Impl. --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Interix specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/Linux/MappedFile.cpp b/lib/System/Linux/MappedFile.cpp new file mode 100644 index 00000000000..d8fb35eccb0 --- /dev/null +++ b/lib/System/Linux/MappedFile.cpp @@ -0,0 +1,18 @@ +//===- Linux/MappedFile.cpp - Linux MappedFile Implementation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Linux specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/MappedFile.cpp b/lib/System/MappedFile.cpp new file mode 100644 index 00000000000..55e17012f39 --- /dev/null +++ b/lib/System/MappedFile.cpp @@ -0,0 +1,29 @@ +//===- MappedFile.cpp - MappedFile Support ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the mapped file concept. +// +//===----------------------------------------------------------------------===// + +#include "llvm/System/MappedFile.h" + +namespace llvm { +using namespace sys; + +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only TRULY operating system +//=== independent code. +//===----------------------------------------------------------------------===// + +} + +// Include the platform-specific parts of this class. +#include "platform/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/SunOS/MappedFile.cpp b/lib/System/SunOS/MappedFile.cpp new file mode 100644 index 00000000000..ebde62afc17 --- /dev/null +++ b/lib/System/SunOS/MappedFile.cpp @@ -0,0 +1,18 @@ +//===- SunOS/MappedFile.cpp - SunOS MappedFile Implementation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the SunOS specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +// Include the generic unix implementation +#include "../Unix/MappedFile.cpp" + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/Unix/MappedFile.cpp b/lib/System/Unix/MappedFile.cpp new file mode 100644 index 00000000000..d853acec4f4 --- /dev/null +++ b/lib/System/Unix/MappedFile.cpp @@ -0,0 +1,138 @@ +//===- Unix/MappedFile.cpp - Unix MappedFile Implementation -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the generic Unix implementation of the MappedFile concept. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only generic UNIX code that +//=== is guaranteed to work on *all* UNIX variants. +//===----------------------------------------------------------------------===// + +#include "llvm/System/Process.h" +#include "Unix.h" +#include +#include + +namespace llvm { +using namespace sys; + +struct sys::MappedFileInfo { + int fd_; + struct stat sbuf_; +}; + +void MappedFile::initialize() { + if (path_.exists()) { + info_ = new MappedFileInfo; + int mode = 0; + if (options_&READ_ACCESS) + if (options_&WRITE_ACCESS) + mode = O_RDWR; + else + mode = O_RDONLY; + else if (options_&WRITE_ACCESS) + mode = O_WRONLY; + info_->fd_ = ::open(path_.c_str(),mode); + if (info_->fd_ < 0) { + delete info_; + info_ = 0; + ThrowErrno(std::string("Can't open file: ") + path_.get()); + } + struct stat sbuf; + if(::fstat(info_->fd_, &info_->sbuf_) < 0) { + ::close(info_->fd_); + delete info_; + info_ = 0; + ThrowErrno(std::string("Can't stat file: ") + path_.get()); + } + } +} + +void MappedFile::terminate() { + assert(info_ && "MappedFile not initialized"); + if (info_->fd_ >= 0) + ::close(info_->fd_); + delete info_; + info_ = 0; +} + +void MappedFile::unmap() { + assert(info_ && "MappedFile not initialized"); + if (isMapped()) { + if (options_ & WRITE_ACCESS) + ::msync(base_, info_->sbuf_.st_size, MS_SYNC); + ::munmap(base_, info_->sbuf_.st_size); + } +} + +void* MappedFile::map() { + if (!isMapped()) { + int prot = PROT_NONE; + int flags = MAP_FILE; + if (options_ == 0) { + prot = PROT_READ; + flags = MAP_PRIVATE; + } else { + if (options_ & READ_ACCESS) + prot |= PROT_READ; + if (options_ & WRITE_ACCESS) + prot |= PROT_WRITE; + if (options_ & EXEC_ACCESS) + prot |= PROT_EXEC; + if (options_ & SHARED_MAPPING) + flags |= MAP_SHARED; + else + flags |= MAP_PRIVATE; + } + size_t map_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) * + Process::GetPageSize(); + + base_ = ::mmap(0, map_size, prot, flags, info_->fd_, 0); + if (base_ == MAP_FAILED) + ThrowErrno(std::string("Can't map file:") + path_.get()); + } + return base_; +} + +size_t MappedFile::size() { + assert(info_ && "MappedFile not initialized"); + return info_->sbuf_.st_size; +} + +void MappedFile::size(size_t new_size) { + assert(info_ && "MappedFile not initialized"); + + // Take the mapping out of memory + this->unmap(); + + // Adjust the current size to a page boundary + size_t cur_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) * + Process::GetPageSize(); + + // Adjust the new_size to a page boundary + new_size = ((new_size / Process::GetPageSize())+1) * + Process::GetPageSize(); + + // If the file needs to be extended + if (new_size > cur_size) { + // Ensure we can allocate at least the idodes necessary to handle the + // file size requested. + ::lseek(info_->fd_, new_size, SEEK_SET); + ::write(info_->fd_, "\0", 1); + } + + // Seek to current end of file. + this->map(); +} + +} + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab diff --git a/lib/System/Win32/MappedFile.cpp b/lib/System/Win32/MappedFile.cpp new file mode 100644 index 00000000000..d106eb16ad2 --- /dev/null +++ b/lib/System/Win32/MappedFile.cpp @@ -0,0 +1,38 @@ +//===- Win32/MappedFile.cpp - Win32 MappedFile Implementation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the Win32 specific implementation of the MappedFile +// concept. +// +//===----------------------------------------------------------------------===// + +#include "Win32.h" + +void MappedFile::initialize() { +} + +void MappedFile::terminate() { +} + +void MappedFile::unmap() { +} + +void* MappedFile::map() { + static char junk[4096]; + return junk; +} + +size_t MappedFile::size() { + return 4096; +} + +void MappedFile::size(size_t new_size) { +} + +// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab