- 論壇徽章:
- 0
|
本帖最后由 626788149 于 2015-12-08 11:37 編輯
問題已經(jīng)解決。
最近一直在寫操作系統(tǒng),寫到內存管理那塊了。想實現(xiàn)一個SLUB分配器。
差不多實現(xiàn)完成了,不過出現(xiàn)了SMP的同步問題,還沒被釋放的對象可能會被分配出去,我差不多是按照linux的SLUB系統(tǒng)寫的。
如果在SLUB分配接口加上一把大鎖,同步問題就不會出現(xiàn)。
我一直沒看懂第27行。
c->page->inuse = c->page->objects;
可能同步問題跟inuse這個值有關。
誰能告訴我c->page->inuse = c->page->objects; 這行是啥意思?- static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- unsigned long addr, struct kmem_cache_cpu *c)
- {
- void **object;
- struct page *new;
-
- /* We handle __GFP_ZERO in the caller */
- gfpflags &= ~__GFP_ZERO;
-
- if (!c->page)/*本地CPU的slab結構中沒有存儲可分配的內存,則要為其尋找新的slab*/
- goto new_slab;
-
- slab_lock(c->page);
- if (unlikely(!node_match(c, node)))//節(jié)點不匹配
- goto another_slab;
-
- stat(c, ALLOC_REFILL);
-
- load_freelist:
- object = c->page->freelist;//獲取一個對象
- if (unlikely(!object))
- goto another_slab;
- if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
- goto debug;
-
- c->freelist = object[c->offset]; //更新freelist
- c->page->inuse = c->page->objects;
- /*一旦slab從partial slab鏈表轉移到本地CPU,則page_freelist不再負責維護空閑對象了,
- 因此設為NULL*/
- c->page->freelist = NULL;
- c->node = page_to_nid(c->page);
- unlock_out:
- slab_unlock(c->page);
- stat(c, ALLOC_SLOWPATH);
- return object; //返回對象
-
- another_slab:
- deactivate_slab(s, c);//將本地CPU的slab移回partial slab鏈表
-
- new_slab:
- /*從partial slab鏈表中尋找一個slab*/
- new = get_partial(s, gfpflags, node);
- if (new) {/*獲取成功則直接將該slab交給本地CPU*/
- c->page = new;
- stat(c, ALLOC_FROM_PARTIAL);
- goto load_freelist;
- }
-
- if (gfpflags & __GFP_WAIT)
- local_irq_enable();
-
- /*如果partial slab鏈表中已無法獲取slab則創(chuàng)建新的slab*/
- new = new_slab(s, gfpflags, node);
-
- if (gfpflags & __GFP_WAIT)
- local_irq_disable();
-
- if (new) {//創(chuàng)建成功
- c = get_cpu_slab(s, smp_processor_id());//獲取本地CPU的slab信息結構
- stat(c, ALLOC_SLAB);
- if (c->page)//本地CPU中存在slab,則移除該slab
- flush_slab(s, c);
- slab_lock(new);
- __SetPageSlubFrozen(new);//凍結slab,表明slab處于本地CPU中
- c->page = new;//本地CPU中的slab設置為新創(chuàng)建的slab
- goto load_freelist;
- }
- if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
- slab_out_of_memory(s, gfpflags, node);
- return NULL;
- debug:
- if (!alloc_debug_processing(s, c->page, object, addr))
- goto another_slab;
-
- c->page->inuse++;
- c->page->freelist = object[c->offset];
- c->node = -1;
- goto unlock_out;
- }
復制代碼 |
|