X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=smalloc.c;h=fc6ac526c33d95cac6c88f2bfe371f724f0d426c;hp=8eb0f2a03740faa63c8e3b0b5681bd6ecaa3ec87;hb=443bb114d963a99082eef916025268a5a107092b;hpb=3f1959101ed6a935ff3e2aec0fe7f5828f23fbcb diff --git a/smalloc.c b/smalloc.c index 8eb0f2a0..fc6ac526 100644 --- a/smalloc.c +++ b/smalloc.c @@ -11,9 +11,10 @@ #include #include +#include "mutex.h" #include "arch/arch.h" -#include "spinlock.h" +#define MP_SAFE /* define to make thread safe */ #define SMALLOC_REDZONE /* define to detect memory corruption */ #define SMALLOC_BPB 32 /* block size, bytes-per-bit in bitmap */ @@ -21,7 +22,7 @@ #define SMALLOC_BPL (SMALLOC_BPB * SMALLOC_BPI) #define INITIAL_SIZE 1024*1024 /* new pool size */ -#define MAX_POOLS 4 /* maximum number of pools to setup */ +#define MAX_POOLS 128 /* maximum number of pools to setup */ #define SMALLOC_PRE_RED 0xdeadbeefU #define SMALLOC_POST_RED 0x5aa55aa5U @@ -29,7 +30,7 @@ unsigned int smalloc_pool_size = INITIAL_SIZE; struct pool { - struct fio_spinlock *lock; + struct fio_mutex *lock; /* protects this pool */ void *map; /* map of blocks */ unsigned int *bitmap; /* blocks free/busy map */ unsigned int free_blocks; /* free blocks */ @@ -50,36 +51,42 @@ struct block_hdr { static struct pool mp[MAX_POOLS]; static unsigned int nr_pools; static unsigned int last_pool; -static struct fio_spinlock *slock; +static struct fio_mutex *lock; static inline void pool_lock(struct pool *pool) { - fio_spin_lock(pool->lock); + if (pool->lock) + fio_mutex_down(pool->lock); } static inline void pool_unlock(struct pool *pool) { - fio_spin_unlock(pool->lock); + if (pool->lock) + fio_mutex_up(pool->lock); } static inline void global_read_lock(void) { - fio_spin_lock(slock); + if (lock) + fio_mutex_down_read(lock); } static inline void global_read_unlock(void) { - fio_spin_unlock(slock); + if (lock) + fio_mutex_up_read(lock); } static inline void global_write_lock(void) { - fio_spin_lock(slock); + if (lock) + fio_mutex_down_write(lock); } static inline void global_write_unlock(void) { - fio_spin_unlock(slock); + if (lock) + fio_mutex_up_write(lock); } static inline int ptr_valid(struct pool *pool, void *ptr) @@ -211,15 +218,21 @@ static int add_pool(struct pool *pool, unsigned int alloc_size) pool->map = ptr; pool->bitmap = (void *) ptr + (pool->nr_blocks * SMALLOC_BPL); - pool->lock = fio_spinlock_init(); +#ifdef MP_SAFE + pool->lock = fio_mutex_init(1); if (!pool->lock) goto out_unlink; +#endif + /* + * Unlink pool file now. It wont get deleted until the fd is closed, + * which happens both for cleanup or unexpected quit. This way we + * don't leave temp files around in case of a crash. + */ pool->fd = fd; + unlink(pool->file); - global_write_lock(); nr_pools++; - global_write_unlock(); return 0; out_unlink: fprintf(stderr, "smalloc: failed adding pool\n"); @@ -236,18 +249,24 @@ void sinit(void) { int ret; - slock = fio_spinlock_init(); - assert(slock); +#ifdef MP_SAFE + lock = fio_mutex_rw_init(); +#endif ret = add_pool(&mp[0], INITIAL_SIZE); assert(!ret); } static void cleanup_pool(struct pool *pool) { - unlink(pool->file); + /* + * This will also remove the temporary file we used as a backing + * store, it was already unlinked + */ close(pool->fd); munmap(pool->map, pool->mmap_size); - fio_spinlock_remove(pool->lock); + + if (pool->lock) + fio_mutex_remove(pool->lock); } void scleanup(void) @@ -257,7 +276,8 @@ void scleanup(void) for (i = 0; i < nr_pools; i++) cleanup_pool(&mp[i]); - fio_spinlock_remove(slock); + if (lock) + fio_mutex_remove(lock); } #ifdef SMALLOC_REDZONE @@ -429,7 +449,7 @@ void *smalloc(unsigned int size) { unsigned int i; - global_read_lock(); + global_write_lock(); i = last_pool; do { @@ -438,7 +458,7 @@ void *smalloc(unsigned int size) if (ptr) { last_pool = i; - global_read_unlock(); + global_write_unlock(); return ptr; } } @@ -451,15 +471,13 @@ void *smalloc(unsigned int size) break; else { i = nr_pools; - global_read_unlock(); if (add_pool(&mp[nr_pools], size)) goto out; - global_read_lock(); } } while (1); - global_read_unlock(); out: + global_write_unlock(); return NULL; }