Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nouveau_heap.c
4570 views
/*1* Copyright 2007 Nouveau Project2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*/2122#include <stdlib.h>23#include <errno.h>2425#include "nouveau_heap.h"2627int28nouveau_heap_init(struct nouveau_heap **heap,29unsigned start, unsigned size)30{31struct nouveau_heap *r;3233r = calloc(1, sizeof(struct nouveau_heap));34if (!r)35return 1;3637r->start = start;38r->size = size;39*heap = r;40return 0;41}4243void44nouveau_heap_destroy(struct nouveau_heap **heap)45{46if (!*heap)47return;48free(*heap);49*heap = NULL;50}5152int53nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv,54struct nouveau_heap **res)55{56struct nouveau_heap *r;5758if (!heap || !size || !res || *res)59return 1;6061while (heap) {62if (!heap->in_use && heap->size >= size) {63r = calloc(1, sizeof(struct nouveau_heap));64if (!r)65return 1;6667r->start = (heap->start + heap->size) - size;68r->size = size;69r->in_use = 1;70r->priv = priv;7172heap->size -= size;7374r->next = heap->next;75if (heap->next)76heap->next->prev = r;77r->prev = heap;78heap->next = r;7980*res = r;81return 0;82}8384heap = heap->next;85}8687return 1;88}8990void91nouveau_heap_free(struct nouveau_heap **res)92{93struct nouveau_heap *r;9495if (!res || !*res)96return;97r = *res;98*res = NULL;99100r->in_use = 0;101102if (r->next && !r->next->in_use) {103struct nouveau_heap *new = r->next;104105new->prev = r->prev;106if (r->prev)107r->prev->next = new;108new->size += r->size;109new->start = r->start;110111free(r);112r = new;113}114115if (r->prev && !r->prev->in_use) {116r->prev->next = r->next;117if (r->next)118r->next->prev = r->prev;119r->prev->size += r->size;120free(r);121}122}123124125