Files
odkitee/serialization/bump_allocator.c
2020-07-24 12:03:58 -07:00

62 lines
1.6 KiB
C

/*
* Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
* source code may only be used and distributed under the Widevine Master
* License Agreement.
*/
#include "bump_allocator.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INITIAL_ALLOCATOR_BUFFER_SIZE (8 * 1024)
static uint8_t buffer[INITIAL_ALLOCATOR_BUFFER_SIZE];
static uint8_t* ptr = buffer;
static size_t buffer_size = sizeof(buffer);
static size_t buffer_offset = 0;
uint8_t* BumpAllocate(size_t nbytes) {
size_t new_offset = 0;
if(__builtin_add_overflow(buffer_offset, nbytes, &new_offset) ||
(new_offset > buffer_size)) {
/*
* The bump allocator buffer should be large enough that a malloc
* is never required. But allow a malloc if the buffer overflows.
*/
fprintf(stderr, "Warning: bump allocator memory size exceeded,"
" size=%zd, requested=%zd\n", buffer_size, new_offset);
size_t new_size = 2 * buffer_size;
uint8_t* new_ptr = malloc(new_size);
if (new_ptr == NULL) {
fprintf(stderr, "Fatal: bump allocator could not malloc %zd bytes\n",
new_size);
abort();
}
memcpy(new_ptr, ptr, buffer_size);
memset(new_ptr + buffer_size, 0, buffer_size);
buffer_size = new_size;
if (ptr != buffer) {
free(ptr);
}
ptr = new_ptr;
}
uint8_t* result = ptr + buffer_offset;
memset(result, 0, nbytes);
buffer_offset = new_offset;
return result;
}
void BumpAllocator_Reset(void) {
buffer_offset = 0;
if (ptr != buffer) {
free(ptr);
}
ptr = buffer;
buffer_size = sizeof(buffer);
memset(buffer, 0, sizeof(buffer));
}