/src/avm/avm_mem/avm_mem.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 3-Clause Clear License |
5 | | * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear |
6 | | * License was not distributed with this source code in the LICENSE file, you |
7 | | * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the |
8 | | * Alliance for Open Media Patent License 1.0 was not distributed with this |
9 | | * source code in the PATENTS file, you can obtain it at |
10 | | * aomedia.org/license/patent-license/. |
11 | | */ |
12 | | |
13 | | #include "avm_mem.h" |
14 | | #include <stdio.h> |
15 | | #include <stdlib.h> |
16 | | #include <string.h> |
17 | | #include "include/avm_mem_intrnl.h" |
18 | | #include "avm/avm_integer.h" |
19 | | |
20 | | #if defined(AVM_MAX_ALLOCABLE_MEMORY) |
21 | | // Returns 0 in case of overflow of nmemb * size. |
22 | 7.66M | static int check_size_argument_overflow(uint64_t nmemb, uint64_t size) { |
23 | 7.66M | const uint64_t total_size = nmemb * size; |
24 | 7.66M | if (nmemb == 0) return 1; |
25 | 7.66M | if (size > AVM_MAX_ALLOCABLE_MEMORY / nmemb) return 0; |
26 | 7.66M | if (total_size != (size_t)total_size) return 0; |
27 | 7.66M | return 1; |
28 | 7.66M | } |
29 | | #endif |
30 | | |
31 | 7.66M | static size_t GetAlignedMallocSize(size_t size, size_t align) { |
32 | 7.66M | return size + align - 1 + ADDRESS_STORAGE_SIZE; |
33 | 7.66M | } |
34 | | |
35 | 15.5M | static size_t *GetMallocAddressLocation(void *const mem) { |
36 | 15.5M | return ((size_t *)mem) - 1; |
37 | 15.5M | } |
38 | | |
39 | | static void SetActualMallocAddress(void *const mem, |
40 | 7.71M | const void *const malloc_addr) { |
41 | 7.71M | size_t *const malloc_addr_location = GetMallocAddressLocation(mem); |
42 | 7.71M | *malloc_addr_location = (size_t)malloc_addr; |
43 | 7.71M | } |
44 | | |
45 | 7.82M | static void *GetActualMallocAddress(void *const mem) { |
46 | 7.82M | const size_t *const malloc_addr_location = GetMallocAddressLocation(mem); |
47 | 7.82M | return (void *)(*malloc_addr_location); |
48 | 7.82M | } |
49 | | |
50 | 7.66M | void *avm_memalign(size_t align, size_t size) { |
51 | 7.66M | void *x = NULL; |
52 | 7.66M | const size_t aligned_size = GetAlignedMallocSize(size, align); |
53 | 7.66M | #if defined(AVM_MAX_ALLOCABLE_MEMORY) |
54 | 7.66M | if (!check_size_argument_overflow(1, aligned_size)) return NULL; |
55 | 7.66M | #endif |
56 | 7.66M | void *const addr = malloc(aligned_size); |
57 | 7.70M | if (addr) { |
58 | 7.70M | x = avm_align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, align); |
59 | 7.70M | SetActualMallocAddress(x, addr); |
60 | 7.70M | } |
61 | 7.66M | return x; |
62 | 7.66M | } |
63 | | |
64 | 6.19M | void *avm_malloc(size_t size) { return avm_memalign(DEFAULT_ALIGNMENT, size); } |
65 | | |
66 | 5.11M | void *avm_calloc(size_t num, size_t size) { |
67 | 5.11M | const size_t total_size = num * size; |
68 | 5.11M | void *const x = avm_malloc(total_size); |
69 | 5.16M | if (x) memset(x, 0, total_size); |
70 | 5.11M | return x; |
71 | 5.11M | } |
72 | | |
73 | 93.4M | void avm_free(void *memblk) { |
74 | 93.4M | if (memblk) { |
75 | 7.82M | void *addr = GetActualMallocAddress(memblk); |
76 | 7.82M | free(addr); |
77 | 7.82M | } |
78 | 93.4M | } |
79 | | |
80 | 34.2M | void *avm_memset16(void *dest, int val, size_t length) { |
81 | 34.2M | size_t i; |
82 | 34.2M | uint16_t *dest16 = (uint16_t *)dest; |
83 | 1.24G | for (i = 0; i < length; i++) *dest16++ = val; |
84 | 34.2M | return dest; |
85 | 34.2M | } |
86 | | |
87 | 0 | void *avm_memset_int16(void *dest, int16_t val, size_t length) { |
88 | 0 | size_t i; |
89 | 0 | int16_t *dest16 = (int16_t *)dest; |
90 | 0 | for (i = 0; i < length; i++) *dest16++ = val; |
91 | 0 | return dest; |
92 | 0 | } |