void beast_mm_flush() { beast_header_t *header; beast_block_t *block; void *shmaddr; beast_locker_lock(beast_mm_locker); shmaddr = beast_mm_block; header = (beast_header_t *)shmaddr; header->avail = beast_mm_block_size - sizeof(beast_header_t) - sizeof(beast_block_t) - beast_mm_alignmem(sizeof(int)); /* the free list head block node */ block = _BLOCKAT(sizeof(beast_header_t)); block->size = 0; block->next = sizeof(beast_header_t) + sizeof(beast_block_t); /* the avail block */ block = _BLOCKAT(block->next); block->size = header->avail; block->next = 0; beast_locker_unlock(beast_mm_locker); }
/* * Push cache item into cache manager, * this function return a cache item, * may be return value not equals push item, * so we must use return value. */ cache_item_t *beast_cache_push(cache_item_t *item) { int hashval = beast_cache_hash(&item->key); int index = hashval % BUCKETS_DEFAULT_SIZE; cache_item_t **this; beast_locker_lock(beast_cache_locker); this = &beast_cache_buckets[index]; while (*this) { /* this item was exists */ if (!memcmp(&(*this)->key, &item->key, sizeof(cache_key_t))) { beast_mm_free(item); item = *this; break; } this = &(*this)->next; } *this = item; beast_locker_unlock(beast_cache_locker); return item; }
int beast_cache_destroy() { int index; cache_item_t *item, *next; if (!beast_cache_initialization) { return 0; } beast_locker_lock(beast_cache_locker); for (index = 0; index < BUCKETS_DEFAULT_SIZE; index++) { item = beast_cache_buckets[index]; while (item) { next = item->next; beast_mm_free(item); item = next; } } beast_mm_free(beast_cache_buckets); beast_mm_destroy(); beast_locker_unlock(beast_cache_locker); beast_locker_destroy(beast_cache_locker); beast_cache_initialization = 0; return 0; }
void beast_mm_free(void *p) { int offset = (unsigned int)((char *)p - (char *)beast_mm_block); beast_locker_lock(beast_mm_locker); beast_mm_deallocate(beast_mm_block, offset); beast_locker_unlock(beast_mm_locker); }
void *beast_mm_malloc(int size) { int offset; void *p = NULL; beast_locker_lock(beast_mm_locker); offset = beast_mm_allocate(beast_mm_block, size); if (offset != -1) { p = (void *)(((char *)beast_mm_block) + offset); } beast_locker_unlock(beast_mm_locker); return p; }
cache_item_t *beast_cache_create(cache_key_t *key, int size) { cache_item_t *item, *next; int i, msize; msize = sizeof(*item) + size; if (msize >= beast_mm_realspace()) { return NULL; } item = beast_mm_malloc(msize); if (!item) { beast_locker_lock(beast_cache_locker); for (i = 0; i < BUCKETS_DEFAULT_SIZE; i++) { if (beast_mm_availspace() >= msize) { break; } item = beast_cache_buckets[i]; while (item) { next = item->next; beast_mm_free(item); item = next; } beast_cache_buckets[i] = NULL; } beast_locker_unlock(beast_cache_locker); item = beast_mm_malloc(msize); if (!item) { return NULL; } } item->key.device = key->device; item->key.inode = key->inode; item->key.fsize = key->fsize; item->key.mtime = key->mtime; item->next = NULL; return item; }
void beast_cache_info(zval *retval) { char key[128]; int i; cache_item_t *item; beast_locker_lock(beast_cache_locker); for (i = 0; i < BUCKETS_DEFAULT_SIZE; i++) { item = beast_cache_buckets[i]; while (item) { sprintf(key, "{device(%d)#inode(%d)}", item->key.device, item->key.inode); add_assoc_long(retval, key, item->key.fsize); item = item->next; } } beast_locker_unlock(beast_cache_locker); }
cache_item_t *beast_cache_create(cache_key_t *key, int size) { cache_item_t *item, *next; int i, msize, bsize; msize = sizeof(*item) + size; bsize = sizeof(cache_item_t *) * BUCKETS_DEFAULT_SIZE; if ((msize + bsize) > beast_mm_realspace()) { beast_write_log(beast_log_error, "Cache item size too big"); return NULL; } item = beast_mm_malloc(msize); if (!item) { int index; beast_locker_lock(beast_cache_locker); for (index = 0; index < BUCKETS_DEFAULT_SIZE; index++) { beast_cache_buckets[index] = NULL; } beast_locker_unlock(beast_cache_locker); beast_mm_flush(); /* clean all caches */ item = beast_mm_malloc(msize); if (!item) { return NULL; } } item->key.device = key->device; item->key.inode = key->inode; item->key.fsize = key->fsize; item->key.mtime = key->mtime; item->next = NULL; return item; }
/* * Push cache item into cache manager, * this function return a cache item, * may be return value not equals push item, * so we must use return value. */ cache_item_t *beast_cache_push(cache_item_t *item) { int hashval = beast_cache_hash(&item->key); int index = hashval % BUCKETS_DEFAULT_SIZE; cache_item_t **this, *self; beast_locker_lock(beast_cache_locker); /* lock */ #if 0 this = &beast_cache_buckets[index]; while (*this) { self = *this; /* the same files */ if (self->key.device == item->key.device && self->key.inode == item->key.inode) { if (self->key.mtime >= item->key.mtime) { beast_mm_free(item); beast_locker_unlock(beast_cache_locker); /* unlock */ return self; } else { /* do replace */ item->next = self->next; beast_mm_free(self); *this = item; beast_locker_unlock(beast_cache_locker); /* unlock */ return item; } } this = &self->next; } *this = item; #endif item->next = beast_cache_buckets[index]; beast_cache_buckets[index] = item; beast_locker_unlock(beast_cache_locker); /* unlock */ return item; }
cache_item_t *beast_cache_find(cache_key_t *key) { int hashval = beast_cache_hash(key); int index = hashval % BUCKETS_DEFAULT_SIZE; cache_item_t *item, *temp; beast_locker_lock(beast_cache_locker); item = beast_cache_buckets[index]; while (item) { if (item->key.device == key->device && item->key.inode == key->inode) { break; } item = item->next; } if (item && item->key.mtime < key->mtime) /* cache exprie */ { temp = beast_cache_buckets[index]; if (temp == item) { /* header */ beast_cache_buckets[index] = NULL; } else { while (temp->next != item) temp = temp->next; temp->next = item->next; } beast_mm_free(item); item = NULL; } beast_locker_unlock(beast_cache_locker); return item; }