X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=smalloc.c;h=b7502dc9616a25b0292947c51be0b4daf2022487;hb=ed4aa70764eb13c4bb36cd1b0647c26859f7bbd0;hp=0b9abad301d56ba8cb4ab7b1fb077a149c25aa6b;hpb=d24c33a479fcd68debad128da057814495f65e20;p=fio.git diff --git a/smalloc.c b/smalloc.c index 0b9abad3..b7502dc9 100644 --- a/smalloc.c +++ b/smalloc.c @@ -57,16 +57,28 @@ static inline void pool_unlock(struct pool *pool) fio_mutex_up(pool->lock); } -static inline void global_lock(void) +static inline void global_read_lock(void) { if (lock) - fio_mutex_down(lock); + fio_mutex_down_read(lock); } -static inline void global_unlock(void) +static inline void global_read_unlock(void) { if (lock) - fio_mutex_up(lock); + fio_mutex_up_read(lock); +} + +static inline void global_write_lock(void) +{ + if (lock) + fio_mutex_down_write(lock); +} + +static inline void global_write_unlock(void) +{ + if (lock) + fio_mutex_up_write(lock); } #define hdr_free(hdr) ((hdr)->size & 0x80000000) @@ -240,7 +252,9 @@ static int add_pool(struct pool *pool) pool->room = hdr->size = pool->size - sizeof(*hdr); pool->largest_block = pool->room; hdr_mark_free(hdr); + global_write_lock(); nr_pools++; + global_write_unlock(); return 0; out_unlink: if (pool->map) @@ -254,11 +268,12 @@ out_close: void sinit(void) { - int ret = add_pool(&mp[0]); + int ret; #ifdef MP_SAFE - lock = fio_mutex_init(1); + lock = fio_mutex_rw_init(); #endif + ret = add_pool(&mp[0]); assert(!ret); } @@ -314,7 +329,7 @@ void sfree(void *ptr) struct pool *pool = NULL; unsigned int i; - global_lock(); + global_read_lock(); for (i = 0; i < nr_pools; i++) { if (ptr_valid(&mp[i], ptr)) { @@ -323,7 +338,7 @@ void sfree(void *ptr) } } - global_unlock(); + global_read_unlock(); assert(pool); sfree_pool(pool, ptr); @@ -349,7 +364,7 @@ restart: do { if (combine(pool, prv, hdr)) hdr = prv; - + if (hdr_free(hdr) && hdr_size(hdr) >= size) break; @@ -418,7 +433,7 @@ void *smalloc(unsigned int size) { unsigned int i; - global_lock(); + global_read_lock(); i = last_pool; do { @@ -427,7 +442,7 @@ void *smalloc(unsigned int size) if (ptr) { last_pool = i; - global_unlock(); + global_read_unlock(); return ptr; } } @@ -440,12 +455,15 @@ void *smalloc(unsigned int size) break; else { i = nr_pools; + global_read_unlock(); if (add_pool(&mp[nr_pools])) - break; + goto out; + global_read_lock(); } } while (1); - global_unlock(); + global_read_unlock(); +out: return NULL; }