• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 /* upb_Arena is a specific allocator implementation that uses arena allocation.
9  * The user provides an allocator that will be used to allocate the underlying
10  * arena blocks.  Arenas by nature do not require the individual allocations
11  * to be freed.  However the Arena does allow users to register cleanup
12  * functions that will run when the arena is destroyed.
13  *
14  * A upb_Arena is *not* thread-safe.
15  *
16  * You could write a thread-safe arena allocator that satisfies the
17  * upb_alloc interface, but it would not be as efficient for the
18  * single-threaded case. */
19 
20 #ifndef UPB_MEM_ARENA_H_
21 #define UPB_MEM_ARENA_H_
22 
23 #include <stddef.h>
24 #include <stdint.h>
25 
26 #include "upb/mem/alloc.h"
27 #include "upb/mem/internal/arena.h"
28 
29 // Must be last.
30 #include "upb/port/def.inc"
31 
32 typedef struct upb_Arena upb_Arena;
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 // Creates an arena from the given initial block (if any -- n may be 0).
39 // Additional blocks will be allocated from |alloc|.  If |alloc| is NULL, this
40 // is a fixed-size arena and cannot grow.
41 UPB_API upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc);
42 
43 UPB_API void upb_Arena_Free(upb_Arena* a);
44 UPB_API bool upb_Arena_Fuse(upb_Arena* a, upb_Arena* b);
45 
46 bool upb_Arena_IncRefFor(upb_Arena* a, const void* owner);
47 void upb_Arena_DecRefFor(upb_Arena* a, const void* owner);
48 
49 size_t upb_Arena_SpaceAllocated(upb_Arena* a, size_t* fused_count);
50 uint32_t upb_Arena_DebugRefCount(upb_Arena* a);
51 
upb_Arena_New(void)52 UPB_API_INLINE upb_Arena* upb_Arena_New(void) {
53   return upb_Arena_Init(NULL, 0, &upb_alloc_global);
54 }
55 
56 UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size);
57 
58 UPB_API_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize,
59                                        size_t size);
60 
61 // Sets the maximum block size for all arenas. This is a global configuration
62 // setting that will affect all existing and future arenas. If
63 // upb_Arena_Malloc() is called with a size larger than this, we will exceed
64 // this size and allocate a larger block.
65 //
66 // This API is meant for experimentation only. It will likely be removed in
67 // the future.
68 void upb_Arena_SetMaxBlockSize(size_t max);
69 
70 // Shrinks the last alloc from arena.
71 // REQUIRES: (ptr, oldsize) was the last malloc/realloc from this arena.
72 // We could also add a upb_Arena_TryShrinkLast() which is simply a no-op if
73 // this was not the last alloc.
74 UPB_API_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr,
75                                          size_t oldsize, size_t size);
76 
77 #ifdef UPB_TRACING_ENABLED
78 void upb_Arena_SetTraceHandler(void (*initArenaTraceHandler)(const upb_Arena*,
79                                                              size_t size),
80                                void (*fuseArenaTraceHandler)(const upb_Arena*,
81                                                              const upb_Arena*),
82                                void (*freeArenaTraceHandler)(const upb_Arena*));
83 #endif
84 
85 #ifdef __cplusplus
86 } /* extern "C" */
87 #endif
88 
89 #include "upb/port/undef.inc"
90 
91 #endif /* UPB_MEM_ARENA_H_ */
92