Path: blob/21.2-virgl/src/intel/vulkan/tests/block_pool_no_free.c
4547 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <pthread.h>2425#include "anv_private.h"26#include "test_common.h"2728#define NUM_THREADS 1629#define BLOCKS_PER_THREAD 102430#define NUM_RUNS 643132struct job {33pthread_t thread;34unsigned id;35struct anv_block_pool *pool;36int32_t blocks[BLOCKS_PER_THREAD];37int32_t back_blocks[BLOCKS_PER_THREAD];38} jobs[NUM_THREADS];394041static void *alloc_blocks(void *_job)42{43struct job *job = _job;44uint32_t job_id = job - jobs;45uint32_t block_size = 16 * ((job_id % 4) + 1);46int32_t block, *data;4748for (unsigned i = 0; i < BLOCKS_PER_THREAD; i++) {49block = anv_block_pool_alloc(job->pool, block_size, NULL);50data = anv_block_pool_map(job->pool, block, block_size);51*data = block;52ASSERT(block >= 0);53job->blocks[i] = block;5455block = anv_block_pool_alloc_back(job->pool, block_size);56data = anv_block_pool_map(job->pool, block, block_size);57*data = block;58ASSERT(block < 0);59job->back_blocks[i] = -block;60}6162for (unsigned i = 0; i < BLOCKS_PER_THREAD; i++) {63block = job->blocks[i];64data = anv_block_pool_map(job->pool, block, block_size);65ASSERT(*data == block);6667block = -job->back_blocks[i];68data = anv_block_pool_map(job->pool, block, block_size);69ASSERT(*data == block);70}7172return NULL;73}7475static void validate_monotonic(int32_t **blocks)76{77/* A list of indices, one per thread */78unsigned next[NUM_THREADS];79memset(next, 0, sizeof(next));8081int highest = -1;82while (true) {83/* First, we find which thread has the lowest next element */84int32_t thread_min = INT32_MAX;85int min_thread_idx = -1;86for (unsigned i = 0; i < NUM_THREADS; i++) {87if (next[i] >= BLOCKS_PER_THREAD)88continue;8990if (thread_min > blocks[i][next[i]]) {91thread_min = blocks[i][next[i]];92min_thread_idx = i;93}94}9596/* The only way this can happen is if all of the next[] values are at97* BLOCKS_PER_THREAD, in which case, we're done.98*/99if (thread_min == INT32_MAX)100break;101102/* That next element had better be higher than the previous highest */103ASSERT(blocks[min_thread_idx][next[min_thread_idx]] > highest);104105highest = blocks[min_thread_idx][next[min_thread_idx]];106next[min_thread_idx]++;107}108}109110static void run_test()111{112struct anv_physical_device physical_device = { };113struct anv_device device = {114.physical = &physical_device,115};116struct anv_block_pool pool;117118pthread_mutex_init(&device.mutex, NULL);119anv_bo_cache_init(&device.bo_cache);120anv_block_pool_init(&pool, &device, "test", 4096, 4096);121122for (unsigned i = 0; i < NUM_THREADS; i++) {123jobs[i].pool = &pool;124jobs[i].id = i;125pthread_create(&jobs[i].thread, NULL, alloc_blocks, &jobs[i]);126}127128for (unsigned i = 0; i < NUM_THREADS; i++)129pthread_join(jobs[i].thread, NULL);130131/* Validate that the block allocations were monotonic */132int32_t *block_ptrs[NUM_THREADS];133for (unsigned i = 0; i < NUM_THREADS; i++)134block_ptrs[i] = jobs[i].blocks;135validate_monotonic(block_ptrs);136137/* Validate that the back block allocations were monotonic */138for (unsigned i = 0; i < NUM_THREADS; i++)139block_ptrs[i] = jobs[i].back_blocks;140validate_monotonic(block_ptrs);141142anv_block_pool_finish(&pool);143pthread_mutex_destroy(&device.mutex);144}145146int main(void)147{148for (unsigned i = 0; i < NUM_RUNS; i++)149run_test();150}151152153