Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/upb/mem/alloc.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2023 Google LLC.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 #ifndef UPB_MEM_ALLOC_H_
0009 #define UPB_MEM_ALLOC_H_
0010 
0011 #include <stddef.h>
0012 
0013 // Must be last.
0014 #include "upb/port/def.inc"
0015 
0016 #ifdef __cplusplus
0017 extern "C" {
0018 #endif
0019 
0020 typedef struct upb_alloc upb_alloc;
0021 
0022 /* A combined `malloc()`/`free()` function.
0023  * If `size` is 0 then the function acts like `free()`, otherwise it acts like
0024  * `realloc()`.  Only `oldsize` bytes from a previous allocation are
0025  * preserved. If `actual_size` is not null and the allocator supports it, the
0026  * actual size of the resulting allocation is stored in `actual_size`. If
0027  * `actual_size` is not null, you must zero out the memory pointed to by
0028  * `actual_size` before calling. */
0029 typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize,
0030                              size_t size, size_t* actual_size);
0031 
0032 /* A upb_alloc is a possibly-stateful allocator object.
0033  *
0034  * It could either be an arena allocator (which doesn't require individual
0035  * `free()` calls) or a regular `malloc()` (which does).  The client must
0036  * therefore free memory unless it knows that the allocator is an arena
0037  * allocator. */
0038 struct upb_alloc {
0039   upb_alloc_func* func;
0040 };
0041 
0042 UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) {
0043   UPB_ASSERT(alloc);
0044   return alloc->func(alloc, NULL, 0, size, NULL);
0045 }
0046 
0047 typedef struct {
0048   void* p;
0049   size_t n;
0050 } upb_SizedPtr;
0051 
0052 UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) {
0053   UPB_ASSERT(alloc);
0054   upb_SizedPtr result;
0055   result.n = 0;
0056   result.p = alloc->func(alloc, NULL, 0, size, &result.n);
0057   result.n = result.p != NULL ? UPB_MAX(result.n, size) : 0;
0058   return result;
0059 }
0060 
0061 UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize,
0062                              size_t size) {
0063   UPB_ASSERT(alloc);
0064   return alloc->func(alloc, ptr, oldsize, size, NULL);
0065 }
0066 
0067 UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) {
0068   UPB_ASSERT(alloc);
0069   alloc->func(alloc, ptr, 0, 0, NULL);
0070 }
0071 
0072 UPB_INLINE void upb_free_sized(upb_alloc* alloc, void* ptr, size_t size) {
0073   UPB_ASSERT(alloc);
0074   alloc->func(alloc, ptr, size, 0, NULL);
0075 }
0076 
0077 // The global allocator used by upb. Uses the standard malloc()/free().
0078 
0079 extern upb_alloc upb_alloc_global;
0080 
0081 /* Functions that hard-code the global malloc.
0082  *
0083  * We still get benefit because we can put custom logic into our global
0084  * allocator, like injecting out-of-memory faults in debug/testing builds. */
0085 
0086 UPB_INLINE void* upb_gmalloc(size_t size) {
0087   return upb_malloc(&upb_alloc_global, size);
0088 }
0089 
0090 UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) {
0091   return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
0092 }
0093 
0094 UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); }
0095 
0096 #ifdef __cplusplus
0097 } /* extern "C" */
0098 #endif
0099 
0100 #include "upb/port/undef.inc"
0101 
0102 #endif /* UPB_MEM_ALLOC_H_ */