xref: /xnu-8792.61.2/libkern/os/log_mem.h (revision 42e220869062b56f8d7d0726fd4c88954f87902c)
1 /*
2  * Copyright (c) 2020-2021 Apple Inc. All rights reserved.
3  *
4  * @APPLE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. Please obtain a copy of the License at
10  * http://www.opensource.apple.com/apsl/ and read it before using this
11  * file.
12  *
13  * The Original Code and all software distributed under the License are
14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18  * Please see the License for the specific language governing rights and
19  * limitations under the License.
20  *
21  * @APPLE_LICENSE_HEADER_END@
22  */
23 
24 #ifndef log_mem_h
25 #define log_mem_h
26 
27 #include <stddef.h>
28 #include <stdint.h>
29 #include <sys/param.h>
30 
31 /*
32  * A simple allocator on a top of a plain byte array. Primarily intended to
33  * support OS kernel logging in order to avoid dependency to VM.
34  */
35 typedef struct logmem_s {
36 	lck_spin_t  lm_lock;
37 	uint8_t     *lm_mem;
38 	uint8_t     *lm_mem_map;
39 	size_t      lm_mem_size;
40 	size_t      lm_cap_order;
41 	size_t      lm_min_order;
42 	size_t      lm_max_order;
43 	uint32_t    lm_cnt_allocations;
44 	uint32_t    lm_cnt_failed_size;
45 	uint32_t    lm_cnt_failed_full;
46 	uint32_t    lm_cnt_failed_lmoff;
47 	uint32_t    lm_cnt_free;
48 } logmem_t;
49 
50 /*
51  * Initializes dynamically allocated logmem. The caller is responsible for
52  * allocating and providing backing memory for both data and the bitmap.
53  * LOGMEM_SIZE and LOGMEM_MAP_SIZE provide a way to determine the right sizes.
54  */
55 void logmem_init(logmem_t *, void *, size_t, size_t, size_t, size_t);
56 
57 /*
58  * Returns true if the logmem is initialized, false otherwise.
59  */
60 bool logmem_ready(const logmem_t *);
61 
62 /*
63  * Allocates memory from a respective logmem. Returns a pointer to the beginning
64  * of the allocated block. The resulting size of the allocated block is equal or
65  * bigger than the size passed in during the call. The function comes in two
66  * flavours, locking and non-locking. The caller is responsible for choosing the
67  * right one based on where and how the logmem is used.
68  */
69 void *logmem_alloc(logmem_t *, size_t *);
70 void *logmem_alloc_locked(logmem_t *, size_t *);
71 
72 /*
73  * Frees memory previously allocated by logmem_alloc*(). The caller must call
74  * logmem_free*() with exact pointer and size value returned by logmem_alloc*().
75  * The function comes in two flavours, locking and non-locking. The caller is
76  * responsible for choosing the right one based on where and how the logmem is
77  * used.
78  */
79 void logmem_free(logmem_t *, void *, size_t);
80 void logmem_free_locked(logmem_t *, void *, size_t);
81 
82 /*
83  * Returns the maximum memory size allocatable by the logmem.
84  */
85 size_t logmem_max_size(const logmem_t *);
86 
87 /*
88  * Returns true if logmem is empty, false otherwise.
89  */
90 bool logmem_empty(const logmem_t *);
91 
92 /*
93  * Returns an amount of memory the logmem needs to be initialized with in order
94  * to provide allocations and to maintain its internal state. The caller should
95  * use this function to get the right amount, allocate the memory accodingly and
96  * pass it to logmem_init().
97  */
98 size_t logmem_required_size(size_t, size_t);
99 
100 #endif /* log_mem_h */
101