33,027
社区成员




typedef struct
{
ushort *bitmask;
ulong *chksums;
int bitmask_sz;
int chksums_sz;
int log2_hwords_in_chksum;
int inuse;
} intpool_t;
void intpool_init(intpool_t *ip, int log2_size)
{
int log2_bitmask_sz;
int log2_chksums_sz;
int log2_hwords_in_chksum;
int i;
// how many ushorts do we need to store 1<<log2_size bitflags?
log2_bitmask_sz = log2_size - 4;
if (log2_bitmask_sz < 0)
log2_bitmask_sz = 0;
// how many checksums do we need and how many ushorts should each checksum cover
log2_chksums_sz = log2_bitmask_sz/2;
log2_hwords_in_chksum = log2_bitmask_sz - (log2_bitmask_sz/2);
// Save the results in object
ip->bitmask_sz = 1<<log2_bitmask_sz;
ip->chksums_sz = 1<<log2_chksums_sz;
ip->log2_hwords_in_chksum = log2_hwords_in_chksum;
// Allocate space for the bitmasks and the checksums
ip->bitmask = kmalloc(ip->bitmask_sz * sizeof(ushort), GFP_KERNEL);
ip->chksums = kmalloc(ip->chksums_sz * sizeof(ulong), GFP_KERNEL);
// Clear the bitmasks and the checksums
memset(ip->bitmask, 0, ip->bitmask_sz * sizeof(ushort));
memset(ip->chksums, 0, ip->chksums_sz * sizeof(ushort));
// Keep track of number allocated
ip->inuse = 0;
// Allocate all the bits we don't use (to stop them being allocated again!)
for (i = 1<<log2_size; i < ip->bitmask_sz<<4 ; i++)
{
ip->bitmask[i>>4] |= 1<<(i&0xf);
ip->chksums[(i>>4)>>(ip->log2_hwords_in_chksum)] += 1<<(i&0xf);
}
}
/*
#########################################################
#
# Function : intpool_destroy
#
# Purpose : destroys a intpool_t object freeing memory
#
# Args : ip = pointer to object
#
##########################################################
# Edit history:
# Who When What
# AJZ 27Jul01 Created
##########################################################
*/
void intpool_destroy(intpool_t *ip)
{
kfree(ip->bitmask);
kfree(ip->chksums);
}
/*
#########################################################
#
# Function : intpool_alloc
#
# Purpose : allocated a number that has never
# been allocated before, or has been recently freed
#
# Args : ip = pointer to object
#
# Returns : smallest free value or -1 for failure
##########################################################
# Edit history:
# Who When What
# AJZ 27Jul01 Created
##########################################################
*/
int intpool_alloc(intpool_t *ip)
{
int i;
int j;
int k;
// Go through the checksums till we find one that isn't
// full
for (i = 0; i < ip->chksums_sz; i++)
{
if ((ip->chksums[i]) != (0xffff<<ip->log2_hwords_in_chksum))
break;
}
// did we find one?
if (i == ip->chksums_sz)
return -1; // No!
// Yes
// There must be a clear bit in ip->bitmask[i<<ip->log2_hwords_in_chksum] to
// ip->bitmask[((i+1)<<ip->log2_hwords_in_chksum)-1]
for (j = i<<(ip->log2_hwords_in_chksum);
j < (i+1)<<(ip->log2_hwords_in_chksum);
j++)
{
if (ip->bitmask[j] != 0xffff)
break;
}
// Note: We must have found j in the range!
// Find the least significant unset bit
for (k = 0; k < 16; k++)
{
if ((ip->bitmask[j] & (1<<k)) == 0)
{
// set bit
ip->bitmask[j] |= (1<<k);
// update chksum
ip->chksums[i] += (1<<k);
// update alloc count
ip->inuse++;
// return the number
return k + (j<<4);
}
}
// This is impossible
printk(KERN_ERR "Error: (" __FUNCTION__ ") something impossible happened\n");
return -1;
}
/*
#########################################################
#
# Function : intpool_free
#
# Purpose : free a currently allocated number
#
# Args : ip = pointer to objeip; val = number to free
#
##########################################################
# Edit history:
# Who When What
# AJZ 27Jul01 Created
##########################################################
*/
void intpool_free(intpool_t *ip, int val)
{
// Don't do anything if val is out of range
if ((val>>4) >= ip->bitmask_sz)
return;
// Don't do anything if not already allocated
if (ip->bitmask[val>>4] & (1<<(val&0xf)))
{
ip->bitmask[val>>4] ^= 1<<(val&0xf);
ip->chksums[(val>>4)>>(ip->log2_hwords_in_chksum)] -= 1<<(val&0xf);
}
// update alloc count
ip->inuse--;
}
/*
#########################################################
#
# Function : intpool_inuse
#
# Purpose : return the number of values allocated
#
# Args : ip = pointer to intpool
#
##########################################################
# Edit history:
# Who When What
# AJZ 19Nov01 Created
##########################################################
*/
int intpool_inuse(intpool_t *ip)
{
return ip->inuse;
}