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 "FreeRTOS.h"
6 : :
7 : : /* This component requires FreeRTOS built with static allocation and mutexes. */
8 : : #if (configSUPPORT_STATIC_ALLOCATION == 1) && (configUSE_MUTEXES == 1)
9 : :
10 : : #include "SolidSyslogFreeRtosMutex.h"
11 : :
12 : : #include <stddef.h>
13 : :
14 : : #include "semphr.h"
15 : :
16 : : #include "SolidSyslogError.h"
17 : : #include "SolidSyslogFreeRtosMutexErrors.h"
18 : : #include "SolidSyslogFreeRtosMutexPrivate.h"
19 : : #include "SolidSyslogMutexDefinition.h"
20 : : #include "SolidSyslogNullMutex.h"
21 : :
22 : : const struct SolidSyslogErrorSource SolidSyslogFreeRtosMutexErrorSource = {
23 : : "FreeRtosMutex",
24 : : SolidSyslogMutexErrors_Name
25 : : };
26 : :
27 : : static void FreeRtosMutex_Lock(struct SolidSyslogMutex* base);
28 : : static void FreeRtosMutex_Unlock(struct SolidSyslogMutex* base);
29 : :
30 : : static inline struct SolidSyslogFreeRtosMutex* FreeRtosMutex_SelfFromBase(struct SolidSyslogMutex* base);
31 : : static inline SemaphoreHandle_t FreeRtosMutex_AsHandle(struct SolidSyslogFreeRtosMutex* self);
32 : :
33 : 16 : void SolidSyslogFreeRtosMutex_Initialise(struct SolidSyslogMutex* base)
34 : : {
35 : 16 : struct SolidSyslogFreeRtosMutex* self = FreeRtosMutex_SelfFromBase(base);
36 : : /* The storage is ours, so this cannot fail for want of memory; the kernel
37 : : * returns NULL only when handed a NULL buffer, which this call never does.
38 : : * configSUPPORT_STATIC_ALLOCATION is a compile-time requirement rather than
39 : : * a runtime one - without it the function does not exist to call. The
40 : : * branch is therefore defensive: an unexpected NULL leaves the NullMutex
41 : : * vtable in place rather than a dangling handle in Lock/Unlock. */
42 [ + + ]: 16 : if (xSemaphoreCreateMutexStatic(&self->Buffer) != NULL)
43 : : {
44 : 14 : self->Base.Lock = FreeRtosMutex_Lock;
45 : 14 : self->Base.Unlock = FreeRtosMutex_Unlock;
46 : : }
47 : : else
48 : : {
49 : 2 : *base = *SolidSyslogNullMutex_Get();
50 : : }
51 : 16 : }
52 : :
53 : 34 : static inline struct SolidSyslogFreeRtosMutex* FreeRtosMutex_SelfFromBase(struct SolidSyslogMutex* base)
54 : : {
55 : 34 : return (struct SolidSyslogFreeRtosMutex*) base;
56 : : }
57 : :
58 : 16 : void SolidSyslogFreeRtosMutex_Cleanup(struct SolidSyslogMutex* base)
59 : : {
60 : 16 : struct SolidSyslogFreeRtosMutex* self = FreeRtosMutex_SelfFromBase(base);
61 [ + + ]: 16 : if (self->Base.Lock == FreeRtosMutex_Lock)
62 : : {
63 : 14 : vSemaphoreDelete(FreeRtosMutex_AsHandle(self));
64 : : }
65 : : /* Overwrite the abstract base with the shared NullMutex vtable so
66 : : * use-after-destroy is a safe no-op rather than a NULL-fn-pointer crash. */
67 : 16 : *base = *SolidSyslogNullMutex_Get();
68 : 16 : }
69 : :
70 : : /* cppcheck-suppress constParameterPointer -- hands back the storage as a handle the kernel writes through. */
71 : 16 : static inline SemaphoreHandle_t FreeRtosMutex_AsHandle(struct SolidSyslogFreeRtosMutex* self)
72 : : {
73 : 16 : return (SemaphoreHandle_t) &self->Buffer;
74 : : }
75 : :
76 : 1 : static void FreeRtosMutex_Lock(struct SolidSyslogMutex* base)
77 : : {
78 : 1 : (void) xSemaphoreTake(FreeRtosMutex_AsHandle(FreeRtosMutex_SelfFromBase(base)), portMAX_DELAY);
79 : 1 : }
80 : :
81 : 1 : static void FreeRtosMutex_Unlock(struct SolidSyslogMutex* base)
82 : : {
83 : 1 : (void) xSemaphoreGive(FreeRtosMutex_AsHandle(FreeRtosMutex_SelfFromBase(base)));
84 : 1 : }
85 : :
86 : : #else
87 : :
88 : : /* ISO C forbids an empty translation unit. */
89 : : typedef int FreeRtosMutex_EmptyTranslationUnit;
90 : :
91 : : #endif /* configSUPPORT_STATIC_ALLOCATION && configUSE_MUTEXES */
|