1848b8605Smrg/* 2848b8605Smrg * Copyright 2007 Nouveau Project 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 9848b8605Smrg * Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice shall be included in 12848b8605Smrg * all copies or substantial portions of the Software. 13848b8605Smrg * 14848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 21848b8605Smrg */ 22848b8605Smrg 23848b8605Smrg#include <stdlib.h> 24848b8605Smrg#include <errno.h> 25848b8605Smrg 26848b8605Smrg#include "nouveau_heap.h" 27848b8605Smrg 28848b8605Smrgint 29848b8605Smrgnouveau_heap_init(struct nouveau_heap **heap, 30848b8605Smrg unsigned start, unsigned size) 31848b8605Smrg{ 32b8e80941Smrg struct nouveau_heap *r; 33848b8605Smrg 34b8e80941Smrg r = calloc(1, sizeof(struct nouveau_heap)); 35b8e80941Smrg if (!r) 36b8e80941Smrg return 1; 37848b8605Smrg 38b8e80941Smrg r->start = start; 39b8e80941Smrg r->size = size; 40b8e80941Smrg *heap = r; 41b8e80941Smrg return 0; 42848b8605Smrg} 43848b8605Smrg 44848b8605Smrgvoid 45848b8605Smrgnouveau_heap_destroy(struct nouveau_heap **heap) 46848b8605Smrg{ 47b8e80941Smrg if (!*heap) 48b8e80941Smrg return; 49b8e80941Smrg free(*heap); 50b8e80941Smrg *heap = NULL; 51848b8605Smrg} 52848b8605Smrg 53848b8605Smrgint 54848b8605Smrgnouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv, 55848b8605Smrg struct nouveau_heap **res) 56848b8605Smrg{ 57b8e80941Smrg struct nouveau_heap *r; 58848b8605Smrg 59b8e80941Smrg if (!heap || !size || !res || *res) 60b8e80941Smrg return 1; 61848b8605Smrg 62b8e80941Smrg while (heap) { 63b8e80941Smrg if (!heap->in_use && heap->size >= size) { 64b8e80941Smrg r = calloc(1, sizeof(struct nouveau_heap)); 65b8e80941Smrg if (!r) 66b8e80941Smrg return 1; 67848b8605Smrg 68b8e80941Smrg r->start = (heap->start + heap->size) - size; 69b8e80941Smrg r->size = size; 70b8e80941Smrg r->in_use = 1; 71b8e80941Smrg r->priv = priv; 72848b8605Smrg 73b8e80941Smrg heap->size -= size; 74848b8605Smrg 75b8e80941Smrg r->next = heap->next; 76b8e80941Smrg if (heap->next) 77b8e80941Smrg heap->next->prev = r; 78b8e80941Smrg r->prev = heap; 79b8e80941Smrg heap->next = r; 80848b8605Smrg 81b8e80941Smrg *res = r; 82b8e80941Smrg return 0; 83b8e80941Smrg } 84848b8605Smrg 85b8e80941Smrg heap = heap->next; 86b8e80941Smrg } 87848b8605Smrg 88b8e80941Smrg return 1; 89848b8605Smrg} 90848b8605Smrg 91848b8605Smrgvoid 92848b8605Smrgnouveau_heap_free(struct nouveau_heap **res) 93848b8605Smrg{ 94b8e80941Smrg struct nouveau_heap *r; 95b8e80941Smrg 96b8e80941Smrg if (!res || !*res) 97b8e80941Smrg return; 98b8e80941Smrg r = *res; 99b8e80941Smrg *res = NULL; 100b8e80941Smrg 101b8e80941Smrg r->in_use = 0; 102b8e80941Smrg 103b8e80941Smrg if (r->next && !r->next->in_use) { 104b8e80941Smrg struct nouveau_heap *new = r->next; 105b8e80941Smrg 106b8e80941Smrg new->prev = r->prev; 107b8e80941Smrg if (r->prev) 108b8e80941Smrg r->prev->next = new; 109b8e80941Smrg new->size += r->size; 110b8e80941Smrg new->start = r->start; 111b8e80941Smrg 112b8e80941Smrg free(r); 113b8e80941Smrg r = new; 114b8e80941Smrg } 115b8e80941Smrg 116b8e80941Smrg if (r->prev && !r->prev->in_use) { 117b8e80941Smrg r->prev->next = r->next; 118b8e80941Smrg if (r->next) 119b8e80941Smrg r->next->prev = r->prev; 120b8e80941Smrg r->prev->size += r->size; 121b8e80941Smrg free(r); 122b8e80941Smrg } 123848b8605Smrg} 124