psxcounters: try to support a dynarec with a very long timeslice
[pcsx_rearmed.git] / deps / lightrec / memmanager.c
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3  * Copyright (C) 2019-2021 Paul Cercueil <paul@crapouillou.net>
4  */
5
6 #include "lightrec-config.h"
7 #include "lightrec-private.h"
8 #include "memmanager.h"
9
10 #include <stdlib.h>
11 #if ENABLE_TINYMM
12 #include <tinymm.h>
13 #endif
14
15 #ifdef ENABLE_THREADED_COMPILER
16 #include <stdatomic.h>
17
18 static atomic_uint lightrec_bytes[MEM_TYPE_END];
19
20 void lightrec_register(enum mem_type type, unsigned int len)
21 {
22         atomic_fetch_add(&lightrec_bytes[type], len);
23 }
24
25 void lightrec_unregister(enum mem_type type, unsigned int len)
26 {
27         atomic_fetch_sub(&lightrec_bytes[type], len);
28 }
29
30 unsigned int lightrec_get_mem_usage(enum mem_type type)
31 {
32         return atomic_load(&lightrec_bytes[type]);
33 }
34
35 #else /* ENABLE_THREADED_COMPILER */
36
37 static unsigned int lightrec_bytes[MEM_TYPE_END];
38
39 void lightrec_register(enum mem_type type, unsigned int len)
40 {
41         lightrec_bytes[type] += len;
42 }
43
44 void lightrec_unregister(enum mem_type type, unsigned int len)
45 {
46         lightrec_bytes[type] -= len;
47 }
48
49 unsigned int lightrec_get_mem_usage(enum mem_type type)
50 {
51         return lightrec_bytes[type];
52 }
53 #endif /* ENABLE_THREADED_COMPILER */
54
55 unsigned int lightrec_get_total_mem_usage(void)
56 {
57         unsigned int i, count;
58
59         for (i = 0, count = 0; i < MEM_TYPE_END; i++)
60                 count += lightrec_get_mem_usage((enum mem_type)i);
61
62         return count;
63 }
64
65 void * lightrec_malloc(struct lightrec_state *state,
66                        enum mem_type type, unsigned int len)
67 {
68         void *ptr;
69
70 #if ENABLE_TINYMM
71         if (type == MEM_FOR_IR)
72                 ptr = tinymm_malloc(state->tinymm, len);
73         else
74 #endif
75                 ptr = malloc(len);
76         if (!ptr)
77                 return NULL;
78
79         lightrec_register(type, len);
80
81         return ptr;
82 }
83
84 void * lightrec_calloc(struct lightrec_state *state,
85                        enum mem_type type, unsigned int len)
86 {
87         void *ptr;
88
89 #if ENABLE_TINYMM
90         if (type == MEM_FOR_IR)
91                 ptr = tinymm_zalloc(state->tinymm, len);
92         else
93 #endif
94                 ptr = calloc(1, len);
95         if (!ptr)
96                 return NULL;
97
98         lightrec_register(type, len);
99
100         return ptr;
101 }
102
103 void lightrec_free(struct lightrec_state *state,
104                    enum mem_type type, unsigned int len, void *ptr)
105 {
106         lightrec_unregister(type, len);
107 #if ENABLE_TINYMM
108         if (type == MEM_FOR_IR)
109                 tinymm_free(state->tinymm, ptr);
110         else
111 #endif
112                 free(ptr);
113 }
114
115 float lightrec_get_average_ipi(void)
116 {
117         unsigned int code_mem = lightrec_get_mem_usage(MEM_FOR_CODE);
118         unsigned int native_mem = lightrec_get_mem_usage(MEM_FOR_MIPS_CODE);
119
120         return native_mem ? (float)code_mem / (float)native_mem : 0.0f;
121 }