请教帮忙分析关于位图的一个问题?

alphaxiang 2011-04-16 03:37:59
大家好,最近我看到一段代码,没怎么明白其中的原理,大家有空的请帮我看看并解释下其中的原理.
(代码来至:Linux ATM driver for Motorola MPC8260 下载地址:http://sourceforge.net/projects/atm8260/)

这段代码的功能我觉得是通过位图来记录0~N之间的数的使用情况,并提供分配(返回一个尚未被使用的数),释放(释放一个在使用中的数). 但如果功能是我分析的这样,我觉得代码可以写的更简明一些.不知道是不是我想的不对,还请大家帮我看看.

代码如下(其中intpool_init中的第二个参数log2_size二进制位宽,比如要管理的范围为0~127,则intpool_init=7):

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;
}

...全文
142 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
showjim 2011-04-16
  • 打赏
  • 举报
回复
没看代码,如果是分配(随便分配)与回收,用位图配合链表,空间复杂度是两倍位图的空间,时间复杂度O(1)

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧