home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
lxapi32.zip
/
Lib32
/
lxresource.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-04-26
|
4KB
|
145 lines
/* $Id: lxresource.c,v 1.2 2002/04/26 23:09:24 smilcke Exp $ */
/*
* resource.c
* Autor: Stefan Milcke
* Erstellt am: 25.10.2001
* Letzte Aenderung am: 31.12.2001
*
*/
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/io.h>
static rwlock_t resource_lock=RW_LOCK_UNLOCKED;
//----------------------------- __request_resource -----------------------------
static struct resource *__request_resource(struct resource *root
,struct resource *newr)
{
unsigned long start=newr->start;
unsigned long end=newr->end;
struct resource *tmp,**p;
if(end<start)
return root;
if(start<root->start)
return root;
if(end>root->end)
return root;
p=&root->child;
for(;;)
{
tmp=*p;
if(!tmp||tmp->start>end)
{
newr->sibling=tmp;
*p=newr;
newr->parent=root;
return 0;
}
p=&tmp->sibling;
if(tmp->end<start)
continue;
return tmp;
}
}
//----------------------------- __release_resource -----------------------------
static int __release_resource(struct resource *old)
{
struct resource *tmp,**p;
p=&old->parent->child;
for(;;)
{
tmp=*p;
if(!tmp)
break;
if(tmp==old)
{
*p=tmp->sibling;
old->parent=0;
return 0;
}
p=&tmp->sibling;
}
return -EINVAL;
}
//------------------------------ request_resource ------------------------------
int request_resource(struct resource *root,struct resource *newr)
{
struct resource *conflict;
write_lock((spinlock_t *)&resource_lock);
conflict=__request_resource(root,newr);
write_unlock((spinlock_t *)&resource_lock);
return conflict ? -EBUSY : 0;
}
//------------------------------ release_resource ------------------------------
int release_resource(struct resource *old)
{
int retval;
write_lock((spinlock_t *)&resource_lock);
retval=__release_resource(old);
write_unlock((spinlock_t *)&resource_lock);
return retval;
}
//------------------------------- find_resource --------------------------------
static int find_resource(struct resource *root,struct resource *newr
,unsigned long size
,unsigned long min,unsigned long max
,unsigned long align
,void (*alignf)(void *,struct resource *,unsigned long)
,void *alignf_data)
{
struct resource *thisr=root->child;
newr->start=root->start;
for(;;)
{
if(thisr)
newr->end=thisr->start;
else
newr->end=root->end;
if(newr->start<min)
newr->start=min;
if(newr->end>max)
newr->end=max;
newr->start=(newr->start + align-1)&~(align-1);
if(alignf)
alignf(alignf_data,newr,size);
if(newr->start<newr->end && newr->end-newr->start+1>=size)
{
newr->end=newr->start+size-1;
return 0;
}
if(!thisr)
break;
newr->start=thisr->end+1;
thisr=thisr->sibling;
}
return -EBUSY;
}
//----------------------------- allocate_resource ------------------------------
int allocate_resource(struct resource *root,struct resource *newr
,unsigned long size
,unsigned long min,unsigned long max
,unsigned long align
,void (*alignf)(void *,struct resource*,unsigned long)
,void *alignf_data)
{
int err;
write_lock((spinlock_t *)&resource_lock);
err=find_resource(root,newr,size,min,max,align,alignf,alignf_data);
if(err>=0 && __request_resource(root,newr))
err=-EBUSY;
write_unlock((spinlock_t *)&resource_lock);
return err;
}