1 /* 2 * Copyright (c) 2006 Jeffrey M. Hsu. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Jeffrey M. Hsu. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of The DragonFly Project nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific, prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/objcache.h> 34 35 struct acpicache { 36 struct objcache *cache; 37 struct objcache_malloc_args args; 38 }; 39 40 /* 41 * Add some magic numbers to catch double-frees earlier rather 42 * then later. 43 */ 44 struct acpiobjhead { 45 int state; 46 void *cache; 47 const char *func; 48 int line; 49 int unused; 50 }; 51 52 #define TRACK_ALLOCATED 0x7AF45533 53 #define TRACK_FREED 0x7B056644 54 55 #define OBJHEADSIZE sizeof(struct acpiobjhead) 56 57 #include "acpi.h" 58 59 #ifndef ACPI_USE_LOCAL_CACHE 60 61 ACPI_STATUS 62 AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, 63 ACPI_CACHE_T **ReturnCache) 64 { 65 ACPI_CACHE_T *cache; 66 67 cache = kmalloc(sizeof(*cache), M_TEMP, M_WAITOK); 68 cache->args.objsize = OBJHEADSIZE + ObjectSize; 69 cache->args.mtype = M_CACHE; 70 cache->cache = objcache_create(CacheName, 0, 0, NULL, NULL, 71 NULL, objcache_malloc_alloc, objcache_malloc_free, &cache->args); 72 *ReturnCache = cache; 73 return AE_OK; 74 } 75 76 ACPI_STATUS 77 AcpiOsDeleteCache(ACPI_CACHE_T *Cache) 78 { 79 objcache_destroy(Cache->cache); 80 kfree(Cache, M_TEMP); 81 return AE_OK; 82 } 83 84 85 ACPI_STATUS 86 AcpiOsPurgeCache(ACPI_CACHE_T *Cache) 87 { 88 struct objcache *reclaimlist[] = { Cache->cache }; 89 90 objcache_reclaimlist(reclaimlist, 1, M_WAITOK); 91 return AE_OK; 92 } 93 94 void * 95 AcpiOsAcquireObject(ACPI_CACHE_T *Cache) 96 { 97 struct acpiobjhead *head; 98 99 head = objcache_get(Cache->cache, M_WAITOK); 100 bzero(head, Cache->args.objsize); 101 head->state = TRACK_ALLOCATED; 102 #ifdef ACPI_DEBUG_CACHE 103 head->cache = Cache; 104 head->func = "nowhere"; 105 head->line = 0; 106 #endif 107 return (head + 1); 108 } 109 110 ACPI_STATUS 111 #ifdef ACPI_DEBUG_CACHE 112 _AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object, 113 const char *func, int line) 114 #else 115 AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object) 116 #endif 117 { 118 struct acpiobjhead *head = (void *)((char *)Object - OBJHEADSIZE); 119 120 #ifdef ACPI_DEBUG_CACHE 121 if (head->cache != Cache) { 122 kprintf("%s: object %p belongs to %p, not %p\n", 123 __func__, Object, head->cache, Cache); 124 } 125 #endif 126 if (head->state != TRACK_ALLOCATED) { 127 if (head->state == TRACK_FREED) { 128 #ifdef ACPI_DEBUG_CACHE 129 kprintf("%s: Double Free %p, %s:%d, first %s:%d\n", 130 __func__, Object, func, line, head->func, 131 head->line); 132 #else 133 kprintf("%s: Double Free %p\n", __func__, Object); 134 #endif 135 } else 136 kprintf("AcpiOsReleaseObject: Bad object %p (%08x)\n", 137 Object, head->state); 138 return AE_OK; 139 } 140 head->state = TRACK_FREED; 141 #ifdef ACPI_DEBUG_CACHE 142 head->func = func; 143 head->line = line; 144 #endif 145 objcache_put(Cache->cache, head); 146 return AE_OK; 147 } 148 149 #endif 150