/*
*
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
* Copyright (c) 2009, Intel Corporation.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files(the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice(including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
*/
/*
* Generic simple memory manager implementation. Intended to be used as a base
* class implementation for more advanced memory managers.
*
* Note that the algorithm used is quite simple and there might be substantial
* performance gains if a smarter free list is implemented.
* Currently it is just an
* unordered stack of free regions. This could easily be improved if an RB-tree
* is used instead. At least if we expect heavy fragmentation.
*
* Aligned allocations can also see improvement.
*
* Authors:
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "drmP.h"
unsigned long
{
return (0);
}
int
{
return (ENOMEM);
return (ENOMEM);
return (0);
}
static int
unsigned long start,
unsigned long size)
{
child = (struct drm_mm_node *)
if (!child)
return (ENOMEM);
return (0);
}
int
{
return (drm_mm_create_tail_node(mm,
}
return (0);
}
static struct drm_mm_node *
unsigned long size)
{
child = (struct drm_mm_node *)
if (!child)
return (NULL);
return (child);
}
/*
* Put a block. Merge with the previous and / or next block if they are free.
* Otherwise add to the free stack.
*/
void
{
int merged = 0;
struct drm_mm_node, ml_entry);
merged = 1;
}
}
struct drm_mm_node, ml_entry);
if (merged) {
sizeof (*next_node), DRM_MEM_MM);
} else {
merged = 1;
}
}
}
if (!merged) {
} else {
}
}
struct drm_mm_node *
unsigned long size,
unsigned alignment)
{
unsigned tmp = 0;
if (alignment)
if (tmp) {
if (!align_splitoff)
return (NULL);
}
return (parent);
} else {
}
if (align_splitoff)
return (child);
}
struct drm_mm_node *
unsigned long size,
unsigned alignment,
int best_match)
{
unsigned long best_size;
unsigned wasted;
wasted = 0;
continue;
if (alignment) {
if (tmp)
}
if (!best_match)
return (entry);
}
}
}
return (best);
}
int
{
}
int
{
}
void
{
DRM_ERROR("Memory manager not clean. Delaying takedown\n");
return;
}
}
void
{
return;
DRM_DEBUG("ml_entry 0x%x, size 0x%x, start 0x%x",
}
}