2005-04-16 15:20:36 -07:00
/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*-
* Created : Mon Jan 4 10 : 05 : 05 1999 by sclin @ sis . com . tw
*
* Copyright 2000 Silicon Integrated Systems Corp , Inc . , HsinChu , Taiwan .
* 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 , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
2005-09-25 14:28:13 +10:00
*
2005-04-16 15:20:36 -07:00
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
2005-09-25 14:28:13 +10:00
*
2005-04-16 15:20:36 -07:00
* 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 NONINFRINGEMENT . IN NO EVENT SHALL
* PRECISION INSIGHT AND / OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM , 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 .
2005-09-25 14:28:13 +10:00
*
2005-04-16 15:20:36 -07:00
* Authors :
* Sung - Ching Lin < sclin @ sis . com . tw >
2005-09-25 14:28:13 +10:00
*
2005-04-16 15:20:36 -07:00
*/
# include "drmP.h"
# include "drm.h"
# include "sis_ds.h"
/* Set Data Structure, not check repeated value
* temporarily used
*/
set_t * setInit ( void )
{
int i ;
set_t * set ;
2005-09-25 14:28:13 +10:00
set = ( set_t * ) drm_alloc ( sizeof ( set_t ) , DRM_MEM_DRIVER ) ;
2005-04-16 15:20:36 -07:00
if ( set ! = NULL ) {
for ( i = 0 ; i < SET_SIZE ; i + + ) {
2005-09-25 14:28:13 +10:00
set - > list [ i ] . free_next = i + 1 ;
2005-04-16 15:20:36 -07:00
set - > list [ i ] . alloc_next = - 1 ;
}
2005-09-25 14:28:13 +10:00
set - > list [ SET_SIZE - 1 ] . free_next = - 1 ;
2005-04-16 15:20:36 -07:00
set - > free = 0 ;
set - > alloc = - 1 ;
set - > trace = - 1 ;
}
return set ;
}
2005-09-25 14:28:13 +10:00
int setAdd ( set_t * set , ITEM_TYPE item )
2005-04-16 15:20:36 -07:00
{
int free = set - > free ;
2005-09-25 14:28:13 +10:00
2005-04-16 15:20:36 -07:00
if ( free ! = - 1 ) {
set - > list [ free ] . val = item ;
set - > free = set - > list [ free ] . free_next ;
} else {
return 0 ;
}
set - > list [ free ] . alloc_next = set - > alloc ;
2005-09-25 14:28:13 +10:00
set - > alloc = free ;
set - > list [ free ] . free_next = - 1 ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
2005-09-25 14:28:13 +10:00
int setDel ( set_t * set , ITEM_TYPE item )
2005-04-16 15:20:36 -07:00
{
int alloc = set - > alloc ;
2005-09-25 14:28:13 +10:00
int prev = - 1 ;
2005-04-16 15:20:36 -07:00
while ( alloc ! = - 1 ) {
if ( set - > list [ alloc ] . val = = item ) {
if ( prev ! = - 1 )
set - > list [ prev ] . alloc_next =
set - > list [ alloc ] . alloc_next ;
else
set - > alloc = set - > list [ alloc ] . alloc_next ;
break ;
}
prev = alloc ;
alloc = set - > list [ alloc ] . alloc_next ;
}
if ( alloc = = - 1 )
return 0 ;
set - > list [ alloc ] . free_next = set - > free ;
set - > free = alloc ;
set - > list [ alloc ] . alloc_next = - 1 ;
return 1 ;
}
/* setFirst -> setAdd -> setNext is wrong */
2005-09-25 14:28:13 +10:00
int setFirst ( set_t * set , ITEM_TYPE * item )
2005-04-16 15:20:36 -07:00
{
if ( set - > alloc = = - 1 )
return 0 ;
* item = set - > list [ set - > alloc ] . val ;
set - > trace = set - > list [ set - > alloc ] . alloc_next ;
return 1 ;
}
2005-09-25 14:28:13 +10:00
int setNext ( set_t * set , ITEM_TYPE * item )
2005-04-16 15:20:36 -07:00
{
if ( set - > trace = = - 1 )
return 0 ;
* item = set - > list [ set - > trace ] . val ;
set - > trace = set - > list [ set - > trace ] . alloc_next ;
return 1 ;
}
2005-09-25 14:28:13 +10:00
int setDestroy ( set_t * set )
2005-04-16 15:20:36 -07:00
{
drm_free ( set , sizeof ( set_t ) , DRM_MEM_DRIVER ) ;
return 1 ;
}
/*
* GLX Hardware Device Driver common code
* Copyright ( C ) 1999 Wittawat Yamwong
*
* 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 , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice 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 NONINFRINGEMENT . IN NO EVENT SHALL
2005-09-25 14:28:13 +10:00
* WITTAWAT YAMWONG , OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM ,
* DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR
* OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE
2005-04-16 15:20:36 -07:00
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*
*/
# define ISFREE(bptr) ((bptr)->free)
2005-09-25 14:28:13 +10:00
memHeap_t * mmInit ( int ofs , int size )
2005-04-16 15:20:36 -07:00
{
PMemBlock blocks ;
if ( size < = 0 )
return NULL ;
2005-09-25 14:28:13 +10:00
blocks = ( TMemBlock * ) drm_calloc ( 1 , sizeof ( TMemBlock ) , DRM_MEM_DRIVER ) ;
2005-04-16 15:20:36 -07:00
if ( blocks ! = NULL ) {
blocks - > ofs = ofs ;
blocks - > size = size ;
blocks - > free = 1 ;
2005-09-25 14:28:13 +10:00
return ( memHeap_t * ) blocks ;
2005-04-16 15:20:36 -07:00
} else
return NULL ;
}
/* Checks if a pointer 'b' is part of the heap 'heap' */
2005-09-25 14:28:13 +10:00
int mmBlockInHeap ( memHeap_t * heap , PMemBlock b )
2005-04-16 15:20:36 -07:00
{
TMemBlock * p ;
if ( heap = = NULL | | b = = NULL )
return 0 ;
p = heap ;
while ( p ! = NULL & & p ! = b ) {
p = p - > next ;
}
if ( p = = b )
return 1 ;
else
return 0 ;
}
2005-09-25 14:28:13 +10:00
static TMemBlock * SliceBlock ( TMemBlock * p ,
int startofs , int size ,
2005-04-16 15:20:36 -07:00
int reserved , int alignment )
{
TMemBlock * newblock ;
/* break left */
if ( startofs > p - > ofs ) {
2005-09-25 14:28:13 +10:00
newblock = ( TMemBlock * ) drm_calloc ( 1 , sizeof ( TMemBlock ) ,
DRM_MEM_DRIVER ) ;
2005-04-16 15:20:36 -07:00
newblock - > ofs = startofs ;
newblock - > size = p - > size - ( startofs - p - > ofs ) ;
newblock - > free = 1 ;
newblock - > next = p - > next ;
p - > size - = newblock - > size ;
p - > next = newblock ;
p = newblock ;
}
/* break right */
if ( size < p - > size ) {
2005-09-25 14:28:13 +10:00
newblock = ( TMemBlock * ) drm_calloc ( 1 , sizeof ( TMemBlock ) ,
DRM_MEM_DRIVER ) ;
2005-04-16 15:20:36 -07:00
newblock - > ofs = startofs + size ;
newblock - > size = p - > size - size ;
newblock - > free = 1 ;
newblock - > next = p - > next ;
p - > size = size ;
p - > next = newblock ;
}
/* p = middle block */
p - > align = alignment ;
p - > free = 0 ;
p - > reserved = reserved ;
return p ;
}
2005-09-25 14:28:13 +10:00
PMemBlock mmAllocMem ( memHeap_t * heap , int size , int align2 , int startSearch )
2005-04-16 15:20:36 -07:00
{
2005-09-25 14:28:13 +10:00
int mask , startofs , endofs ;
2005-04-16 15:20:36 -07:00
TMemBlock * p ;
2005-09-25 14:28:13 +10:00
2005-04-16 15:20:36 -07:00
if ( heap = = NULL | | align2 < 0 | | size < = 0 )
return NULL ;
2005-09-25 14:28:13 +10:00
mask = ( 1 < < align2 ) - 1 ;
2005-04-16 15:20:36 -07:00
startofs = 0 ;
2005-09-25 14:28:13 +10:00
p = ( TMemBlock * ) heap ;
2005-04-16 15:20:36 -07:00
while ( p ! = NULL ) {
if ( ISFREE ( p ) ) {
startofs = ( p - > ofs + mask ) & ~ mask ;
2005-09-25 14:28:13 +10:00
if ( startofs < startSearch ) {
2005-04-16 15:20:36 -07:00
startofs = startSearch ;
}
2005-09-25 14:28:13 +10:00
endofs = startofs + size ;
if ( endofs < = ( p - > ofs + p - > size ) )
2005-04-16 15:20:36 -07:00
break ;
}
p = p - > next ;
}
if ( p = = NULL )
return NULL ;
2005-09-25 14:28:13 +10:00
p = SliceBlock ( p , startofs , size , 0 , mask + 1 ) ;
2005-04-16 15:20:36 -07:00
p - > heap = heap ;
return p ;
}
2005-09-25 14:28:13 +10:00
static __inline__ int Join2Blocks ( TMemBlock * p )
2005-04-16 15:20:36 -07:00
{
if ( p - > free & & p - > next & & p - > next - > free ) {
TMemBlock * q = p - > next ;
p - > size + = q - > size ;
p - > next = q - > next ;
drm_free ( q , sizeof ( TMemBlock ) , DRM_MEM_DRIVER ) ;
return 1 ;
}
return 0 ;
}
int mmFreeMem ( PMemBlock b )
{
TMemBlock * p , * prev ;
if ( b = = NULL )
return 0 ;
if ( b - > heap = = NULL )
return - 1 ;
p = b - > heap ;
prev = NULL ;
while ( p ! = NULL & & p ! = b ) {
prev = p ;
p = p - > next ;
}
if ( p = = NULL | | p - > free | | p - > reserved )
return - 1 ;
p - > free = 1 ;
Join2Blocks ( p ) ;
if ( prev )
2005-09-25 14:28:13 +10:00
Join2Blocks ( prev ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}