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 ACPI_STATUS 60 AcpiOsCreateCache(char *CacheName, UINT16 ObjectSize, UINT16 MaxDepth, 61 ACPI_CACHE_T **ReturnCache) 62 { 63 ACPI_CACHE_T *cache; 64 65 cache = kmalloc(sizeof(*cache), M_TEMP, M_WAITOK); 66 cache->args.objsize = OBJHEADSIZE + ObjectSize; 67 cache->args.mtype = M_CACHE; 68 cache->cache = objcache_create(CacheName, 0, 0, NULL, NULL, 69 NULL, objcache_malloc_alloc, objcache_malloc_free, &cache->args); 70 *ReturnCache = cache; 71 return AE_OK; 72 } 73 74 ACPI_STATUS 75 AcpiOsDeleteCache(ACPI_CACHE_T *Cache) 76 { 77 objcache_destroy(Cache->cache); 78 kfree(Cache, M_TEMP); 79 return AE_OK; 80 } 81 82 83 ACPI_STATUS 84 AcpiOsPurgeCache(ACPI_CACHE_T *Cache) 85 { 86 struct objcache *reclaimlist[] = { Cache->cache }; 87 88 objcache_reclaimlist(reclaimlist, 1, M_WAITOK); 89 return AE_OK; 90 } 91 92 void * 93 AcpiOsAcquireObject(ACPI_CACHE_T *Cache) 94 { 95 struct acpiobjhead *head; 96 97 head = objcache_get(Cache->cache, M_WAITOK); 98 bzero(head, Cache->args.objsize); 99 head->state = TRACK_ALLOCATED; 100 #ifdef ACPI_DEBUG_CACHE 101 head->cache = Cache; 102 head->func = "nowhere"; 103 head->line = 0; 104 #endif 105 return (head + 1); 106 } 107 108 ACPI_STATUS 109 #ifdef ACPI_DEBUG_CACHE 110 _AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object, 111 const char *func, int line) 112 #else 113 AcpiOsReleaseObject(ACPI_CACHE_T *Cache, void *Object) 114 #endif 115 { 116 struct acpiobjhead *head = (void *)((char *)Object - OBJHEADSIZE); 117 118 #ifdef ACPI_DEBUG_CACHE 119 if (head->cache != Cache) { 120 kprintf("%s: object %p belongs to %p, not %p\n", 121 __func__, Object, head->cache, Cache); 122 } 123 #endif 124 if (head->state != TRACK_ALLOCATED) { 125 if (head->state == TRACK_FREED) { 126 #ifdef ACPI_DEBUG_CACHE 127 kprintf("%s: Double Free %p, %s:%d, first %s:%d\n", 128 __func__, Object, func, line, head->func, 129 head->line); 130 #else 131 kprintf("%s: Double Free %p\n", __func__, Object); 132 #endif 133 } else 134 kprintf("AcpiOsReleaseObject: Bad object %p (%08x)\n", 135 Object, head->state); 136 return AE_OK; 137 } 138 head->state = TRACK_FREED; 139 #ifdef ACPI_DEBUG_CACHE 140 head->func = func; 141 head->line = line; 142 #endif 143 objcache_put(Cache->cache, head); 144 return AE_OK; 145 } 146