func (p *Backend) allocPool() (err error) { var ( shmid int size int addr uintptr block *C.struct_cache_block cache *backendCache ) cache = p.cache cache.Lock() defer cache.Unlock() shmid, size, err = Shmget(cache.endkey, p.ShmSize, C.IPC_CREAT|0700) if err != nil { glog.Errorf(MODULE_NAME+"shmget(%d, %d, ipc_create ) err %s", cache.endkey, p.ShmSize, err) return err } cache.endkey++ if size != p.ShmSize { glog.Errorf(MODULE_NAME+"alloc shm size %d want %d, remove and try again", size, p.ShmSize) cleanBlocks(cache.endkey) shmid, _, err = Shmget(cache.endkey, p.ShmSize, C.IPC_CREAT|0700) if err != nil { glog.Errorf(MODULE_NAME+"shmget(%d, %d, ipc_create ) err %s", cache.endkey, p.ShmSize, err) return err } } addr, err = Shmat(shmid, 0, 0) if err != nil { glog.Errorf(MODULE_NAME+"shmat(%d, 0, 0 ) err %s", shmid, err) return err } block = (*C.struct_cache_block)(unsafe.Pointer(addr)) if uint32(block.magic) == p.ShmMagic { Shmdt(addr) glog.Errorf(MODULE_NAME+"magic head already set at shmid %d", shmid) return specs.ErrExist } glog.V(5).Infof(MODULE_NAME+"alloc shm segment, endkey 0x%08x shmid %d len(shmaddr) %d", cache.endkey, shmid, len(cache.shmaddrs)) cache.shmaddrs = append(cache.shmaddrs, addr) cache.shmids = append(cache.shmids, shmid) block.magic = C.uint32_t(p.ShmMagic) block.block_size = C.int(p.ShmSize) block.cache_entry_nb = C.int(cache.cache_entry_nb) list := &cache.poolq list.Lock() defer list.Unlock() for i := 0; i < int(block.cache_entry_nb); i++ { e := &cacheEntry{ e: (*C.struct_cache_entry)(unsafe.Pointer(addr + uintptr(C.sizeof_struct_cache_block) + uintptr(i*C.sizeof_struct_cache_entry))), } list.head.AddTail(&e.list_data) } //list.size += int(block.cache_entry_nb) //fmt.Printf("poolq.size %d \n", list.size) return nil }
func (p *Backend) importBlocks() (int, error) { var ( shmid int size int addr uintptr block *C.struct_cache_block err error cache *backendCache ) cache = p.cache cache.Lock() defer cache.Unlock() for { shmid, size, err = Shmget(cache.endkey, p.ShmSize, C.IPC_CREAT|0700) if err != nil { return cache.endkey - cache.startkey, err } cache.endkey++ if size != p.ShmSize { glog.Errorf(MODULE_NAME+"segment size error, remove "+ "segment from 0x%x and retry", cache.endkey) cleanBlocks(cache.endkey) return cache.endkey - cache.startkey, err } addr, err = Shmat(shmid, 0, 0) if err != nil { return cache.endkey - cache.startkey, err } block = (*C.struct_cache_block)(unsafe.Pointer(addr)) for uint32(block.magic) != p.ShmMagic { glog.Infof(MODULE_NAME+"set magic head at 0x%x", shmid) block.magic = C.uint32_t(p.ShmMagic) return cache.endkey - cache.startkey, specs.EFMT } cache.shmaddrs = append(cache.shmaddrs, addr) cache.shmids = append(cache.shmids, shmid) list := &cache.poolq for i := 0; i < int(block.cache_entry_nb); i++ { e := &cacheEntry{ e: (*C.struct_cache_entry)(unsafe.Pointer(addr + uintptr(C.sizeof_struct_cache_block) + uintptr(i*C.sizeof_struct_cache_entry))), } key := e.hashkey() if key == "" { // add to pool list.head.AddTail(&e.list_data) } else { // restore to cacheEntry cache.hash[key] = e cache.dataq.enqueue(&e.list_data) cache.idx0q.enqueue(&e.list_idx) } } } return cache.endkey - cache.startkey, nil }