#include <inttypes.h>
+#include "util/simple_mtx.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/list.h"
struct list_head used;
struct list_head full;
int num_free;
+ simple_mtx_t lock;
};
struct nouveau_mman {
int words, ret;
const uint32_t size = mm_default_slab_size(chunk_order);
+ simple_mtx_assert_locked(&bucket->lock);
+
words = ((size >> chunk_order) + 31) / 32;
assert(words);
assert(bucket == mm_bucket_by_order(cache, chunk_order));
list_add(&slab->head, &bucket->free);
- cache->allocated += size;
+ p_atomic_add(&cache->allocated, size);
if (nouveau_mesa_debug)
debug_printf("MM: new slab, total memory = %"PRIu64" KiB\n",
return NULL;
}
+ alloc = MALLOC_STRUCT(nouveau_mm_allocation);
+ if (!alloc)
+ return NULL;
+
+ simple_mtx_lock(&bucket->lock);
if (!list_is_empty(&bucket->used)) {
slab = list_entry(bucket->used.next, struct mm_slab, head);
} else {
*offset = mm_slab_alloc(slab) << slab->order;
- alloc = MALLOC_STRUCT(nouveau_mm_allocation);
- if (!alloc)
- return NULL;
-
nouveau_bo_ref(slab->bo, bo);
if (slab->free == 0) {
list_del(&slab->head);
list_add(&slab->head, &bucket->full);
}
+ simple_mtx_unlock(&bucket->lock);
alloc->offset = *offset;
alloc->priv = (void *)slab;
struct mm_slab *slab = (struct mm_slab *)alloc->priv;
struct mm_bucket *bucket = mm_bucket_by_order(slab->cache, slab->order);
+ simple_mtx_lock(&bucket->lock);
mm_slab_free(slab, alloc->offset >> slab->order);
if (slab->free == slab->count) {
list_del(&slab->head);
list_addtail(&slab->head, &bucket->used);
}
+ simple_mtx_unlock(&bucket->lock);
FREE(alloc);
}
list_inithead(&cache->bucket[i].free);
list_inithead(&cache->bucket[i].used);
list_inithead(&cache->bucket[i].full);
+ simple_mtx_init(&cache->bucket[i].lock, mtx_plain);
}
return cache;
nouveau_mm_free_slabs(&cache->bucket[i].free);
nouveau_mm_free_slabs(&cache->bucket[i].used);
nouveau_mm_free_slabs(&cache->bucket[i].full);
+ simple_mtx_destroy(&cache->bucket[i].lock);
}
FREE(cache);