Ejemplo n.º 1
0
Archivo: cache.go Proyecto: yubo/falcon
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
}