Branch data Line data Source code
1 : : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
2 : : * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
3 : : */
4 : :
5 : : #include "SolidSyslogCmsisRtosMutex.h"
6 : :
7 : : #include <stdbool.h>
8 : : #include <stddef.h>
9 : : #include <stdint.h>
10 : :
11 : : #include "SolidSyslogCmsisRtosMutexErrors.h"
12 : : #include "SolidSyslogCmsisRtosMutexPrivate.h"
13 : : #include "SolidSyslogError.h"
14 : : #include "SolidSyslogErrorCategory.h"
15 : : #include "SolidSyslogNullMutex.h"
16 : : #include "SolidSyslogPoolAllocator.h"
17 : : #include "SolidSyslogPrival.h"
18 : : #include "SolidSyslogTunables.h"
19 : :
20 : : struct SolidSyslogMutex;
21 : :
22 : : static inline size_t CmsisRtosMutex_IndexFromHandle(const struct SolidSyslogMutex* base);
23 : : static inline void CmsisRtosMutex_CleanupAtIndex(size_t index, void* context);
24 : :
25 : : static bool CmsisRtosMutex_InUse[SOLIDSYSLOG_MUTEX_POOL_SIZE];
26 : : static struct SolidSyslogCmsisRtosMutex CmsisRtosMutex_Pool[SOLIDSYSLOG_MUTEX_POOL_SIZE];
27 : : static struct SolidSyslogPoolAllocator CmsisRtosMutex_Allocator = {CmsisRtosMutex_InUse, SOLIDSYSLOG_MUTEX_POOL_SIZE};
28 : :
29 : 30 : struct SolidSyslogMutex* SolidSyslogCmsisRtosMutex_Create(void* controlBlock, uint32_t controlBlockBytes)
30 : : {
31 : 30 : size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&CmsisRtosMutex_Allocator);
32 : 30 : struct SolidSyslogMutex* handle = SolidSyslogNullMutex_Get();
33 [ + + ]: 30 : if (SolidSyslogPoolAllocator_IndexIsValid(&CmsisRtosMutex_Allocator, index) == true)
34 : : {
35 : : bool created =
36 : 26 : SolidSyslogCmsisRtosMutex_Initialise(&CmsisRtosMutex_Pool[index].Base, controlBlock, controlBlockBytes);
37 [ + + ]: 26 : if (created == true)
38 : : {
39 : 20 : handle = &CmsisRtosMutex_Pool[index].Base;
40 : : }
41 : : else
42 : : {
43 : : /* The RTOS refused to make the mutex, so the slot goes straight
44 : : * back: the caller is handed the shared NullMutex and holds nothing
45 : : * that names this slot, and a deterministic refusal would otherwise
46 : : * empty the pool one retry at a time. */
47 : 6 : (void) SolidSyslogPoolAllocator_FreeIfInUse(
48 : : &CmsisRtosMutex_Allocator,
49 : : index,
50 : : CmsisRtosMutex_CleanupAtIndex,
51 : : NULL
52 : : );
53 : : }
54 : : }
55 : : else
56 : : {
57 : 4 : CmsisRtosMutex_Report(
58 : : SOLIDSYSLOG_POOL_EXHAUSTED_SEVERITY,
59 : : SOLIDSYSLOG_CAT_POOL_EXHAUSTED,
60 : : SOLIDSYSLOG_MUTEX_ERROR_POOL_EXHAUSTED
61 : : );
62 : : }
63 : 30 : return handle;
64 : : }
65 : :
66 : 30 : void SolidSyslogCmsisRtosMutex_Destroy(struct SolidSyslogMutex* base)
67 : : {
68 : 30 : size_t index = CmsisRtosMutex_IndexFromHandle(base);
69 : 30 : bool released =
70 [ + + + + ]: 51 : SolidSyslogPoolAllocator_IndexIsValid(&CmsisRtosMutex_Allocator, index) &&
71 : 21 : SolidSyslogPoolAllocator_FreeIfInUse(&CmsisRtosMutex_Allocator, index, CmsisRtosMutex_CleanupAtIndex, NULL);
72 [ + + ]: 30 : if (!released)
73 : : {
74 : 10 : CmsisRtosMutex_Report(
75 : : SOLIDSYSLOG_UNKNOWN_DESTROY_SEVERITY,
76 : : SOLIDSYSLOG_CAT_UNKNOWN_DESTROY,
77 : : SOLIDSYSLOG_MUTEX_ERROR_UNKNOWN_DESTROY
78 : : );
79 : : }
80 : 30 : }
81 : :
82 : 30 : static inline size_t CmsisRtosMutex_IndexFromHandle(const struct SolidSyslogMutex* base)
83 : : {
84 : 30 : size_t result = SOLIDSYSLOG_MUTEX_POOL_SIZE;
85 [ + + ]: 39 : for (size_t poolIndex = 0U; poolIndex < SOLIDSYSLOG_MUTEX_POOL_SIZE; poolIndex++)
86 : : {
87 [ + + ]: 30 : if (base == &CmsisRtosMutex_Pool[poolIndex].Base)
88 : : {
89 : 21 : result = poolIndex;
90 : 21 : break;
91 : : }
92 : : }
93 : 30 : return result;
94 : : }
95 : :
96 : 26 : static inline void CmsisRtosMutex_CleanupAtIndex(size_t index, void* context)
97 : : {
98 : : (void) context;
99 : 26 : SolidSyslogCmsisRtosMutex_Cleanup(&CmsisRtosMutex_Pool[index].Base);
100 : 26 : }
|