don't lock files

that's simpler and enough for now
This commit is contained in:
2024-03-22 14:51:10 +01:00
parent 29ed4b786a
commit d9de8e45a0
7 changed files with 33 additions and 82 deletions

View File

@@ -13,6 +13,7 @@
FDT::FD FDT::open(const Path &p, FileOpts opts) {
if (auto n = VFSGlobals::root.traverse(p)) {
LockGuard l(_mtx);
_files.add(_cur_fd++, UniquePtr<File>(new File(n, opts)));
return _cur_fd - 1;
}
@@ -24,13 +25,15 @@ FDT::FD FDT::open(const Path &p, FileOpts opts) {
}
void FDT::close(FDT::FD fd) {
LockGuard l(_mtx);
if (auto f = _files.find(fd))
if (!f->end)
if (f->key == fd) {
_files.erase(fd);
}
}
File *FDT::get(FDT::FD fd) {
File *FDT::get(FDT::FD fd) const {
LockGuard l(_mtx);
if (auto f = _files.find(fd))
if (!f->end)
if (f->key == fd)

View File

@@ -17,14 +17,14 @@ public:
using FD = int64_t;
FD open(const Path &p, FileOpts opts);
void close(FD fd);
File *get(FD fd);
File *get(FD fd) const;
static FDT *current();
private:
SkipList<FD, UniquePtr<File>> _files;
int64_t _cur_fd = 10;
Mutex _mtx;
mutable Mutex _mtx;
};
class FDHandle {

View File

@@ -9,16 +9,8 @@
File::File(Node *node, FileOpts opts) : _n(node), _opts(opts) {
if (opts & FileOpts::O_WRONLY)
assert(opts & FileOpts::O_RDONLY);
if (opts & FileOpts::O_WRONLY)
while (!_n->lock_rw()) { yield_self(); }
else
while (!_n->lock_r()) { yield_self(); }
}
File::~File() {
if (_opts & FileOpts::O_WRONLY)
_n->unlock_rw();
else
_n->unlock_r();
}
Node *File::node() {
return _n;
@@ -27,7 +19,7 @@ NodeDir *File::dir() {
if (_n && _n->type() == Node::DIR) return static_cast<NodeDir *>(_n);
return nullptr;
}
NodeFile *File::file() {
NodeFile *File::file() const {
if (_n && _n->type() == Node::FILE) return static_cast<NodeFile *>(_n);
return nullptr;
}

View File

@@ -21,7 +21,7 @@ public:
Node *node();
NodeDir *dir();
NodeFile *file();
NodeFile *file() const;
uint64_t seek(uint64_t pos);
uint64_t read(char *buf, uint64_t size);
@@ -29,7 +29,7 @@ public:
uint64_t size();
private:
Node *_n;
Node *const _n;
uint64_t _pos = 0;
FileOpts _opts;
};

View File

@@ -5,10 +5,8 @@
#include "MemFs.hpp"
#include "LockGuard.hpp"
//FIXME: asserts on read also make sense
Vector<Node *> MemFs::MemFsNodeDir::children() {
// assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
// assert(_lock.owner() == cur_task());
LockGuard l(_lock);
Vector<Node *> out;
for (auto c: _children) {
@@ -18,21 +16,20 @@ Vector<Node *> MemFs::MemFsNodeDir::children() {
}
NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) {
assert(_rw_lock.owner() == cur_task());
LockGuard l(_lock);
auto newnode = new MemFsNodeDir();
newnode->_name = name;
_children.add(name, newnode);
return newnode;
}
NodeFile *MemFs::MemFsNodeDir::mkfile(const String &name) {
assert(_rw_lock.owner() == cur_task());
LockGuard l(_lock);
auto newfile = new MemFsNodeFile(name);
_children.add(name, newfile);
return newfile;
}
bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
// assert(_lock.owner() == cur_task());
LockGuard l(_lock);
if (start >= _bytes.size()) return false;
if (start + num > _bytes.size()) return false;
for (size_t i = 0; i < num; i++) {
@@ -41,8 +38,7 @@ bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
return false;
}
bool MemFs::MemFsNodeFile::write(const char *buf, size_t start, size_t num) {
assert(_rw_lock.owner() == cur_task());
// fixme
LockGuard l(_lock);
while (_bytes.size() <= start + num) _bytes.emplace_back(0);
for (size_t i = 0; i < num; i++) {
_bytes[start + i] = buf[i];
@@ -50,5 +46,6 @@ bool MemFs::MemFsNodeFile::write(const char *buf, size_t start, size_t num) {
return true;
}
size_t MemFs::MemFsNodeFile::size() {
LockGuard l(_lock);
return _bytes.size();
}

View File

@@ -9,72 +9,36 @@
Node::~Node() = default;
Node *Node::traverse(const Path &path) {
while (!lock_r()) { yield_self(); }
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
if (nodeDir._mount) return nodeDir._mount->root()->traverse(path);
Filesystem *mnt;
{
LockGuard l(_lock);
mnt = nodeDir._mount;
}
if (mnt) return mnt->root()->traverse(path);
if (path.empty()) {
unlock_r();
return this;
}
if (_type == DIR) {
if (type() == DIR) {
// Horribly inefficient
auto children = nodeDir.children();
for (size_t i = 0; i < children.size(); i++) {
if (children[i]->name() == path[0]) {
unlock_r();
return children[i]->traverse(path.subvector(1, path.size()));
}
}
unlock_r();
return nullptr;
}
unlock_r();
return nullptr;
}
void NodeDir::set_mounted(Filesystem *mount) {
LockGuard l(_lock);
assert(_type == DIR);
assert(_mount == nullptr);
_mount = mount;
}
bool Node::lock_r() {
LockGuard l(_lock);
if (_rw_lock.test() && _rw_lock.owner() != cur_task()) return false;
_r_lock_count++;
return true;
}
bool Node::lock_rw() {
LockGuard l(_lock);
if (_rw_lock.test() && _rw_lock.owner() != cur_task()) return false;
if (_r_lock_count != 0 && !(_rw_lock.test() && _rw_lock.owner() == cur_task())) return false;
if (_rw_lock_count == 0) {
assert(!_rw_lock.test());
_rw_lock.lock();
}
_rw_lock_count++;
return true;
}
void Node::unlock_r() {
LockGuard l(_lock);
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
assert(_r_lock_count > 0);
_r_lock_count--;
}
void Node::unlock_rw() {
LockGuard l(_lock);
assert(_rw_lock.test() && _rw_lock.owner() == cur_task());
assert(_rw_lock_count > 0);
_rw_lock_count--;
if (_rw_lock_count == 0)
_rw_lock.unlock();
}

View File

@@ -6,6 +6,7 @@
#define OS2_NODE_HPP
#include "List.hpp"
#include "LockGuard.hpp"
#include "String.hpp"
#include "Path.hpp"
@@ -23,25 +24,19 @@ public:
virtual ~Node() = 0;
Type type() const { return _type; }
const String &name() const { return _name; }
const String &name() const {
LockGuard l(_lock);
return _name;
}
virtual Node *traverse(const Path &path);
bool lock_r();
bool lock_rw();
void unlock_r();
void unlock_rw();
protected:
Node(Type type) : _type(type) {}
Type _type = Type::INVALID;
const Type _type = Type::INVALID;
// This is uuugly
Mutex _lock;
uint64_t _r_lock_count = 0;
uint64_t _rw_lock_count = 0;
List<Task *> r_lockers;
Mutex _rw_lock;
mutable Mutex _lock;
String _name;
Filesystem *_mount = nullptr;