linux中的内存pipe理:实现第一次适合

我有任务,我尽我所能,但无论我尝试什么,我都无法得到最合适的scheme。 以下是代码。 为了实现最佳匹配,我对slob_page_alloc函数进行了更改。 代码如下:

 static void *slob_page_alloc(struct page *sp, size_t size, int align) { slob_t *prev, *cur, *aligned = NULL, *best_fit=NULL; /* See SLOB_UNITS defination for meaning of macro. units is required * number OF units.*/ int delta = 0, units = SLOB_UNITS(size); unsigned long frag_size = -1UL; /*Iterate throught the whole page to find best fit*/ //printk("Before the for loop\n"); printk("Starting slob_page_alloc execution\t"); for(prev=NULL, cur=sp->freelist; ; prev=cur, cur=slob_next(cur)) { slobidx_t avail = slob_units(cur); if(align) { aligned = (slob_t *)ALIGN((unsigned long)cur, align); delta = aligned - cur; } if(avail >= delta+units) { if( frag_size > avail-units ) { frag_size = avail-units; best_fit = cur; } } if(slob_last(cur)) break; } //printk("after the for loop.\n"); if(best_fit) { slobidx_t avail = slob_units(best_fit); //printk("best fit found\n"); if (align) { aligned = (slob_t *)ALIGN((unsigned long)best_fit, align); delta = aligned - best_fit; } if (avail >= units + delta) { /* room enough? */ slob_t *next; if (delta) { /* need to fragment head to align? */ next = slob_next(best_fit); /*Update the newly fragmented slob*/ set_slob(aligned, avail - delta, next); /* Update the lod slob about reduced size * and new next slob*/ set_slob(best_fit, delta, aligned); prev = best_fit; best_fit = aligned; avail = slob_units(best_fit); } next = slob_next(best_fit); if (avail == units) { /* exact fit? unlink. */ if (prev) set_slob(prev, slob_units(prev), next); else sp->freelist = next; } else { /* fragment */ if (prev) set_slob(prev, slob_units(prev), best_fit + units); else sp->freelist = best_fit + units; set_slob(best_fit + units, avail - units, next); } sp->units -= units; if (!sp->units) clear_slob_page_free(sp); printk("Returned from slob_page_alloc\t"); return best_fit; } } printk("Returned from slob_page_alloc\t"); return NULL; } 

当我用这个schemeconfiguration内核时,它只是挂在某个地方。

debugging:

我已经在这个函数的某个地方完成了打印,而且在slob_alloc函数中也完成了打印。 虽然对我来说没有任何意义,但是我的function被多次调用并成功地返回,然后再被调用并返回等等。 但是一旦被调用,就会打印这个函数内部的语句,但是不会打印来自被调用者的语句,只是无限期地挂在那里。

任何帮助表示赞赏! 谢谢。

问题是prev指针是错误的,因为当你找到best_fit的时候没有破坏,但是在slob_last(cur)上破坏。 best_fit指针是最后一个best_fit,但prev是prev的最后一个。

稍后在代码列表中修改假设prev是best_fit的prev条目。 当列表弄乱你会得到一个无尽的循环。

我认为这里没有足够的代码来弄清楚什么是错的(可能是lxr.oss.org.cn/source/mm/slob.c,但我没有检查)。 但是我猜这是你的问题:

不知何故,你在链表中得到一个循环(或“循环”),所以你对slob_last(cur)的调用永远不会返回true。 (你的代码确实到达了这一行;之前没有任何东西,缺少一个段错误,这将阻止它。)我已经添加了一个调试函数,将扫描列表,看看它是否终止或有一个循环,并打印出一个消息,如果有一个循环。 然后我在你的函数中添加了一个对这个函数的调用。 如果您之前没有听说过Bob Floyd的宠物龟和野兔,Google对Bob Floyd和链表循环检测(或链表循环检测)。 我还没有测试过我的代码,但我认为我是正确的。 如果它检测到一个循环,则查看将slob_t添加到列表的逻辑,并查看将它们从列表中移除的代码。 有一些条件,或者不适当地增加了一些名单,或者不适当地从列表中删除了某些东西。 如果你在这里找到一个循环,可以在其他位置添加额外的调用…在代码中的每一个点之前和之后立即修改列表…这样你就可以缩小代码中导致循环的部分。

 static void slob_debug_detect_loop(slob_t *list_head, const char* debug_location) { // Bob Floyd's pet tortoise & hare, both born in 1967... slot_t *hare = list_head; slob_t *tortoise = list_head; int tortoise_pacer=0; while (!slob_last(hare)) { hare = slob_next(hare); if (++tortoise_pacer&1) tortoise = slob_next(tortoise); if (tortoise_pacer>2 && hare==tortoise) { printk("LINKED LIST LOOP DETECTED at %s!\n", debug_location); return; } } } static void *slob_page_alloc(struct page *sp, size_t size, int align) { slob_t *prev, *cur, *aligned = NULL, *best_fit=NULL; /* See SLOB_UNITS defination for meaning of macro. units is required * number OF units.*/ int delta = 0, units = SLOB_UNITS(size); unsigned long frag_size = -1UL; /*Iterate throught the whole page to find best fit*/ //printk("Before the for loop\n"); printk("Starting slob_page_alloc execution\t"); slob_debug_detect_loop(sp->freelist, "before best-fit detection loop"); // ++++++++++ for(prev=NULL, cur=sp->freelist; ; prev=cur, cur=slob_next(cur)) { slobidx_t avail = slob_units(cur); if(align) { aligned = (slob_t *)ALIGN((unsigned long)cur, align); delta = aligned - cur; } if(avail >= delta+units) { if( frag_size > avail-units ) { frag_size = avail-units; best_fit = cur; } } if(slob_last(cur)) break; } . . .