예제 #1
0
파일: cache.go 프로젝트: 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
}
예제 #2
0
파일: cache.go 프로젝트: yubo/falcon
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
}