Skip to content

Commit 5e4ef9f

Browse files
committed
Added simple high-level thread safety
All calls are blocking, so a single mutex is able to garuntee synchronization across all relevant functions.
1 parent 26ade62 commit 5e4ef9f

File tree

3 files changed

+91
-8
lines changed

3 files changed

+91
-8
lines changed

LittleFileSystem.cpp

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,11 @@ LittleFileSystem::~LittleFileSystem() {
123123
}
124124

125125
int LittleFileSystem::mount(BlockDevice *bd) {
126+
_mutex.lock();
126127
_bd = bd;
127128
int err = _bd->init();
128129
if (err) {
130+
_mutex.unlock();
129131
return err;
130132
}
131133

@@ -154,24 +156,29 @@ int LittleFileSystem::mount(BlockDevice *bd) {
154156
}
155157

156158
err = lfs_mount(&_lfs, &_config);
159+
_mutex.unlock();
157160
return lfs_toerror(err);
158161
}
159162

160163
int LittleFileSystem::unmount() {
164+
_mutex.lock();
161165
if (_bd) {
162166
int err = lfs_unmount(&_lfs);
163167
if (err) {
168+
_mutex.unlock();
164169
return lfs_toerror(err);
165170
}
166171

167172
err = _bd->deinit();
168173
if (err) {
174+
_mutex.unlock();
169175
return err;
170176
}
171177

172178
_bd = NULL;
173179
}
174180

181+
_mutex.unlock();
175182
return 0;
176183
}
177184

@@ -224,48 +231,67 @@ int LittleFileSystem::format(BlockDevice *bd,
224231
}
225232

226233
int LittleFileSystem::reformat(BlockDevice *bd) {
234+
_mutex.lock();
227235
if (_bd) {
228236
if (!bd) {
229237
bd = _bd;
230238
}
231239

232240
int err = unmount();
233241
if (err) {
242+
_mutex.unlock();
234243
return err;
235244
}
236245
}
237246

238247
if (!bd) {
248+
_mutex.unlock();
239249
return -ENODEV;
240250
}
241251

242252
int err = LittleFileSystem::format(bd,
243253
_read_size, _prog_size, _block_size, _lookahead);
244254
if (err) {
255+
_mutex.unlock();
245256
return err;
246257
}
247258

248-
return mount(bd);
259+
err = mount(bd);
260+
if (err) {
261+
_mutex.unlock();
262+
return err;
263+
}
264+
265+
_mutex.unlock();
266+
return 0;
249267
}
250268

251269
int LittleFileSystem::remove(const char *filename) {
270+
_mutex.lock();
252271
int err = lfs_remove(&_lfs, filename);
272+
_mutex.unlock();
253273
return lfs_toerror(err);
254274
}
255275

256276
int LittleFileSystem::rename(const char *oldname, const char *newname) {
277+
_mutex.lock();
257278
int err = lfs_rename(&_lfs, oldname, newname);
279+
_mutex.unlock();
258280
return lfs_toerror(err);
259281
}
260282

261283
int LittleFileSystem::mkdir(const char *name, mode_t mode) {
284+
_mutex.lock();
262285
int err = lfs_mkdir(&_lfs, name);
286+
_mutex.unlock();
263287
return lfs_toerror(err);
264288
}
265289

266290
int LittleFileSystem::stat(const char *name, struct stat *st) {
267291
struct lfs_info info;
292+
_mutex.lock();
268293
int err = lfs_stat(&_lfs, name, &info);
294+
_mutex.unlock();
269295
st->st_size = info.size;
270296
st->st_mode = lfs_tomode(info.type);
271297
return lfs_toerror(err);
@@ -276,50 +302,66 @@ int LittleFileSystem::stat(const char *name, struct stat *st) {
276302
int LittleFileSystem::file_open(fs_file_t *file, const char *path, int flags) {
277303
lfs_file_t *f = new lfs_file_t;
278304
*file = f;
305+
_mutex.lock();
279306
int err = lfs_file_open(&_lfs, f, path, lfs_fromflags(flags));
307+
_mutex.unlock();
280308
return lfs_toerror(err);
281309
}
282310

283311
int LittleFileSystem::file_close(fs_file_t file) {
284312
lfs_file_t *f = (lfs_file_t *)file;
313+
_mutex.lock();
285314
int err = lfs_file_close(&_lfs, f);
315+
_mutex.unlock();
286316
delete f;
287317
return lfs_toerror(err);
288318
}
289319

290320
ssize_t LittleFileSystem::file_read(fs_file_t file, void *buffer, size_t len) {
291321
lfs_file_t *f = (lfs_file_t *)file;
292-
int res = lfs_file_read(&_lfs, f, buffer, len);
322+
_mutex.lock();
323+
lfs_ssize_t res = lfs_file_read(&_lfs, f, buffer, len);
324+
_mutex.unlock();
293325
return lfs_toerror(res);
294326
}
295327

296328
ssize_t LittleFileSystem::file_write(fs_file_t file, const void *buffer, size_t len) {
297329
lfs_file_t *f = (lfs_file_t *)file;
298-
int res = lfs_file_write(&_lfs, f, buffer, len);
330+
_mutex.lock();
331+
lfs_ssize_t res = lfs_file_write(&_lfs, f, buffer, len);
332+
_mutex.unlock();
299333
return lfs_toerror(res);
300334
}
301335

302336
int LittleFileSystem::file_sync(fs_file_t file) {
303337
lfs_file_t *f = (lfs_file_t *)file;
338+
_mutex.lock();
304339
int err = lfs_file_sync(&_lfs, f);
340+
_mutex.unlock();
305341
return lfs_toerror(err);
306342
}
307343

308344
off_t LittleFileSystem::file_seek(fs_file_t file, off_t offset, int whence) {
309345
lfs_file_t *f = (lfs_file_t *)file;
346+
_mutex.lock();
310347
off_t res = lfs_file_seek(&_lfs, f, offset, lfs_fromwhence(whence));
348+
_mutex.unlock();
311349
return lfs_toerror(res);
312350
}
313351

314352
off_t LittleFileSystem::file_tell(fs_file_t file) {
315353
lfs_file_t *f = (lfs_file_t *)file;
354+
_mutex.lock();
316355
off_t res = lfs_file_tell(&_lfs, f);
356+
_mutex.unlock();
317357
return lfs_toerror(res);
318358
}
319359

320360
off_t LittleFileSystem::file_size(fs_file_t file) {
321361
lfs_file_t *f = (lfs_file_t *)file;
362+
_mutex.lock();
322363
off_t res = lfs_file_size(&_lfs, f);
364+
_mutex.unlock();
323365
return lfs_toerror(res);
324366
}
325367

@@ -328,21 +370,27 @@ off_t LittleFileSystem::file_size(fs_file_t file) {
328370
int LittleFileSystem::dir_open(fs_dir_t *dir, const char *path) {
329371
lfs_dir_t *d = new lfs_dir_t;
330372
*dir = d;
373+
_mutex.lock();
331374
int err = lfs_dir_open(&_lfs, d, path);
375+
_mutex.unlock();
332376
return lfs_toerror(err);
333377
}
334378

335379
int LittleFileSystem::dir_close(fs_dir_t dir) {
336380
lfs_dir_t *d = (lfs_dir_t *)dir;
381+
_mutex.lock();
337382
int err = lfs_dir_close(&_lfs, d);
383+
_mutex.unlock();
338384
delete d;
339385
return lfs_toerror(err);
340386
}
341387

342388
ssize_t LittleFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) {
343389
lfs_dir_t *d = (lfs_dir_t *)dir;
344390
struct lfs_info info;
391+
_mutex.lock();
345392
int res = lfs_dir_read(&_lfs, d, &info);
393+
_mutex.unlock();
346394
if (res == 1) {
347395
ent->d_type = lfs_totype(info.type);
348396
strcpy(ent->d_name, info.name);
@@ -352,16 +400,23 @@ ssize_t LittleFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) {
352400

353401
void LittleFileSystem::dir_seek(fs_dir_t dir, off_t offset) {
354402
lfs_dir_t *d = (lfs_dir_t *)dir;
403+
_mutex.lock();
355404
lfs_dir_seek(&_lfs, d, offset);
405+
_mutex.unlock();
356406
}
357407

358408
off_t LittleFileSystem::dir_tell(fs_dir_t dir) {
359409
lfs_dir_t *d = (lfs_dir_t *)dir;
360-
return lfs_dir_tell(&_lfs, d);
410+
_mutex.lock();
411+
lfs_soff_t res = lfs_dir_tell(&_lfs, d);
412+
_mutex.unlock();
413+
return lfs_toerror(res);
361414
}
362415

363416
void LittleFileSystem::dir_rewind(fs_dir_t dir) {
364417
lfs_dir_t *d = (lfs_dir_t *)dir;
418+
_mutex.lock();
365419
lfs_dir_rewind(&_lfs, d);
420+
_mutex.unlock();
366421
}
367422

LittleFileSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "FileSystem.h"
2626
#include "BlockDevice.h"
27+
#include "PlatformMutex.h"
2728
extern "C" {
2829
#include "lfs.h"
2930
}
@@ -273,6 +274,9 @@ class LittleFileSystem : public FileSystem {
273274
const lfs_size_t _prog_size;
274275
const lfs_size_t _block_size;
275276
const lfs_size_t _lookahead;
277+
278+
// thread-safe locking
279+
PlatformMutex _mutex;
276280
};
277281

278282

littlefs/lfs_util.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,47 @@ static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
3737
}
3838

3939
static inline uint32_t lfs_ctz(uint32_t a) {
40-
#ifdef __ICCARM__
40+
#if defined(__GNUC__) || defined(__CC_ARM)
41+
return __builtin_ctz(a);
42+
#elif defined(__ICCARM__)
4143
return __CLZ(__RBIT(a));
4244
#else
43-
return __builtin_ctz(a);
45+
uint32_t r = 32;
46+
a &= -a;
47+
if (a) r -= 1;
48+
if (a & 0x0000ffff) r -= 16;
49+
if (a & 0x00ff00ff) r -= 8;
50+
if (a & 0x0f0f0f0f) r -= 4;
51+
if (a & 0x33333333) r -= 2;
52+
if (a & 0x55555555) r -= 1;
53+
return r;
4454
#endif
4555
}
4656

4757
static inline uint32_t lfs_npw2(uint32_t a) {
48-
#ifdef __ICCARM__
58+
#if defined(__GNUC__) || defined(__CC_ARM)
59+
return 32 - __builtin_clz(a-1);
60+
#elif defined(__ICCARM__)
4961
return 32 - __CLZ(a-1);
5062
#else
51-
return 32 - __builtin_clz(a-1);
63+
uint32_t r = 0;
64+
uint32_t s;
65+
s = (a > 0xffff) << 4; a >>= s; r |= s;
66+
s = (a > 0xff ) << 3; a >>= s; r |= s;
67+
s = (a > 0xf ) << 2; a >>= s; r |= s;
68+
s = (a > 0x3 ) << 1; a >>= s; r |= s;
69+
return r | (a >> 1);
5270
#endif
5371
}
5472

5573
static inline uint32_t lfs_popc(uint32_t a) {
74+
#if defined(__GNUC__) || defined(__CC_ARM)
5675
return __builtin_popcount(a);
76+
#else
77+
a = a - ((a >> 1) & 0x55555555);
78+
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
79+
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
80+
#endif
5781
}
5882

5983
static inline int lfs_scmp(uint32_t a, uint32_t b) {

0 commit comments

Comments
 (0)