Added simple high-level thread safety

All calls are blocking, so a single mutex is able
to garuntee synchronization across all relevant functions.
pull/5538/head
Christopher Haster 2017-10-30 19:24:58 -05:00
parent 26ade6236a
commit 5e4ef9f5a4
3 changed files with 91 additions and 8 deletions

View File

@ -123,9 +123,11 @@ LittleFileSystem::~LittleFileSystem() {
}
int LittleFileSystem::mount(BlockDevice *bd) {
_mutex.lock();
_bd = bd;
int err = _bd->init();
if (err) {
_mutex.unlock();
return err;
}
@ -154,24 +156,29 @@ int LittleFileSystem::mount(BlockDevice *bd) {
}
err = lfs_mount(&_lfs, &_config);
_mutex.unlock();
return lfs_toerror(err);
}
int LittleFileSystem::unmount() {
_mutex.lock();
if (_bd) {
int err = lfs_unmount(&_lfs);
if (err) {
_mutex.unlock();
return lfs_toerror(err);
}
err = _bd->deinit();
if (err) {
_mutex.unlock();
return err;
}
_bd = NULL;
}
_mutex.unlock();
return 0;
}
@ -224,6 +231,7 @@ int LittleFileSystem::format(BlockDevice *bd,
}
int LittleFileSystem::reformat(BlockDevice *bd) {
_mutex.lock();
if (_bd) {
if (!bd) {
bd = _bd;
@ -231,41 +239,59 @@ int LittleFileSystem::reformat(BlockDevice *bd) {
int err = unmount();
if (err) {
_mutex.unlock();
return err;
}
}
if (!bd) {
_mutex.unlock();
return -ENODEV;
}
int err = LittleFileSystem::format(bd,
_read_size, _prog_size, _block_size, _lookahead);
if (err) {
_mutex.unlock();
return err;
}
return mount(bd);
err = mount(bd);
if (err) {
_mutex.unlock();
return err;
}
_mutex.unlock();
return 0;
}
int LittleFileSystem::remove(const char *filename) {
_mutex.lock();
int err = lfs_remove(&_lfs, filename);
_mutex.unlock();
return lfs_toerror(err);
}
int LittleFileSystem::rename(const char *oldname, const char *newname) {
_mutex.lock();
int err = lfs_rename(&_lfs, oldname, newname);
_mutex.unlock();
return lfs_toerror(err);
}
int LittleFileSystem::mkdir(const char *name, mode_t mode) {
_mutex.lock();
int err = lfs_mkdir(&_lfs, name);
_mutex.unlock();
return lfs_toerror(err);
}
int LittleFileSystem::stat(const char *name, struct stat *st) {
struct lfs_info info;
_mutex.lock();
int err = lfs_stat(&_lfs, name, &info);
_mutex.unlock();
st->st_size = info.size;
st->st_mode = lfs_tomode(info.type);
return lfs_toerror(err);
@ -276,50 +302,66 @@ int LittleFileSystem::stat(const char *name, struct stat *st) {
int LittleFileSystem::file_open(fs_file_t *file, const char *path, int flags) {
lfs_file_t *f = new lfs_file_t;
*file = f;
_mutex.lock();
int err = lfs_file_open(&_lfs, f, path, lfs_fromflags(flags));
_mutex.unlock();
return lfs_toerror(err);
}
int LittleFileSystem::file_close(fs_file_t file) {
lfs_file_t *f = (lfs_file_t *)file;
_mutex.lock();
int err = lfs_file_close(&_lfs, f);
_mutex.unlock();
delete f;
return lfs_toerror(err);
}
ssize_t LittleFileSystem::file_read(fs_file_t file, void *buffer, size_t len) {
lfs_file_t *f = (lfs_file_t *)file;
int res = lfs_file_read(&_lfs, f, buffer, len);
_mutex.lock();
lfs_ssize_t res = lfs_file_read(&_lfs, f, buffer, len);
_mutex.unlock();
return lfs_toerror(res);
}
ssize_t LittleFileSystem::file_write(fs_file_t file, const void *buffer, size_t len) {
lfs_file_t *f = (lfs_file_t *)file;
int res = lfs_file_write(&_lfs, f, buffer, len);
_mutex.lock();
lfs_ssize_t res = lfs_file_write(&_lfs, f, buffer, len);
_mutex.unlock();
return lfs_toerror(res);
}
int LittleFileSystem::file_sync(fs_file_t file) {
lfs_file_t *f = (lfs_file_t *)file;
_mutex.lock();
int err = lfs_file_sync(&_lfs, f);
_mutex.unlock();
return lfs_toerror(err);
}
off_t LittleFileSystem::file_seek(fs_file_t file, off_t offset, int whence) {
lfs_file_t *f = (lfs_file_t *)file;
_mutex.lock();
off_t res = lfs_file_seek(&_lfs, f, offset, lfs_fromwhence(whence));
_mutex.unlock();
return lfs_toerror(res);
}
off_t LittleFileSystem::file_tell(fs_file_t file) {
lfs_file_t *f = (lfs_file_t *)file;
_mutex.lock();
off_t res = lfs_file_tell(&_lfs, f);
_mutex.unlock();
return lfs_toerror(res);
}
off_t LittleFileSystem::file_size(fs_file_t file) {
lfs_file_t *f = (lfs_file_t *)file;
_mutex.lock();
off_t res = lfs_file_size(&_lfs, f);
_mutex.unlock();
return lfs_toerror(res);
}
@ -328,13 +370,17 @@ off_t LittleFileSystem::file_size(fs_file_t file) {
int LittleFileSystem::dir_open(fs_dir_t *dir, const char *path) {
lfs_dir_t *d = new lfs_dir_t;
*dir = d;
_mutex.lock();
int err = lfs_dir_open(&_lfs, d, path);
_mutex.unlock();
return lfs_toerror(err);
}
int LittleFileSystem::dir_close(fs_dir_t dir) {
lfs_dir_t *d = (lfs_dir_t *)dir;
_mutex.lock();
int err = lfs_dir_close(&_lfs, d);
_mutex.unlock();
delete d;
return lfs_toerror(err);
}
@ -342,7 +388,9 @@ int LittleFileSystem::dir_close(fs_dir_t dir) {
ssize_t LittleFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) {
lfs_dir_t *d = (lfs_dir_t *)dir;
struct lfs_info info;
_mutex.lock();
int res = lfs_dir_read(&_lfs, d, &info);
_mutex.unlock();
if (res == 1) {
ent->d_type = lfs_totype(info.type);
strcpy(ent->d_name, info.name);
@ -352,16 +400,23 @@ ssize_t LittleFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) {
void LittleFileSystem::dir_seek(fs_dir_t dir, off_t offset) {
lfs_dir_t *d = (lfs_dir_t *)dir;
_mutex.lock();
lfs_dir_seek(&_lfs, d, offset);
_mutex.unlock();
}
off_t LittleFileSystem::dir_tell(fs_dir_t dir) {
lfs_dir_t *d = (lfs_dir_t *)dir;
return lfs_dir_tell(&_lfs, d);
_mutex.lock();
lfs_soff_t res = lfs_dir_tell(&_lfs, d);
_mutex.unlock();
return lfs_toerror(res);
}
void LittleFileSystem::dir_rewind(fs_dir_t dir) {
lfs_dir_t *d = (lfs_dir_t *)dir;
_mutex.lock();
lfs_dir_rewind(&_lfs, d);
_mutex.unlock();
}

View File

@ -24,6 +24,7 @@
#include "FileSystem.h"
#include "BlockDevice.h"
#include "PlatformMutex.h"
extern "C" {
#include "lfs.h"
}
@ -273,6 +274,9 @@ private:
const lfs_size_t _prog_size;
const lfs_size_t _block_size;
const lfs_size_t _lookahead;
// thread-safe locking
PlatformMutex _mutex;
};

View File

@ -37,23 +37,47 @@ static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
}
static inline uint32_t lfs_ctz(uint32_t a) {
#ifdef __ICCARM__
#if defined(__GNUC__) || defined(__CC_ARM)
return __builtin_ctz(a);
#elif defined(__ICCARM__)
return __CLZ(__RBIT(a));
#else
return __builtin_ctz(a);
uint32_t r = 32;
a &= -a;
if (a) r -= 1;
if (a & 0x0000ffff) r -= 16;
if (a & 0x00ff00ff) r -= 8;
if (a & 0x0f0f0f0f) r -= 4;
if (a & 0x33333333) r -= 2;
if (a & 0x55555555) r -= 1;
return r;
#endif
}
static inline uint32_t lfs_npw2(uint32_t a) {
#ifdef __ICCARM__
#if defined(__GNUC__) || defined(__CC_ARM)
return 32 - __builtin_clz(a-1);
#elif defined(__ICCARM__)
return 32 - __CLZ(a-1);
#else
return 32 - __builtin_clz(a-1);
uint32_t r = 0;
uint32_t s;
s = (a > 0xffff) << 4; a >>= s; r |= s;
s = (a > 0xff ) << 3; a >>= s; r |= s;
s = (a > 0xf ) << 2; a >>= s; r |= s;
s = (a > 0x3 ) << 1; a >>= s; r |= s;
return r | (a >> 1);
#endif
}
static inline uint32_t lfs_popc(uint32_t a) {
#if defined(__GNUC__) || defined(__CC_ARM)
return __builtin_popcount(a);
#else
a = a - ((a >> 1) & 0x55555555);
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
#endif
}
static inline int lfs_scmp(uint32_t a, uint32_t b) {