summaryrefslogtreecommitdiffstats
path: root/tiler/tiler_ptest.c
diff options
context:
space:
mode:
Diffstat (limited to 'tiler/tiler_ptest.c')
-rw-r--r--tiler/tiler_ptest.c729
1 files changed, 729 insertions, 0 deletions
diff --git a/tiler/tiler_ptest.c b/tiler/tiler_ptest.c
new file mode 100644
index 0000000..7f06940
--- /dev/null
+++ b/tiler/tiler_ptest.c
@@ -0,0 +1,729 @@
+/*
+ * tiler_ptest.c
+ *
+ * Memory Allocator Interface tests.
+ *
+ * Copyright (C) 2009-2011 Texas Instruments, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* retrieve type definitions */
+#define __DEBUG__
+#undef __DEBUG_ENTRY__
+#define __DEBUG_ASSERT__
+
+#undef __WRITE_IN_STRIDE__
+#undef STAR_TRACE_MEM
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+#include <utils.h>
+#include <list_utils.h>
+#include <debug_utils.h>
+#include <memmgr.h>
+#include <tilermem.h>
+#include <tilermem_utils.h>
+#include <testlib.h>
+
+#define FALSE 0
+
+/**
+ * Returns the default page stride for this block
+ *
+ * @author a0194118 (9/4/2009)
+ *
+ * @param width Width of 2D container
+ *
+ * @return Stride
+ */
+static bytes_t def_stride(pixels_t width)
+{
+ return (PAGE_SIZE - 1 + (bytes_t)width) & ~(PAGE_SIZE - 1);
+}
+
+/**
+ * Returns the bytes per pixel for the pixel format.
+ *
+ * @author a0194118 (9/4/2009)
+ *
+ * @param pixelFormat Pixelformat
+ *
+ * @return Bytes per pixel
+ */
+static bytes_t def_bpp(pixel_fmt_t pixelFormat)
+{
+ return (pixelFormat == PIXEL_FMT_32BIT ? 4 :
+ pixelFormat == PIXEL_FMT_16BIT ? 2 : 1);
+}
+
+enum ptr_type {
+ ptr_empty = 0,
+ ptr_alloced,
+ ptr_tiler_alloced,
+};
+
+struct ptr_info {
+ int num_blocks;
+ struct tiler_block_info blocks[TILER_MAX_NUM_BLOCKS];
+ int ptr;
+ short type;
+ uint16_t val;
+};
+
+static void dump_block(struct tiler_block_info *blk, char *prefix, char *suffix)
+{
+ switch (blk->fmt)
+ {
+ case PIXEL_FMT_PAGE:
+ P("%s [p=%p(0x%x),l=0x%x,s=%d]%s", prefix, blk->ptr, blk->ssptr,
+ blk->dim.len, blk->stride, suffix);
+ break;
+ case PIXEL_FMT_8BIT:
+ case PIXEL_FMT_16BIT:
+ case PIXEL_FMT_32BIT:
+ P("%s [p=%p(0x%x),%d*%d*%d,s=%d]%s", prefix, blk->ptr, blk->ssptr,
+ blk->dim.area.width, blk->dim.area.height, def_bpp(blk->fmt) * 8,
+ blk->stride, suffix);
+ break;
+ default:
+ P("%s*[p=%p(0x%x),l=0x%x,s=%d,fmt=0x%x]%s", prefix, blk->ptr,
+ blk->ssptr, blk->dim.len, blk->stride, blk->fmt, suffix);
+ }
+}
+
+static void dump_slot(struct ptr_info* buf, char* prefix)
+{
+ P("%sbuf={n=%d,ptr=0x%x,type=%d,", prefix, buf->num_blocks, buf->ptr,
+ buf->type);
+ int ix = 0;
+ for (ix = 0; ix < buf->num_blocks; ix++)
+ {
+ dump_block(buf->blocks + ix, "", ix + 1 == buf->num_blocks ? "}" : "");
+ }
+}
+
+/**
+ * This method fills up a range of memory using a start address
+ * and start value. The method of filling ensures that
+ * accidentally overlapping regions have minimal chances of
+ * matching, even if the same starting value is used. This is
+ * because the difference between successive values varies as
+ * such. This series only repeats after 704189 values, so the
+ * probability of a match for a range of at least 2 values is
+ * less than 2*10^-11.
+ *
+ * V(i + 1) - V(i) = { 1, 2, 3, ..., 65535, 2, 4, 6, 8 ...,
+ * 65534, 3, 6, 9, 12, ..., 4, 8, 12, 16, ... }
+ *
+ * @author a0194118 (9/6/2009)
+ *
+ * @param start start value
+ * @param block pointer to block info strucure
+ */
+void fill_mem(uint16_t start, MemAllocBlock *block)
+{
+ IN;
+ uint16_t *ptr = (uint16_t *)block->ptr, delta = 1, step = 1;
+ bytes_t height, width, stride, i;
+ if (block->pixelFormat == PIXEL_FMT_PAGE)
+ {
+ height = 1;
+ stride = width = block->dim.len;
+ }
+ else
+ {
+ height = block->dim.area.height;
+ width = block->dim.area.width;
+ stride = block->stride;
+ }
+ width *= def_bpp(block->pixelFormat);
+ bytes_t size = height * stride;
+
+ P("(%p,0x%x*0x%x,s=0x%x)=0x%x", block->ptr, width, height, stride, start);
+
+ CHK_I(width,<=,stride);
+ uint32_t *ptr32 = (uint32_t *)ptr;
+ while (height--)
+ {
+ if (block->pixelFormat == PIXEL_FMT_32BIT)
+ {
+ for (i = 0; i < width; i += sizeof(uint32_t))
+ {
+ uint32_t val = (start & 0xFFFF) | (((uint32_t)(start + delta) & 0xFFFF) << 16);
+ *ptr32++ = val;
+ start += delta;
+ delta += step;
+ /* increase step if overflown */
+ if (delta < step) delta = ++step;
+ start += delta;
+ delta += step;
+ /* increase step if overflown */
+ if (delta < step) delta = ++step;
+ }
+#ifdef __WRITE_IN_STRIDE__
+ while (i < stride && (height || ((PAGE_SIZE - 1) & (uint32_t)ptr32)))
+ {
+ *ptr32++ = 0;
+ i += sizeof(uint32_t);
+ }
+#else
+ ptr32 += (stride - i) / sizeof(uint32_t);
+#endif
+ }
+ else
+ {
+ for (i = 0; i < width; i += sizeof(uint16_t))
+ {
+ *ptr++ = start;
+ start += delta;
+ delta += step;
+ /* increase step if overflown */
+ if (delta < step) delta = ++step;
+ }
+#ifdef __WRITE_IN_STRIDE__
+ while (i < stride && (height || ((PAGE_SIZE - 1) & (uint32_t)ptr)))
+ {
+ *ptr++ = 0;
+ i += sizeof(uint16_t);
+ }
+#else
+ ptr += (stride - i) / sizeof(uint16_t);
+#endif
+
+ }
+ }
+ CHK_P((block->pixelFormat == PIXEL_FMT_32BIT ? (void *)ptr32 : (void *)ptr),==,
+ (block->ptr + size));
+ OUT;
+}
+
+/**
+ * This verifies if a range of memory at a given address was
+ * filled up using the start value.
+ *
+ * @author a0194118 (9/6/2009)
+ *
+ * @param start start value
+ * @param block pointer to block info strucure
+ *
+ * @return 0 on success, non-0 error value on failure
+ */
+int check_mem(uint16_t start, MemAllocBlock *block)
+{
+ IN;
+ uint16_t *ptr = (uint16_t *)block->ptr, delta = 1, step = 1;
+ bytes_t height, width, stride, r, i;
+ if (block->pixelFormat == PIXEL_FMT_PAGE)
+ {
+ height = 1;
+ stride = width = block->dim.len;
+ }
+ else
+ {
+ height = block->dim.area.height;
+ width = block->dim.area.width;
+ stride = block->stride;
+ }
+ width *= def_bpp(block->pixelFormat);
+
+ CHK_I(width,<=,stride);
+ uint32_t *ptr32 = (uint32_t *)ptr;
+ for (r = 0; r < height; r++)
+ {
+ if (block->pixelFormat == PIXEL_FMT_32BIT)
+ {
+ for (i = 0; i < width; i += sizeof(uint32_t))
+ {
+ uint32_t val = (start & 0xFFFF) | (((uint32_t)(start + delta) & 0xFFFF) << 16);
+ if (*ptr32++ != val) {
+ DP("assert: val[%u,%u] (=0x%x) != 0x%x", r, i, *--ptr32, val);
+ return R_I(MEMMGR_ERR_GENERIC);
+ }
+ start += delta;
+ delta += step;
+ /* increase step if overflown */
+ if (delta < step) delta = ++step;
+ start += delta;
+ delta += step;
+ /* increase step if overflown */
+ if (delta < step) delta = ++step;
+ }
+#ifdef __WRITE_IN_STRIDE__
+ while (i < stride && ((r < height - 1) || ((PAGE_SIZE - 1) & (uint32_t)ptr32)))
+ {
+ if (*ptr32++) {
+ DP("assert: val[%u,%u] (=0x%x) != 0", r, i, *--ptr32);
+ return R_I(MEMMGR_ERR_GENERIC);
+ }
+ i += sizeof(uint32_t);
+ }
+#else
+ ptr32 += (stride - i) / sizeof(uint32_t);
+#endif
+ }
+ else
+ {
+ for (i = 0; i < width; i += sizeof(uint16_t))
+ {
+ if (*ptr++ != start) {
+ DP("assert: val[%u,%u] (=0x%x) != 0x%x", r, i, *--ptr, start);
+ return R_I(MEMMGR_ERR_GENERIC);
+ }
+ start += delta;
+ delta += step;
+ /* increase step if overflown */
+ if (delta < step) delta = ++step;
+ }
+#ifdef __WRITE_IN_STRIDE__
+ while (i < stride && ((r < height - 1) || ((PAGE_SIZE - 1) & (uint32_t)ptr)))
+ {
+ if (*ptr++) {
+ DP("assert: val[%u,%u] (=0x%x) != 0", r, i, *--ptr);
+ return R_I(MEMMGR_ERR_GENERIC);
+ }
+ i += sizeof(uint16_t);
+ }
+#else
+ ptr += (stride - i) / sizeof(uint16_t);
+#endif
+ }
+ }
+ return R_I(MEMMGR_ERR_NONE);
+}
+
+/**
+ * This method allocates a tiled buffer composed of an arbitrary
+ * set of tiled blocks. If successful, it checks
+ * that the block information was updated with the pointer to
+ * the block. Additionally, it verifies the correct return
+ * values for MemMgr_IsMapped, MemMgr_Is1DBlock,
+ * MemMgr_Is2DBlock, MemMgr_GetStride, TilerMem_GetStride. It
+ * also verifies TilerMem_VirtToPhys using an internally stored
+ * value of the ssptr. If any of these verifications fail, the
+ * buffer is freed. Otherwise, it is filled using the given
+ * start value.
+ *
+ * @author a0194118 (9/7/2009)
+ *
+ * @param num_blocks Number of blocks in the buffer
+ * @param blocks Block information
+ * @param val Fill start value
+ * @param bufPtr Pointer to the allocated buffer
+ *
+ * @return 0 on success, non-0 error value on failure
+ */
+void *alloc_buf(int num_blocks, MemAllocBlock blocks[], uint16_t val)
+{
+ void *bufPtr = MemMgr_Alloc(blocks, num_blocks);
+ void *ptr = bufPtr;
+ int i;
+
+ for (i = 0; i < num_blocks; i++)
+ {
+ if (bufPtr)
+ {
+ pixel_fmt_t fmt = blocks[i].pixelFormat;
+ bytes_t cstride = (fmt == PIXEL_FMT_PAGE ? PAGE_SIZE :
+ fmt == PIXEL_FMT_8BIT ? TILER_STRIDE_8BIT :
+ fmt == PIXEL_FMT_16BIT ? TILER_STRIDE_16BIT :
+ TILER_STRIDE_32BIT);
+ if (NOT_P(blocks[i].ptr,==,ptr) ||
+ NOT_I(MemMgr_IsMapped(ptr),!=,0) ||
+ NOT_I(MemMgr_Is1DBlock(ptr),==,fmt == PIXEL_FMT_PAGE ? 1 : 0) ||
+ NOT_I(MemMgr_Is2DBlock(ptr),==,fmt == PIXEL_FMT_PAGE ? 0 : 1) ||
+ NOT_I(MemMgr_GetStride(bufPtr),==,blocks[i].stride) ||
+ NOT_P(TilerMem_VirtToPhys(ptr),==,blocks[i].reserved) ||
+ NOT_I(TilerMem_GetStride(TilerMem_VirtToPhys(ptr)),==,cstride) ||
+ NOT_L((PAGE_SIZE - 1) & (long)ptr,==,(PAGE_SIZE - 1) & blocks[i].reserved) ||
+ (fmt == PIXEL_FMT_PAGE || NOT_I(blocks[i].stride,!=,0)))
+ {
+ P(" for block %d", i);
+ MemMgr_Free(bufPtr);
+ return NULL;
+ }
+ fill_mem(val, blocks + i);
+ if (blocks[i].pixelFormat != PIXEL_FMT_PAGE)
+ {
+ ptr += def_stride(blocks[i].dim.area.width *
+ def_bpp(blocks[i].pixelFormat)) * blocks[i].dim.area.height;
+ }
+ else
+ {
+ ptr += def_stride(blocks[i].dim.len);
+ }
+ }
+ else
+ {
+ A_P(blocks[i].ptr,==,ptr);
+ A_I(blocks[i].reserved,==,0);
+ }
+ }
+ return bufPtr;
+}
+
+/**
+ * This method frees a tiled buffer composed of an arbitrary set
+ * of tiled blocks. The given start value is used to verify that
+ * the buffer is still correctly filled. In the event of any
+ * errors, the error value is returned.
+ *
+ * @author a0194118 (9/7/2009)
+ *
+ * @param num_blocks Number of blocks in the buffer
+ * @param blocks Block information
+ * @param val Fill start value
+ * @param bufPtr Pointer to the allocated buffer
+ *
+ * @return 0 on success, non-0 error value on failure
+ */
+int free_buf(int num_blocks, MemAllocBlock blocks[], uint16_t val, void *bufPtr)
+{
+ MemAllocBlock blk;
+ void *ptr = bufPtr;
+ int ret = 0, i;
+ for (i = 0; i < num_blocks; i++)
+ {
+ blk = blocks[i];
+ blk.ptr = ptr;
+ ERR_ADD(ret, check_mem(val, &blk));
+ if (blk.pixelFormat != PIXEL_FMT_PAGE)
+ {
+ ptr += def_stride(blk.dim.area.width *
+ def_bpp(blk.pixelFormat)) * blk.dim.area.height;
+ }
+ else
+ {
+ ptr += def_stride(blk.dim.len);
+ }
+ blk.reserved = 0;
+ }
+
+ ERR_ADD(ret, MemMgr_Free(bufPtr));
+ return ret;
+}
+
+#if 0
+struct slot {
+ int op;
+ SSPtr ssptr;
+ void *buffer;
+ void *dataPtr;
+} *slots = NULL;
+
+enum op_enum {
+ op_map_1d,
+ op_alloc_1d,
+ op_alloc_8,
+ op_alloc_16,
+ op_alloc_32,
+ op_alloc_nv12,
+ op_alloc_gen,
+};
+
+static int free_slot(int ix)
+{
+ if (slots[ix].bufPtr)
+ {
+ /* check memory fill */
+ switch (slots[ix].op)
+ {
+ case op_map_1d:
+ res = unmap_1D(slot[ix].dataPtr, slot[ix].length, 0, slot[ix].val, slot[ix].bufPtr);
+ FREE(mem[ix].buffer);
+ break;
+ case op_alloc_1d:
+ res = free_1D(slot[ix].length, 0, slot[ix].val, mem[ix].bufPtr);
+ break;
+ case op_alloc_8:
+ res = free_2D(slot[ix].width, slot[ix].height, PIXEL_FMT_8BIT, 0, slot[ix].val, slot[ix].bufPtr);
+ break;
+ case op_alloc_16:
+ res = free_2D(slot[ix].width, slot[ix].height, PIXEL_FMT_16BIT, 0, slot[ix].val, slot[ix].bufPtr);
+ break;
+ case op_alloc_32:
+ res = free_2D(slot[ix].width, slot[ix].height, PIXEL_FMT_32BIT, 0, slot[ix].val, slot[ix].bufPtr);
+ break;
+ case op_alloc_nv12:
+ res = free_NV12(slot[ix].width, slot[ix].height, slot[ix].val, slot[ix].bufPtr);
+ break;
+ }
+ P("%s[%p]", mem[ix].op ? "free" : "unmap", mem[ix].bufPtr);
+ ZERO(slot[ix]);
+ }
+}
+#endif
+
+#include <tilermgr.h>
+
+char *parse_num(char *p, int *tgt)
+{
+ int len;
+ if (!strncmp(p, "0x", 2)) { /* hex number */
+ if (NOT_I(sscanf(p, "0x%x%n", tgt, &len),==,1))
+ return NULL;
+ return p + len;
+ } else {
+ if (NOT_I(sscanf(p, "%d%n", tgt, &len),==,1))
+ return NULL;
+ return p + len;
+ }
+}
+
+/**
+ * Parametric memmgr test. This is similar to the star test
+ * except the operations are read from the command line:
+ *
+ * [#=]a:w*h*bits[,w*h*bits...] allocates a list of blocks as
+ * buffer # (it frees any previously allocated/mapped buffer
+ * f:# frees a buffer
+ *
+ *
+ * @author a0194118 (11/4/2009)
+ *
+ * @param argc
+ * @param argv
+ */
+int param_test(int argc, char **argv)
+{
+ int delta_slots = 16;
+ int ix, i, n, t, type, max_n, num_slots = delta_slots;
+ struct ptr_info *slots;
+ ALLOCN(slots, num_slots);
+ if (NOT_P(slots,!=,NULL)) return 1;
+
+ int res = TilerMgr_Open();
+ for (i = 1; i < argc && !res; i++)
+ {
+ uint16_t val = (uint16_t) rand();
+
+ char *p = argv[i], *q;
+ struct ptr_info buf;
+ ZERO(buf);
+
+ /* read slot */
+ ix = -1;
+ if (isdigit(*p))
+ {
+ res = 1;
+ q = parse_num(p, &ix);
+ if (NOT_P(q,!=,NULL) || NOT_I(ix,>,0)) break;
+ p = q;
+ if (NOT_I(*p++,==,'.')) break;
+ res = 0;
+ ix--;
+ }
+
+ type = *p++;
+ /* get default slot */
+ if (ix < 0)
+ {
+ switch (type)
+ {
+ /* allocation defaults to the 1st free slot */
+ case 'a':
+ case 'A':
+ for (ix = 0; ix < num_slots && slots[ix].type; ix++);
+ break;
+
+ /* frees default to the 1st used block */
+ case 'f':
+ case 'F':
+ for (ix = 0; ix < num_slots && !slots[ix].type; ix++);
+ if (NOT_I(ix,<,num_slots)) res = 1;
+ break;
+ }
+ }
+ if (res) break;
+
+ /* allocate more slots if needed */
+ if (ix >= num_slots)
+ {
+ int more_slots = ROUND_UP_TO(ix + 1, delta_slots);
+ struct ptr_info *new_slots;
+ ALLOCN(new_slots, more_slots);
+ if (NOT_P(new_slots,!=,NULL)) break;
+ memcpy(new_slots, slots, sizeof(*slots) * num_slots);
+ FREE(slots);
+ slots = new_slots;
+ num_slots = more_slots;
+ }
+
+ /* perform opertaion */
+ res = 1; /* assume failure */
+ switch (type)
+ {
+ case 'a': /* allocate */
+ case 'A': /* tiler-allocate */
+ switch (type)
+ {
+ case 'a': buf.type = ptr_alloced; max_n = TILER_MAX_NUM_BLOCKS; break;
+ case 'A': buf.type = ptr_tiler_alloced; max_n = 1; break;
+ }
+ if (ix < num_slots && NOT_I(slots[ix].type,==,ptr_empty)) break;
+ if (NOT_I(*p++,==,':')) break;
+ for (n = 0; *p && n < max_n; n++) {
+ /* read length or width */
+ p = parse_num(p, (int *) &buf.blocks[n].dim.len);
+ if (NOT_P(p,!=,NULL)) break;
+ if (*p == '*') { /* 2d block */
+ buf.blocks[n].dim.area.width = (uint16_t) buf.blocks[n].dim.len;
+ /* read height */
+ p = parse_num(++p, &t);
+ if (NOT_P(p,!=,NULL) || NOT_I(*p++,==,'*')) break;
+ buf.blocks[n].dim.area.height = (uint16_t) t;
+ /* read bits */
+ p = parse_num(p, &t);
+ if (NOT_P(p,!=,NULL)) break;
+ /* handle nv12 */
+ if (t == 12 && n + 1 < max_n) {
+ buf.blocks[n + 1].dim.area.width = buf.blocks[n].dim.area.width >> 1;
+ buf.blocks[n + 1].dim.area.height = buf.blocks[n].dim.area.height >> 1;
+ buf.blocks[n].fmt = TILFMT_8BIT;
+ t = 16;
+ n++;
+ }
+
+ buf.blocks[n].fmt = (t == 8 ? TILFMT_8BIT :
+ t == 16 ? TILFMT_16BIT :
+ t == 32 ? TILFMT_32BIT : TILFMT_INVALID);
+ if (NOT_I(buf.blocks[n].fmt,!=,TILFMT_INVALID)) break;
+ } else { /* 1d block */
+ buf.blocks[n].fmt = TILFMT_PAGE;
+ }
+ if (*p && NOT_I(*p++,==,',')) break;
+ /* we're OK */
+ res = 0;
+ }
+ if (res || *p) break;
+ /* allocate buffer */
+
+ buf.num_blocks = n;
+ buf.val = val;
+ if (buf.type == ptr_alloced)
+ {
+ dump_slot(&buf, "==(alloc)=>");
+ buf.ptr = (int) alloc_buf(n, (MemAllocBlock *) buf.blocks, val);
+ dump_slot(&buf, "<=(alloc)==");
+ }
+ else
+ {
+ dump_slot(&buf, "==(tiler_alloc)=>");
+ if (buf.blocks[0].fmt == TILFMT_PAGE)
+ {
+ buf.ptr = (int) TilerMgr_PageModeAlloc(buf.blocks[0].dim.len);
+ }
+ else
+ {
+ buf.ptr =(int) TilerMgr_Alloc(buf.blocks[0].fmt,
+ buf.blocks[0].dim.area.width,
+ buf.blocks[0].dim.area.height);
+ }
+ buf.blocks[0].ssptr = (unsigned long) buf.ptr;
+ dump_slot(&buf, "<=(tiler_alloc)==");
+ }
+ if (NOT_I(buf.ptr,!=,0)) res = 1;
+ else memcpy(slots + ix, &buf, sizeof(buf));
+ break;
+
+ case 'f': /* free */
+ case 'F': /* tiler-free */
+ memcpy(&buf, slots + ix, sizeof(buf));
+ switch (type)
+ {
+ case 'f':
+ if (NOT_I(buf.type,==,ptr_alloced)) break;
+ dump_slot(&buf, "==(free)=>");
+ res = free_buf(buf.num_blocks, (MemAllocBlock *) buf.blocks,
+ buf.val, (void *) buf.ptr);
+ P("<=(free)==: %d", res);
+ break;
+ case 'F':
+ if (NOT_I(buf.type,==,ptr_tiler_alloced)) break;
+ dump_slot(&buf, "==(tiler_free)=>");
+ if (buf.blocks[0].fmt == TILFMT_PAGE)
+ {
+ res = TilerMgr_PageModeFree((SSPtr) buf.ptr);
+ }
+ else
+ {
+ res = TilerMgr_Free((SSPtr) buf.ptr);
+ }
+ P("<=(tiler_free)==: %d", res);
+ break;
+ }
+ ZERO(slots[ix]);
+ break;
+ }
+ }
+
+ /* free any memmgr allocated blocks */
+ for (ix = 0; ix < num_slots; ix++)
+ {
+ if (slots[ix].type == ptr_alloced)
+ {
+ dump_slot(slots + ix, "==(free)=>");
+ int res_free = free_buf(slots[ix].num_blocks, (MemAllocBlock *) slots[ix].blocks,
+ slots[ix].val, (void *) slots[ix].ptr);
+ P("<=(free)==: %d", res_free);
+ ERR_ADD(res, res_free);
+ }
+ }
+ ERR_ADD(res, TilerMgr_Close());
+
+ FREE(slots);
+ return res;
+}
+
+/**
+ * Main test function. Checks arguments for test case ranges,
+ * runs tests and prints usage or test list if required.
+ *
+ * @author a0194118 (9/7/2009)
+ *
+ * @param argc Number of arguments
+ * @param argv Arguments
+ *
+ * @return -1 on usage or test list, otherwise # of failed
+ * tests.
+ */
+int main(int argc, char **argv)
+{
+ int res = param_test(argc, argv);
+ P(res ? "FAILURE: %d" : "SUCCESS", res);
+ return res;
+}
+