|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
The optional mutual-exclusion seam taken around every public call. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_fs.h"#include "ra8_fs_fat_internal.h"Go to the source code of this file.
Functions | |
| void | priv_lock_acquire (void) |
| Take the library lock, if the caller installed one. | |
| void | priv_lock_release (void) |
| Drop the library lock taken by priv_lock_acquire. | |
| ra8_err_t | ra8_fs_set_lock (const ra8_fs_lock_t *lock) |
| Install (or remove) the lock taken around every public ra8_fs call. | |
Variables | |
| static ra8_fs_lock_t | s_lock |
| The installed lock binding; meaningful only when s_lock_installed. | |
| static bool | s_lock_installed |
| True once a complete binding has been installed. | |
The optional mutual-exclusion seam taken around every public call.
ra8_fs was written for a world with no scheduler, and its shared state – the file-handle table, the mount table, the one static scratch sector – is serialised by there being nobody else to race. That is the correct default and it stays the default: with no binding installed the two helpers here compile down to a load and a branch, and nothing else in the library changes.
What this file adds is somewhere for an RTOS-world caller to put its mutex, so the alternative is not "wrap every call site by hand" or "ship a second filesystem to get a lock". The binding is a pair of function pointers plus a cookie (ra8_fs_lock_t); no lock primitive, no RTOS header and no scheduler concept appears in this library, and the adapter that binds tx_mutex_get / tx_mutex_put lives with the caller that owns the mutex.
The lock is taken by the public entry points only. Every one of them is a wrapper of the shape
priv_lock_acquire(); e = priv_<op>_locked(...); priv_lock_release();
so a return path that forgets to release cannot be written – there is one return per wrapper – and every guarded implementation carries RA8_EXPECTS_LOCK("ra8_fs_lock") so the annotation checker, not a comment, is what says no internal helper may take it a second time.
Definition in file ra8_fs_fat_lock.c.
| void priv_lock_acquire | ( | void | ) |
Take the library lock, if the caller installed one.
Invokes the installed ra8_fs_lock_t::acquire with its cookie. With no binding installed – the bare-metal default – this is a load and a branch and nothing else, which is why the seam costs the default world nothing. Called only by the public entry-point wrappers: an internal helper taking it a second time would deadlock a non-recursive mutex, and the RA8_EXPECTS_LOCK("ra8_fs_lock") tag on every guarded implementation is what enforces that.
Definition at line 75 of file ra8_fs_fat_lock.c.
References s_lock, and s_lock_installed.
Referenced by ra8_fs_check(), ra8_fs_close(), ra8_fs_dir_next(), ra8_fs_dir_open(), ra8_fs_format(), ra8_fs_free_space(), ra8_fs_get_label(), ra8_fs_listdir(), ra8_fs_mkdir(), ra8_fs_mount(), ra8_fs_mount_partition(), ra8_fs_open(), ra8_fs_probe(), ra8_fs_read(), ra8_fs_rename(), ra8_fs_rmdir(), ra8_fs_seek(), ra8_fs_set_attr(), ra8_fs_set_label(), ra8_fs_size(), ra8_fs_stat(), ra8_fs_tell(), ra8_fs_truncate(), ra8_fs_unlink(), ra8_fs_unmount(), ra8_fs_utime(), ra8_fs_write(), and ra8_fs_write_file().
| void priv_lock_release | ( | void | ) |
Drop the library lock taken by priv_lock_acquire.
Invokes the installed ra8_fs_lock_t::release with its cookie, or does nothing when no binding is installed. This is the release half the annotation checker looks for when it decides whether a public wrapper discharged the ownership it took.
Definition at line 84 of file ra8_fs_fat_lock.c.
References s_lock, and s_lock_installed.
Referenced by ra8_fs_check(), ra8_fs_close(), ra8_fs_dir_next(), ra8_fs_dir_open(), ra8_fs_format(), ra8_fs_free_space(), ra8_fs_get_label(), ra8_fs_listdir(), ra8_fs_mkdir(), ra8_fs_mount(), ra8_fs_mount_partition(), ra8_fs_open(), ra8_fs_probe(), ra8_fs_read(), ra8_fs_rename(), ra8_fs_rmdir(), ra8_fs_seek(), ra8_fs_set_attr(), ra8_fs_set_label(), ra8_fs_size(), ra8_fs_stat(), ra8_fs_tell(), ra8_fs_truncate(), ra8_fs_unlink(), ra8_fs_unmount(), ra8_fs_utime(), ra8_fs_write(), and ra8_fs_write_file().
|
nodiscard |
Install (or remove) the lock taken around every public ra8_fs call.
There is one lock for the whole library, not one per mount: the state that needs serialising – the file-handle table, the mount table and the static scratch sector – is shared by every mount. Installing a lock therefore serialises every public entry point against every other one.
Passing NULL removes the binding and restores the default: no lock, no call, and the caller is once again responsible for serialising access. That is the state the library powers up in, so a bare-metal consumer never calls this function at all and pays nothing for its existence.
The binding is copied, so the caller's ra8_fs_lock_t need not outlive the call; the object ra8_fs_lock_t::ctx points at must, however, outlive every subsequent ra8_fs call.
Call this before the first ra8_fs call and before any other thread can reach the library: swapping the binding while a call is in flight would release a lock the caller never took.
| [in] | lock | Lock binding to install, or NULL to remove the current one. |
| k_ra8_ok | Binding installed (or removed for a NULL lock). |
| k_ra8_err_invalid_arg | lock is non-NULL but acquire or release is NULL – a half-filled binding would leave the library holding a lock it cannot drop. |
lock is non-NULL, both of its callbacks are non-NULL. lock, every subsequent public call brackets itself with acquire / release. lock, no callback is invoked again. Definition at line 92 of file ra8_fs_fat_lock.c.
References ra8_fs_lock_t::acquire, k_ra8_err_invalid_arg, k_ra8_ok, ra8_fs_lock_t::release, s_lock, and s_lock_installed.
Referenced by tx_application_define().
|
static |
The installed lock binding; meaningful only when s_lock_installed.
A copy of the caller's ra8_fs_lock_t rather than a pointer to it, so a binding built as a compound literal or on the installing function's stack stays valid for the life of the program. The ctx cookie is still the caller's to keep alive.
Definition at line 58 of file ra8_fs_fat_lock.c.
Referenced by priv_lock_acquire(), priv_lock_release(), and ra8_fs_set_lock().
|
static |
True once a complete binding has been installed.
Kept separate from s_lock so "no lock" is one predictable branch rather than a NULL test on a function pointer that the compiler must reload.
Definition at line 72 of file ra8_fs_fat_lock.c.
Referenced by priv_lock_acquire(), priv_lock_release(), and ra8_fs_set_lock().