diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2005-01-09 23:29:00 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2005-01-09 23:29:00 +0000 |
commit | c892a0db9faab4c36f2276f4675661875b2c84b9 (patch) | |
tree | a6c30a9befae0918f0a62d7a354cd339a711c91e /llvm/lib/System/Unix/MappedFile.inc | |
parent | fde3a212e2f7f983e676d374e9a7bd445071e5d8 (diff) | |
download | bcm5719-llvm-c892a0db9faab4c36f2276f4675661875b2c84b9.tar.gz bcm5719-llvm-c892a0db9faab4c36f2276f4675661875b2c84b9.zip |
Rename Unix/*.cpp and Win32/*.cpp to have a *.inc suffix so that the silly
gdb debugger doesn't get confused on which file it is reading (the one in
lib/System or the one in lib/System/{Win32,Unix})
llvm-svn: 19426
Diffstat (limited to 'llvm/lib/System/Unix/MappedFile.inc')
-rw-r--r-- | llvm/lib/System/Unix/MappedFile.inc | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/llvm/lib/System/Unix/MappedFile.inc b/llvm/lib/System/Unix/MappedFile.inc new file mode 100644 index 00000000000..07683c14392 --- /dev/null +++ b/llvm/lib/System/Unix/MappedFile.inc @@ -0,0 +1,154 @@ +//===- 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 "Unix.h" +#include "llvm/System/Process.h" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +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_.toString()); + } + 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_.toString()); + } + } else { + throw std::string("Can't open file: ") + path_.toString(); + } +} + +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() { + assert(info_ && "MappedFile not initialized"); + if (!isMapped()) { + int prot = PROT_NONE; + int flags = 0; +#ifdef MAP_FILE + flags |= MAP_FILE; +#endif + 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_.toString()); + } + return base_; +} + +size_t MappedFile::size() const { + 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 |