/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuProcessSectionFileMapView.Unix.cpp Date: 2022-08-09 Author: Reece ***/ #include #include "AuProcessSectionFileMapView.Unix.hpp" #include "AuProcessSectionViewReserved.Unix.hpp" #include "AuProcessSectionView.Unix.hpp" #include namespace Aurora::Process { ProcessSectionFileMapView::ProcessSectionFileMapView(AuUInt uAddress, AuUInt uLength, bool bShouldUnmap, int optFd) : uAddress_(uAddress), uLength_(uLength), bShouldUnmap_(bShouldUnmap), optFd_(optFd) { } ProcessSectionFileMapView::~ProcessSectionFileMapView() { Unmap(); } void ProcessSectionFileMapView::Unmap() { AU_LOCK_GUARD(this->mutex_); if (AuAtomicLoad(&this->uInUse_)) { SysPushErrorResourceLocked("Cannot unmap memory while it's in use"); return; } if (AuExchange(this->bIsDead_, true)) { return; } if (this->uAddress_) { if (this->pSharedSectionHint) { AuStaticCast(this->pSharedSectionHint)->Release(this->uAddress_); } if (this->bShouldUnmap_) { ::munmap(this->GetBasePointer(), this->uLength_); } else { if (!::mmap(this->GetBasePointer(), this->uLength_, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0)) { ::mmap(this->GetBasePointer(), this->uLength_, PROT_READ /*coping*/, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0); } } this->uAddress_ = 0; } // TODO: posix explicitly states this isnt necessary int fd {-1}; if ((fd = AuExchange(this->optFd_, -1)) != -1) { ::close(fd); } } bool ProcessSectionFileMapView::Flush(AuUInt uOffset, AuUInt uLength) { return ::msync(this->GetPointer(uOffset), uLength, MS_SYNC) == 0; } AuMemoryViewWrite ProcessSectionFileMapView::ToWriteView() { return AuMemoryViewWrite((char *)this->uAddress_, this->uLength_, &this->uInUse_); } AuMemoryViewRead ProcessSectionFileMapView::ToReadView() { return AuMemoryViewRead((char *)this->uAddress_, this->uLength_, &this->uInUse_); } AuUInt ProcessSectionFileMapView::GetBaseAddress() { return this->uAddress_; } AuUInt ProcessSectionFileMapView::GetAddress(AuUInt uOffset) { return this->uAddress_ && this->uLength_ > uOffset ? this->uAddress_ + uOffset : 0; } AuUInt8 *ProcessSectionFileMapView::GetBasePointer() { return AuReinterpretCast(this->uAddress_); } AuUInt8 *ProcessSectionFileMapView::GetPointer(AuUInt uOffset) { return this->uAddress_ && this->uLength_ > uOffset ? AuReinterpretCast(this->uAddress_) + uOffset : 0; } bool ProcessSectionFileMapView::LockSwap() { if (!this->uAddress_) { return false; } return AuMemory::SwapLock::Lock({ { this->uAddress_, this->uLength_ } }); } bool ProcessSectionFileMapView::UnlockSwap() { if (!this->uAddress_) { return false; } return AuMemory::SwapLock::Unlock({ { this->uAddress_, this->uLength_ } }); } }