aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/utcache.c
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2012-10-30 22:25:05 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-11-14 18:31:21 -0500
commit6d33b6be17dd6a0934396704f969ceb7f3206347 (patch)
tree4cf68009186944acd1b8ef10fb2b5b87e8c0c2f3 /drivers/acpi/acpica/utcache.c
parent45dcd31547fcd58273423799b12efe0e8371127e (diff)
ACPICA: Fix unmerged utility divergences.
Utility improvements in ACPICA are partial ignored by ACPICA Linux release. This will lead to divergences between Linux and ACPICA. This patch ports the entire "utility" into Linux and makes them igored in the compilation stage by "ACPI_FUTURE_USAGE". The following "Utility" files have been ported into the Linux: drivers/acpi/uttrack.c drivers/acpi/utcache.c drivers/acpi/utids.c This patch will not affect the generated vmlinx binary. This will decrease 274 lines of 20120913 divergence.diff. Signed-off-by: Robert Moore <robert.moore@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/utcache.c')
-rw-r--r--drivers/acpi/acpica/utcache.c323
1 files changed, 323 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c
new file mode 100644
index 000000000000..eacb9ba2b9e0
--- /dev/null
+++ b/drivers/acpi/acpica/utcache.c
@@ -0,0 +1,323 @@
1/******************************************************************************
2 *
3 * Module Name: utcache - local cache allocation routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utcache")
49
50#ifdef ACPI_USE_LOCAL_CACHE
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_os_create_cache
54 *
55 * PARAMETERS: cache_name - Ascii name for the cache
56 * object_size - Size of each cached object
57 * max_depth - Maximum depth of the cache (in objects)
58 * return_cache - Where the new cache object is returned
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Create a cache object
63 *
64 ******************************************************************************/
65acpi_status
66acpi_os_create_cache(char *cache_name,
67 u16 object_size,
68 u16 max_depth, struct acpi_memory_list ** return_cache)
69{
70 struct acpi_memory_list *cache;
71
72 ACPI_FUNCTION_ENTRY();
73
74 if (!cache_name || !return_cache || (object_size < 16)) {
75 return (AE_BAD_PARAMETER);
76 }
77
78 /* Create the cache object */
79
80 cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
81 if (!cache) {
82 return (AE_NO_MEMORY);
83 }
84
85 /* Populate the cache object and return it */
86
87 ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
88 cache->link_offset = 8;
89 cache->list_name = cache_name;
90 cache->object_size = object_size;
91 cache->max_depth = max_depth;
92
93 *return_cache = cache;
94 return (AE_OK);
95}
96
97/*******************************************************************************
98 *
99 * FUNCTION: acpi_os_purge_cache
100 *
101 * PARAMETERS: cache - Handle to cache object
102 *
103 * RETURN: Status
104 *
105 * DESCRIPTION: Free all objects within the requested cache.
106 *
107 ******************************************************************************/
108
109acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache)
110{
111 char *next;
112 acpi_status status;
113
114 ACPI_FUNCTION_ENTRY();
115
116 if (!cache) {
117 return (AE_BAD_PARAMETER);
118 }
119
120 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
121 if (ACPI_FAILURE(status)) {
122 return (status);
123 }
124
125 /* Walk the list of objects in this cache */
126
127 while (cache->list_head) {
128
129 /* Delete and unlink one cached state object */
130
131 next = *(ACPI_CAST_INDIRECT_PTR(char,
132 &(((char *)cache->
133 list_head)[cache->
134 link_offset])));
135 ACPI_FREE(cache->list_head);
136
137 cache->list_head = next;
138 cache->current_depth--;
139 }
140
141 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
142 return (AE_OK);
143}
144
145/*******************************************************************************
146 *
147 * FUNCTION: acpi_os_delete_cache
148 *
149 * PARAMETERS: cache - Handle to cache object
150 *
151 * RETURN: Status
152 *
153 * DESCRIPTION: Free all objects within the requested cache and delete the
154 * cache object.
155 *
156 ******************************************************************************/
157
158acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache)
159{
160 acpi_status status;
161
162 ACPI_FUNCTION_ENTRY();
163
164 /* Purge all objects in the cache */
165
166 status = acpi_os_purge_cache(cache);
167 if (ACPI_FAILURE(status)) {
168 return (status);
169 }
170
171 /* Now we can delete the cache object */
172
173 acpi_os_free(cache);
174 return (AE_OK);
175}
176
177/*******************************************************************************
178 *
179 * FUNCTION: acpi_os_release_object
180 *
181 * PARAMETERS: cache - Handle to cache object
182 * object - The object to be released
183 *
184 * RETURN: None
185 *
186 * DESCRIPTION: Release an object to the specified cache. If cache is full,
187 * the object is deleted.
188 *
189 ******************************************************************************/
190
191acpi_status
192acpi_os_release_object(struct acpi_memory_list * cache, void *object)
193{
194 acpi_status status;
195
196 ACPI_FUNCTION_ENTRY();
197
198 if (!cache || !object) {
199 return (AE_BAD_PARAMETER);
200 }
201
202 /* If cache is full, just free this object */
203
204 if (cache->current_depth >= cache->max_depth) {
205 ACPI_FREE(object);
206 ACPI_MEM_TRACKING(cache->total_freed++);
207 }
208
209 /* Otherwise put this object back into the cache */
210
211 else {
212 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
213 if (ACPI_FAILURE(status)) {
214 return (status);
215 }
216
217 /* Mark the object as cached */
218
219 ACPI_MEMSET(object, 0xCA, cache->object_size);
220 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED);
221
222 /* Put the object at the head of the cache list */
223
224 *(ACPI_CAST_INDIRECT_PTR(char,
225 &(((char *)object)[cache->
226 link_offset]))) =
227 cache->list_head;
228 cache->list_head = object;
229 cache->current_depth++;
230
231 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
232 }
233
234 return (AE_OK);
235}
236
237/*******************************************************************************
238 *
239 * FUNCTION: acpi_os_acquire_object
240 *
241 * PARAMETERS: cache - Handle to cache object
242 *
243 * RETURN: the acquired object. NULL on error
244 *
245 * DESCRIPTION: Get an object from the specified cache. If cache is empty,
246 * the object is allocated.
247 *
248 ******************************************************************************/
249
250void *acpi_os_acquire_object(struct acpi_memory_list *cache)
251{
252 acpi_status status;
253 void *object;
254
255 ACPI_FUNCTION_NAME(os_acquire_object);
256
257 if (!cache) {
258 return (NULL);
259 }
260
261 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
262 if (ACPI_FAILURE(status)) {
263 return (NULL);
264 }
265
266 ACPI_MEM_TRACKING(cache->requests++);
267
268 /* Check the cache first */
269
270 if (cache->list_head) {
271
272 /* There is an object available, use it */
273
274 object = cache->list_head;
275 cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char,
276 &(((char *)
277 object)[cache->
278 link_offset])));
279
280 cache->current_depth--;
281
282 ACPI_MEM_TRACKING(cache->hits++);
283 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
284 "Object %p from %s cache\n", object,
285 cache->list_name));
286
287 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
288 if (ACPI_FAILURE(status)) {
289 return (NULL);
290 }
291
292 /* Clear (zero) the previously used Object */
293
294 ACPI_MEMSET(object, 0, cache->object_size);
295 } else {
296 /* The cache is empty, create a new object */
297
298 ACPI_MEM_TRACKING(cache->total_allocated++);
299
300#ifdef ACPI_DBG_TRACK_ALLOCATIONS
301 if ((cache->total_allocated - cache->total_freed) >
302 cache->max_occupied) {
303 cache->max_occupied =
304 cache->total_allocated - cache->total_freed;
305 }
306#endif
307
308 /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
309
310 status = acpi_ut_release_mutex(ACPI_MTX_CACHES);
311 if (ACPI_FAILURE(status)) {
312 return (NULL);
313 }
314
315 object = ACPI_ALLOCATE_ZEROED(cache->object_size);
316 if (!object) {
317 return (NULL);
318 }
319 }
320
321 return (object);
322}
323#endif /* ACPI_USE_LOCAL_CACHE */