Linux¶ÔI/O¶Ë¿Ú×ÊÔ´µÄ¹ÜÀí(1)

¡¶Linux¶ÔI/O¶Ë¿Ú×ÊÔ´µÄ¹ÜÀí(1)¡·ÕªÒª£º ¢Û×îºó¸ù¾ÝconflictÊÇ·ñΪNULL£¬·µ»Ø£­EBUSY»ò0Öµ¡£ 3£®2£®4 ѰÕÒ¿ÉÓÃ×ÊÔ´ º¯Êýfind_resource()ÓÃÓÚÔÚÒ»¿Å×ÊÔ´Ê÷ÖÐѰÕÒδ±»Ê¹Óõġ¢ÇÒÂú×ã¸ø¶¨Ìõ¼þµÄ£¨Ò²¼´×ÊÔ´³¤¶È´óСΪsize£¬ÇÒÔÚ[min,max]Ç¡­

¢Û×îºó¸ù¾ÝconflictÊÇ·ñΪNULL£¬·µ»Ø£­EBUSY»ò0Öµ¡£

3£®2£®4 ѰÕÒ¿ÉÓÃ×ÊÔ´

º¯Êýfind_resource()ÓÃÓÚÔÚÒ»¿Å×ÊÔ´Ê÷ÖÐѰÕÒδ±»Ê¹Óõġ¢ÇÒÂú×ã¸ø¶¨Ìõ¼þµÄ£¨Ò²¼´×ÊÔ´³¤¶È´óСΪsize£¬ÇÒÔÚ[min,max]Çø¼äÄÚ£©µÄ×ÊÔ´¡£Æäº¯ÊýÔ´´úÂëÈçÏ£º

/*

* Find empty slot in the resource tree given range and alignment.

*/

static int find_resource(struct resource *root, struct resource *new,

unsigned long size,

unsigned long min, unsigned long max,

unsigned long align,

void (*alignf)(void *, struct resource *, unsigned long),

void *alignf_data)

{

struct resource *this = root->child;

new->start = root->start;

for(;;) {

if (this)

new->end = this->start;

else

new->end = root->end;

if (new->start < min)

new->start = min;

if (new->end > max)

new->end = max;

new->start = (new->start + align - 1) & ~(align - 1);

if (alignf)

alignf(alignf_data, new, size);

if (new->start < new->end && new->end - new->start + 1 >= size)

{

new->end = new->start + size - 1;

return 0;

}

if (!this)

break;

new->start = this->end + 1;

this = this->sibling;

}

return -EBUSY;

}

¶Ô¸Ãº¯ÊýµÄNOTEÈçÏ£º

ͬÑù£¬¸Ãº¯ÊýÒ²Òª±éÀúrootµÄchildÁ´±í£¬ÒÔѰÕÒδ±»Ê¹ÓõÄ×ÊÔ´¿Õ¶´¡£Îª´Ë£¬ËüÈÃthisÖ¸Õë±íʾµ±Ç°Õý±»É¨ÃèµÄ×Ó×ÊÔ´½Úµã£¬Æä³õʼֵµÈÓÚroot->child£¬¼´Ö¸ÏòchildÁ´±íÖеĵÚÒ»¸ö½Úµã£¬²¢ÈÃnew->startµÄ³õʼֵµÈÓÚroot->start£¬È»ºóÓÃÒ»¸öforÑ­»·¿ªÊ¼É¨ÃèchildÁ´±í£¬¶ÔÓÚÿһ¸ö±»É¨ÃèµÄ½Úµã£¬Ñ­»·ÌåÖ´ÐÐÈçϲÙ×÷£º

¢ÙÊ×ÏÈ£¬ÅжÏthisÖ¸ÕëÊÇ·ñΪNULL¡£Èç¹û²»Îª¿Õ£¬¾ÍÈÃnew->endµÈÓÚthis->start£¬Ò²¼´ÈÃ×ÊÔ´new±íʾµ±Ç°×ÊÔ´½ÚµãthisÇ°ÃæÄÇÒ»¶ÎδʹÓõÄ×ÊÔ´Çø¼ä¡£

ÄãµÄλÖ㺵çÄÔ¹ÊÕÏÍø >> ²Ù×÷ϵͳ >> Linux/Unix >> Linux¶ÔI/O¶Ë¿Ú×ÊÔ´µÄ¹ÜÀí(1)