- 论坛徽章:
- 0
|
本帖最后由 626788149 于 2015-12-08 11:37 编辑
问题已经解决。
最近一直在写操作系统,写到内存管理那块了。想实现一个SLUB分配器。
差不多实现完成了,不过出现了SMP的同步问题,还没被释放的对象可能会被分配出去,我差不多是按照linux的SLUB系统写的。
如果在SLUB分配接口加上一把大锁,同步问题就不会出现。
我一直没看懂第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)))//节点不匹配
- 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则创建新的slab*/
- new = new_slab(s, gfpflags, node);
-
- if (gfpflags & __GFP_WAIT)
- local_irq_disable();
-
- if (new) {//创建成功
- 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设置为新创建的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;
- }
复制代码 |
|