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 "SolidSyslogSharedScratch.h"
6 : :
7 : : #include <stdbool.h>
8 : : #include <stddef.h>
9 : : #include <stdint.h>
10 : :
11 : : #include "SolidSyslogError.h"
12 : : #include "SolidSyslogErrorCategory.h"
13 : : #include "SolidSyslogPoolAllocator.h"
14 : : #include "SolidSyslogPrival.h"
15 : : #include "SolidSyslogSharedScratchErrors.h"
16 : : #include "SolidSyslogSharedScratchPrivate.h"
17 : : #include "SolidSyslogStackScratch.h"
18 : : #include "SolidSyslogTunables.h"
19 : :
20 : : struct SolidSyslogMutex;
21 : : struct SolidSyslogScratch;
22 : :
23 : : static inline size_t SharedScratch_IndexFromHandle(const struct SolidSyslogScratch* base);
24 : : static inline void SharedScratch_CleanupAtIndex(size_t index, void* context);
25 : :
26 : : /* One per logger the build can hold: the logger pool tunable sizes this pool
27 : : * too, and a build that never calls Create links none of it. */
28 : : static bool SharedScratch_InUse[SOLIDSYSLOG_POOL_SIZE];
29 : : static struct SolidSyslogSharedScratch SharedScratch_Pool[SOLIDSYSLOG_POOL_SIZE];
30 : : static struct SolidSyslogPoolAllocator SharedScratch_Allocator = {SharedScratch_InUse, SOLIDSYSLOG_POOL_SIZE};
31 : :
32 : : /* Both faults fall back to the stack scratch, so logging goes on; the report
33 : : * says the RAM saving is not being made. */
34 : 27 : struct SolidSyslogScratch* SolidSyslogSharedScratch_Create(struct SolidSyslogMutex* mutex)
35 : : {
36 : 27 : struct SolidSyslogScratch* handle = SolidSyslogStackScratch_Get();
37 [ + + ]: 27 : if (mutex == NULL)
38 : : {
39 : 2 : SharedScratch_Report(
40 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
41 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
42 : : SOLIDSYSLOG_SHARED_SCRATCH_ERROR_NULL_MUTEX
43 : : );
44 : : }
45 : : else
46 : : {
47 : 25 : size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&SharedScratch_Allocator);
48 [ + + ]: 25 : if (SolidSyslogPoolAllocator_IndexIsValid(&SharedScratch_Allocator, index))
49 : : {
50 : 23 : SolidSyslogSharedScratch_Initialise(&SharedScratch_Pool[index].Base, mutex);
51 : 23 : handle = &SharedScratch_Pool[index].Base;
52 : : }
53 : : else
54 : : {
55 : 2 : SharedScratch_Report(
56 : : SOLIDSYSLOG_POOL_EXHAUSTED_SEVERITY,
57 : : SOLIDSYSLOG_CAT_POOL_EXHAUSTED,
58 : : SOLIDSYSLOG_SHARED_SCRATCH_ERROR_POOL_EXHAUSTED
59 : : );
60 : : }
61 : : }
62 : 27 : return handle;
63 : : }
64 : :
65 : 28 : void SolidSyslogSharedScratch_Destroy(struct SolidSyslogScratch* base)
66 : : {
67 : 28 : size_t index = SharedScratch_IndexFromHandle(base);
68 : 28 : bool released =
69 [ + + + + ]: 52 : SolidSyslogPoolAllocator_IndexIsValid(&SharedScratch_Allocator, index) &&
70 : 24 : SolidSyslogPoolAllocator_FreeIfInUse(&SharedScratch_Allocator, index, SharedScratch_CleanupAtIndex, NULL);
71 [ + + ]: 28 : if (!released)
72 : : {
73 : 5 : SharedScratch_Report(
74 : : SOLIDSYSLOG_UNKNOWN_DESTROY_SEVERITY,
75 : : SOLIDSYSLOG_CAT_UNKNOWN_DESTROY,
76 : : SOLIDSYSLOG_SHARED_SCRATCH_ERROR_UNKNOWN_DESTROY
77 : : );
78 : : }
79 : 28 : }
80 : :
81 : 28 : static inline size_t SharedScratch_IndexFromHandle(const struct SolidSyslogScratch* base)
82 : : {
83 : 28 : size_t result = SOLIDSYSLOG_POOL_SIZE;
84 [ + + ]: 32 : for (size_t poolIndex = 0U; poolIndex < SOLIDSYSLOG_POOL_SIZE; poolIndex++)
85 : : {
86 [ + + ]: 28 : if (base == &SharedScratch_Pool[poolIndex].Base)
87 : : {
88 : 24 : result = poolIndex;
89 : 24 : break;
90 : : }
91 : : }
92 : 28 : return result;
93 : : }
94 : :
95 : 23 : static inline void SharedScratch_CleanupAtIndex(size_t index, void* context)
96 : : {
97 : : (void) context;
98 : 23 : SolidSyslogSharedScratch_Cleanup(&SharedScratch_Pool[index].Base);
99 : 23 : }
|