0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012
0013 #define _COMPONENT ACPI_UTILITIES
0014 ACPI_MODULE_NAME("utcache")
0015
0016 #ifdef ACPI_USE_LOCAL_CACHE
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 acpi_status
0032 acpi_os_create_cache(char *cache_name,
0033 u16 object_size,
0034 u16 max_depth, struct acpi_memory_list **return_cache)
0035 {
0036 struct acpi_memory_list *cache;
0037
0038 ACPI_FUNCTION_ENTRY();
0039
0040 if (!cache_name || !return_cache || !object_size) {
0041 return (AE_BAD_PARAMETER);
0042 }
0043
0044
0045
0046 cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
0047 if (!cache) {
0048 return (AE_NO_MEMORY);
0049 }
0050
0051
0052
0053 memset(cache, 0, sizeof(struct acpi_memory_list));
0054 cache->list_name = cache_name;
0055 cache->object_size = object_size;
0056 cache->max_depth = max_depth;
0057
0058 *return_cache = cache;
0059 return (AE_OK);
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 acpi_status acpi_os_purge_cache(struct acpi_memory_list *cache)
0075 {
0076 void *next;
0077 acpi_status status;
0078
0079 ACPI_FUNCTION_ENTRY();
0080
0081 if (!cache) {
0082 return (AE_BAD_PARAMETER);
0083 }
0084
0085 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
0086 if (ACPI_FAILURE(status)) {
0087 return (status);
0088 }
0089
0090
0091
0092 while (cache->list_head) {
0093
0094
0095
0096 next = ACPI_GET_DESCRIPTOR_PTR(cache->list_head);
0097 ACPI_FREE(cache->list_head);
0098
0099 cache->list_head = next;
0100 cache->current_depth--;
0101 }
0102
0103 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
0104 return (AE_OK);
0105 }
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 acpi_status acpi_os_delete_cache(struct acpi_memory_list *cache)
0121 {
0122 acpi_status status;
0123
0124 ACPI_FUNCTION_ENTRY();
0125
0126
0127
0128 status = acpi_os_purge_cache(cache);
0129 if (ACPI_FAILURE(status)) {
0130 return (status);
0131 }
0132
0133
0134
0135 acpi_os_free(cache);
0136 return (AE_OK);
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 acpi_status acpi_os_release_object(struct acpi_memory_list *cache, void *object)
0154 {
0155 acpi_status status;
0156
0157 ACPI_FUNCTION_ENTRY();
0158
0159 if (!cache || !object) {
0160 return (AE_BAD_PARAMETER);
0161 }
0162
0163
0164
0165 if (cache->current_depth >= cache->max_depth) {
0166 ACPI_FREE(object);
0167 ACPI_MEM_TRACKING(cache->total_freed++);
0168 }
0169
0170
0171
0172 else {
0173 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
0174 if (ACPI_FAILURE(status)) {
0175 return (status);
0176 }
0177
0178
0179
0180 memset(object, 0xCA, cache->object_size);
0181 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED);
0182
0183
0184
0185 ACPI_SET_DESCRIPTOR_PTR(object, cache->list_head);
0186 cache->list_head = object;
0187 cache->current_depth++;
0188
0189 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
0190 }
0191
0192 return (AE_OK);
0193 }
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 void *acpi_os_acquire_object(struct acpi_memory_list *cache)
0209 {
0210 acpi_status status;
0211 void *object;
0212
0213 ACPI_FUNCTION_TRACE(os_acquire_object);
0214
0215 if (!cache) {
0216 return_PTR(NULL);
0217 }
0218
0219 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
0220 if (ACPI_FAILURE(status)) {
0221 return_PTR(NULL);
0222 }
0223
0224 ACPI_MEM_TRACKING(cache->requests++);
0225
0226
0227
0228 if (cache->list_head) {
0229
0230
0231
0232 object = cache->list_head;
0233 cache->list_head = ACPI_GET_DESCRIPTOR_PTR(object);
0234
0235 cache->current_depth--;
0236
0237 ACPI_MEM_TRACKING(cache->hits++);
0238 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
0239 "%s: Object %p from %s cache\n",
0240 ACPI_GET_FUNCTION_NAME, object,
0241 cache->list_name));
0242
0243 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
0244 if (ACPI_FAILURE(status)) {
0245 return_PTR(NULL);
0246 }
0247
0248
0249
0250 memset(object, 0, cache->object_size);
0251 } else {
0252
0253
0254 ACPI_MEM_TRACKING(cache->total_allocated++);
0255
0256 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0257 if ((cache->total_allocated - cache->total_freed) >
0258 cache->max_occupied) {
0259 cache->max_occupied =
0260 cache->total_allocated - cache->total_freed;
0261 }
0262 #endif
0263
0264
0265
0266 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
0267 if (ACPI_FAILURE(status)) {
0268 return_PTR(NULL);
0269 }
0270
0271 object = ACPI_ALLOCATE_ZEROED(cache->object_size);
0272 if (!object) {
0273 return_PTR(NULL);
0274 }
0275 }
0276
0277 return_PTR(object);
0278 }
0279 #endif