os/ossrv/genericopenlibs/liboil/src/liboiltest.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2  * LIBOIL - Library of Optimized Inner Loops
     3  * Copyright (c) 2003,2004 David A. Schleef <ds@schleef.org>
     4  * All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions
     8  * are met:
     9  * 1. Redistributions of source code must retain the above copyright
    10  *    notice, this list of conditions and the following disclaimer.
    11  * 2. Redistributions in binary form must reproduce the above copyright
    12  *    notice, this list of conditions and the following disclaimer in the
    13  *    documentation and/or other materials provided with the distribution.
    14  * 
    15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
    19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    25  * POSSIBILITY OF SUCH DAMAGE.
    26  */
    27 //Portions Copyright (c)  2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
    28 
    29 #ifdef HAVE_CONFIG_H
    30 #include <config.h>
    31 #endif
    32 
    33 #include <liboil/liboiltest.h>
    34 #include <liboil/liboildebug.h>
    35 #include <liboil/liboilrandom.h>
    36 #include <liboil/liboilprofile.h>
    37 #include <liboil/liboilfault.h>
    38 #include <stdlib.h>
    39 #include <string.h>
    40 #include <stdio.h>
    41 #include <math.h>
    42 
    43 #ifdef __SYMBIAN32__
    44 #ifdef __WINSCW__
    45 #pragma warn_unusedarg off 
    46 #endif//__WINSCW__
    47 #endif//__SYMBIAN32__
    48 
    49 #define MAX_PARAMS 20
    50 
    51 /**
    52  * SECTION:liboiltest
    53  * @title:OilTest
    54  * @short_description: Test and profile function implementations.
    55  *
    56  */
    57 static void oil_test_init_params (OilTest *test);
    58 static void fill_array (void *ptr, OilType type, int pre_n, int stride,
    59     int post_n);
    60 static double check_array (void *data, void *ref, OilType type, int pre_n,
    61     int stride, int post_n);
    62 static int check_holes (void *data, OilType type, int pre_n,
    63     int stride, int post_n, int guard);
    64 
    65 /**
    66  * oil_test_new:
    67  * @klass: an OilFunctionClass
    68  *
    69  * Creates a new OilTest for the OilFunctionClass represented by @klass.
    70  *
    71  * Returns: the new OilTest
    72  */
    73 #ifdef __SYMBIAN32__
    74 EXPORT_C
    75 #endif
    76 OilTest *
    77 oil_test_new (OilFunctionClass *klass)
    78 {
    79   OilTest *test;
    80   OilPrototype *proto;
    81   int i;
    82 
    83   if (klass == NULL) return NULL;
    84 
    85   proto = oil_prototype_from_string (klass->prototype);
    86   if (proto == NULL) return NULL;
    87 
    88   test = malloc (sizeof (OilTest));
    89   memset (test, 0, sizeof (OilTest));
    90 
    91   test->klass = klass;
    92   test->proto = proto;
    93   test->impl = klass->reference_impl;
    94   test->tolerance = 0.0;
    95 
    96   for (i=0;i<proto->n_params;i++){
    97     if (proto->params[i].parameter_type == OIL_ARG_UNKNOWN) {
    98       return NULL;
    99     }
   100     if (oil_type_is_floating_point(proto->params[i].type)) {
   101       test->tolerance = 0.001;
   102     }
   103     memcpy (&test->params[proto->params[i].parameter_type], &proto->params[i],
   104         sizeof(OilParameter));
   105   }
   106   for (i=0;i<OIL_ARG_LAST;i++){
   107     test->params[i].src_data = NULL;
   108     test->params[i].ref_data = NULL;
   109     test->params[i].test_data = NULL;
   110     test->params[i].test_header = OIL_TEST_HEADER;
   111     test->params[i].test_footer = OIL_TEST_FOOTER;
   112   }
   113 
   114   test->iterations = 10;
   115   test->n = 100;
   116   test->m = 100;
   117 
   118   return test;
   119 }
   120 
   121 /**
   122  * oil_test_free:
   123  * @test: the OilTest
   124  *
   125  * Frees memory associated with @test.
   126  */
   127  #ifdef __SYMBIAN32__
   128 EXPORT_C
   129 #endif
   130 void
   131 oil_test_free (OilTest *test)
   132 {
   133   int i;
   134 
   135   if (test->proto) {
   136     oil_prototype_free (test->proto);
   137   }
   138 
   139   for(i=0;i<OIL_ARG_LAST;i++){
   140     if (test->params[i].src_data) {
   141       free (test->params[i].src_data);
   142     }
   143     if (test->params[i].ref_data) {
   144       free (test->params[i].ref_data);
   145     }
   146     if (test->params[i].test_data) {
   147       free (test->params[i].test_data);
   148     }
   149   }
   150 
   151   free(test);
   152 }
   153 
   154 /**
   155  * oil_test_set_impl:
   156  * @test: the OilTest
   157  * @impl: an OilFunctionImpl to set
   158  *
   159  * Sets the current implementation of @test to @impl.
   160  */
   161  #ifdef __SYMBIAN32__
   162  EXPORT_C
   163 #endif
   164 void
   165 oil_test_set_impl (OilTest *test, OilFunctionImpl *impl)
   166 {
   167   test->impl = impl;
   168 }
   169 
   170 /**
   171  * oil_test_set_iterations:
   172  * @test: the OilTest
   173  * @iterations: the number of iterations
   174  *
   175  * Sets the number of iterations of @test to @iterations.
   176  */
   177  #ifdef __SYMBIAN32__
   178  EXPORT_C
   179 #endif
   180 void
   181 oil_test_set_iterations (OilTest *test, int iterations)
   182 {
   183   test->iterations = iterations;
   184 }
   185 
   186 /**
   187  * oil_test_set_test_header:
   188  * @test: the OilTest
   189  * @p: the OilParameter to change the header for
   190  * @test_header: the number of bytes of guard header
   191  *
   192  * Sets the number of bytes of guard header for @p to @test_header.
   193  */
   194  #ifdef __SYMBIAN32__
   195  EXPORT_C
   196 #endif
   197 void
   198 oil_test_set_test_header (OilTest *test, OilParameter *p, int test_header)
   199 {
   200   p->test_header = test_header;
   201 }
   202 
   203 /**
   204  * oil_test_set_test_footer:
   205  * @test: the OilTest
   206  * @p: the OilParameter to change the footer for
   207  * @test_footer: the number of bytes of guard footer
   208  *
   209  * Sets the number of bytes of guard footer for @p to @test_footer.
   210  */
   211  #ifdef __SYMBIAN32__
   212  EXPORT_C
   213 #endif
   214 void
   215 oil_test_set_test_footer (OilTest *test, OilParameter *p, int test_footer)
   216 {
   217   p->test_footer = test_footer;
   218 }
   219 
   220 /**
   221  * oil_test_init:
   222  * @test: the OilTest
   223  *
   224  * Intializes @test.
   225  * 
   226  * FIXME: needs work
   227  */
   228  #ifdef __SYMBIAN32__
   229  EXPORT_C
   230 #endif
   231 void
   232 oil_test_init (OilTest *test)
   233 {
   234   if (test->inited) {
   235     return;
   236   }
   237 
   238   oil_test_init_params(test);
   239 
   240   test->params[OIL_ARG_N].value = test->n;
   241   
   242   test->inited = 1;
   243 
   244   if (test->klass->test_func) {
   245     test->klass->test_func (test);
   246   }
   247 }
   248 
   249 #ifdef __WINSCW__
   250 #pragma suppress_warnings on 
   251 #endif//__WINSCW__
   252 #ifdef __ARMCC__
   253 #pragma diag_remark 188
   254 #endif//__ARMCC__
   255 
   256 static void
   257 oil_test_check_function (void * priv)
   258 {
   259   OilTest *test = priv;
   260   int i;
   261   int j;
   262   unsigned long args[MAX_PARAMS];
   263   unsigned int pointer_mask;
   264 
   265   oil_test_init (test);
   266 
   267   OIL_LOG("calling function %s", test->impl->name);
   268 
   269   pointer_mask = 1;
   270   for(i=0;i<test->proto->n_params;i++){
   271     OilParameter *p;
   272     j = test->proto->params[i].parameter_type;
   273     p = &test->params[j];
   274 
   275     pointer_mask <<= 1;
   276     OIL_LOG("  %s: 0x%08lx (%ld)", oil_arg_type_name (j), p->value, p->value);
   277     if (p->is_pointer) {
   278       pointer_mask |= 1;
   279       if (p->direction == 's') {
   280         args[i] = (unsigned long)p->src_data + p->test_header;
   281       } else if (p->direction == 'i') {
   282         memcpy (p->test_data, p->src_data, p->size);
   283         args[i] = (unsigned long)p->test_data + p->test_header;
   284       } else if (p->direction == 'd') {
   285         memset (p->test_data, p->guard, p->size);
   286         args[i] = (unsigned long)p->test_data + p->test_header;
   287       } else {
   288         OIL_ERROR ("not reached");
   289       }
   290     } else {
   291       args[i] = p->value;
   292     }
   293   }
   294 #ifdef __WINSCW__
   295 #pragma suppress_warnings off
   296 #endif//__WINSCW__
   297 
   298   oil_profile_init (&test->prof);
   299   for(i=0;i<test->iterations;i++){
   300     int k;
   301 
   302     for(k=0;k<test->proto->n_params;k++){
   303       OilParameter *p;
   304       j = test->proto->params[k].parameter_type;
   305       p = &test->params[j];
   306       if (p->direction == 'i') {
   307         memcpy (p->test_data, p->src_data, p->size);
   308       }
   309     }
   310     _oil_test_marshal_function (test->impl->func, args, test->proto->n_params,
   311         pointer_mask, &test->prof);
   312   }
   313 
   314   oil_profile_get_ave_std (&test->prof, &test->profile_ave,
   315       &test->profile_std);
   316 }
   317 
   318 /**
   319  * oil_test_check_ref:
   320  * @test: the OilTest
   321  *
   322  * Runs the test specified by @test on the reference function of the
   323  * class being tested.
   324  */
   325  #ifdef __SYMBIAN32__
   326  EXPORT_C
   327 #endif
   328 void
   329 oil_test_check_ref (OilTest *test)
   330 {
   331   int i;
   332 
   333   if (test->proto->n_params > MAX_PARAMS) {
   334     OIL_ERROR ("function class %s has too many parameters",
   335         test->klass->name);
   336     return;
   337   }
   338   if (test->klass->reference_impl == NULL) {
   339     OIL_ERROR ("function class %s has no reference implementation",
   340         test->klass->name);
   341     return;
   342   }
   343 
   344   test->impl = test->klass->reference_impl;
   345 
   346   oil_test_check_function (test);
   347 
   348   for(i=0;i<OIL_ARG_LAST;i++){
   349     OilParameter *p = &test->params[i];
   350 
   351     if (p->is_pointer) {
   352       if (p->direction == 'i' || p->direction == 'd') {
   353         memcpy (p->ref_data, p->test_data, p->size);
   354       }
   355     }
   356   }
   357 
   358   test->tested_ref = 1;
   359 }
   360 
   361 static int
   362 check_guard (uint8_t *data, int n, int guard)
   363 {
   364   int i;
   365   for(i=0;i<n;i++) {
   366     if (data[i] != guard) return 0;
   367   }
   368   return 1;
   369 }
   370 
   371 /**
   372  * oil_test_check_impl:
   373  * @test: the OilTest
   374  * @impl: an OilFunctionImpl
   375  *
   376  * Runs the testing procedure described by @test on the implementation
   377  * @impl.
   378  *
   379  * Returns: 1 if @impl passes the test, 0 if it fails
   380  */
   381  #ifdef __SYMBIAN32__
   382  EXPORT_C
   383 #endif
   384 int
   385 oil_test_check_impl (OilTest *test, OilFunctionImpl *impl)
   386 {
   387   double x;
   388   int i;
   389   int n;
   390   int fail = 0;
   391   int ret;
   392 
   393   if (test->proto->n_params > MAX_PARAMS) {
   394     OIL_ERROR ("function has too many parameters");
   395     return 0;
   396   }
   397 
   398   if (!test->inited || !test->tested_ref) {
   399     oil_test_check_ref(test);
   400   }
   401 
   402   test->impl = impl;
   403   ret = oil_fault_check_try (oil_test_check_function, test);
   404   if (!ret) {
   405     OIL_ERROR ("illegal instruction in %s", test->impl->name);
   406     test->profile_ave = 0;
   407     test->profile_std = 0;
   408 
   409     return 0;
   410   }
   411 
   412   x = 0;
   413   n = 0;
   414   for(i=0;i<OIL_ARG_LAST;i++){
   415     OilParameter *p = &test->params[i];
   416 
   417     if (p->is_pointer) {
   418       if (p->direction == 'i' || p->direction == 'd') {
   419         x += check_array (p->test_data + p->test_header,
   420             p->ref_data + p->test_header, p->type, p->pre_n, p->stride,
   421             p->post_n);
   422         n += p->pre_n * p->post_n;
   423         if (!check_guard (p->test_data, p->test_header, p->guard)) {
   424           fail = 1;
   425           OIL_ERROR("function %s wrote before area for parameter %s",
   426               test->impl->name, p->parameter_name);
   427         }
   428         if (!check_guard ((uint8_t *)p->test_data + p->size - p->test_footer,
   429               p->test_footer, p->guard)) {
   430           fail = 1;
   431           OIL_ERROR("function %s wrote after area for parameter %s",
   432               test->impl->name, p->parameter_name);
   433         }
   434         if (!check_holes (p->test_data, p->type, p->pre_n, p->stride,
   435               p->post_n, p->guard)) {
   436           fail = 1;
   437           OIL_ERROR("function %s wrote in interstitial area for parameter %s",
   438               test->impl->name, p->parameter_name);
   439         }
   440       }
   441     }
   442   }
   443   OIL_DEBUG("sum of absolute differences %g for %d values", x, n);
   444   test->sum_abs_diff = x;
   445   test->n_points = n;
   446 
   447   if (x > test->tolerance * n || fail) {
   448     OIL_ERROR ("function %s in class %s failed check (%g > %g) || (outside=%d)",
   449         test->impl->name, test->klass->name, x, test->tolerance * n, fail);
   450     return 0;
   451   }
   452 
   453   return 1;
   454 }
   455 
   456 /**
   457  * oil_test_cleanup
   458  * @test: the OilTest
   459  *
   460  * Cleans up @test.
   461  *
   462  * FIXME: needs work
   463  */
   464  #ifdef __SYMBIAN32__
   465  EXPORT_C
   466 #endif
   467 void
   468 oil_test_cleanup (OilTest *test)
   469 {
   470   OilParameter *params = test->params;
   471 
   472   /* src1 */
   473   if(params[OIL_ARG_SRC1].type) {
   474     if (!params[OIL_ARG_SSTR1].type) {
   475       params[OIL_ARG_SSTR1].value = oil_type_sizeof (params[OIL_ARG_SRC1].type);
   476     }
   477   }
   478 
   479   /* src2 */
   480   if(params[OIL_ARG_SRC2].type) {
   481     if (!params[OIL_ARG_SSTR2].type) {
   482       params[OIL_ARG_SSTR2].value = oil_type_sizeof (params[OIL_ARG_SRC2].type);
   483     }
   484   }
   485 
   486   /* src3 */
   487   if(params[OIL_ARG_SRC3].type) {
   488     if (!params[OIL_ARG_SSTR3].type) {
   489       params[OIL_ARG_SSTR3].value = oil_type_sizeof (params[OIL_ARG_SRC3].type);
   490     }
   491   }
   492 
   493   /* dest1 */
   494   if(params[OIL_ARG_DEST1].type) {
   495     if (!params[OIL_ARG_DSTR1].type) {
   496       params[OIL_ARG_DSTR1].value = oil_type_sizeof (params[OIL_ARG_DEST1].type);
   497     }
   498   }
   499 
   500   /* dest2 */
   501   if(params[OIL_ARG_DEST2].type) {
   502     if (!params[OIL_ARG_DSTR2].type) {
   503       params[OIL_ARG_DSTR2].value = oil_type_sizeof (params[OIL_ARG_DEST2].type);
   504     }
   505   }
   506 
   507   /* dest3 */
   508   if(params[OIL_ARG_DEST3].type) {
   509     if (!params[OIL_ARG_DSTR3].type) {
   510       params[OIL_ARG_DSTR3].value = oil_type_sizeof (params[OIL_ARG_DEST3].type);
   511     }
   512   }
   513 
   514 }
   515 
   516 
   517 static void
   518 init_parameter (OilTest *test, OilParameter *p, OilParameter *ps)
   519 {
   520   if (!p->type) return;
   521 
   522   p->pre_n = p->prestride_length;
   523   if (p->prestride_var == 1) {
   524     p->pre_n += test->n;
   525   }
   526   if (p->prestride_var == 2) {
   527     p->pre_n += test->m;
   528   }
   529 
   530   if (ps->value) {
   531     p->stride = ps->value;
   532   } else {
   533     p->stride = oil_type_sizeof (p->type) * p->pre_n;
   534     ps->value = p->stride;
   535   }
   536 
   537   p->post_n = p->poststride_length;
   538   if (p->poststride_var == 1) {
   539     p->post_n += test->n;
   540   }
   541   if (p->poststride_var == 2) {
   542     p->post_n += test->m;
   543   }
   544 
   545   p->size = p->stride * p->post_n + p->test_header + p->test_footer;
   546   p->guard = oil_rand_u8();
   547 
   548   if (p->direction == 'i' || p->direction == 's') {
   549     if (p->src_data) free (p->src_data);
   550 
   551     OIL_DEBUG("allocating %d bytes for src_data for %s", p->size, p->parameter_name);
   552     p->src_data = malloc (p->size);
   553     memset (p->src_data, p->guard, p->size);
   554     fill_array (p->src_data + p->test_header, p->type, p->pre_n, p->stride, p->post_n);
   555   }
   556 
   557   if (p->direction == 'i' || p->direction == 'd') {
   558     if (p->ref_data) free (p->ref_data);
   559     p->ref_data = malloc (p->size);
   560     memset (p->ref_data, p->guard, p->size);
   561     OIL_DEBUG("allocating %d bytes for ref_data and test_data for %s", p->size, p->parameter_name);
   562 
   563     if (p->test_data) free (p->test_data);
   564     p->test_data = malloc (p->size);
   565     memset (p->test_data, p->guard, p->size);
   566   }
   567 }
   568 
   569 static void
   570 oil_test_init_params (OilTest *test)
   571 {
   572   init_parameter (test, &test->params[OIL_ARG_DEST1],
   573       &test->params[OIL_ARG_DSTR1]);
   574   init_parameter (test, &test->params[OIL_ARG_DEST2],
   575       &test->params[OIL_ARG_DSTR2]);
   576   init_parameter (test, &test->params[OIL_ARG_DEST3],
   577       &test->params[OIL_ARG_DSTR3]);
   578 
   579   init_parameter (test, &test->params[OIL_ARG_SRC1],
   580       &test->params[OIL_ARG_SSTR1]);
   581   init_parameter (test, &test->params[OIL_ARG_SRC2],
   582       &test->params[OIL_ARG_SSTR2]);
   583   init_parameter (test, &test->params[OIL_ARG_SRC3],
   584       &test->params[OIL_ARG_SSTR3]);
   585   init_parameter (test, &test->params[OIL_ARG_SRC4],
   586       &test->params[OIL_ARG_SSTR4]);
   587   init_parameter (test, &test->params[OIL_ARG_SRC5],
   588       &test->params[OIL_ARG_SSTR5]);
   589 
   590   init_parameter (test, &test->params[OIL_ARG_INPLACE1],
   591       &test->params[OIL_ARG_ISTR1]);
   592   init_parameter (test, &test->params[OIL_ARG_INPLACE2],
   593       &test->params[OIL_ARG_ISTR2]);
   594 }
   595 
   596 static void
   597 fill_array (void *data, OilType type, int pre_n, int stride, int post_n)
   598 {
   599   int i;
   600 
   601 #define FILL(type,func) do {\
   602   for(i=0;i<post_n;i++){ \
   603     func (OIL_OFFSET(data, i*stride), pre_n); \
   604   } \
   605 }while(0)
   606 
   607   switch (type) {
   608     case OIL_TYPE_s8p:
   609       FILL(int8_t,oil_random_s8);
   610       break;
   611     case OIL_TYPE_u8p:
   612       FILL(uint8_t,oil_random_u8);
   613       break;
   614     case OIL_TYPE_s16p:
   615       FILL(int16_t,oil_random_s16);
   616       break;
   617     case OIL_TYPE_u16p:
   618       FILL(uint16_t,oil_random_u16);
   619       break;
   620     case OIL_TYPE_s32p:
   621       FILL(int32_t,oil_random_s32);
   622       break;
   623     case OIL_TYPE_u32p:
   624       FILL(uint32_t,oil_random_u32);
   625       break;
   626     case OIL_TYPE_s64p:
   627       FILL(int64_t,oil_random_s64);
   628       break;
   629     case OIL_TYPE_u64p:
   630       FILL(uint64_t,oil_random_u64);
   631       break;
   632     case OIL_TYPE_f32p:
   633       FILL(float,oil_random_f32);
   634       break;
   635     case OIL_TYPE_f64p:
   636       FILL(double,oil_random_f64);
   637       break;
   638     default:
   639       OIL_ERROR ("should not be reached (type == %d)", type);
   640       return;
   641       break;
   642   }
   643 }
   644 
   645 static double
   646 check_array (void *data, void *ref, OilType type, int pre_n, int stride, int post_n)
   647 {
   648   int i;
   649   int j;
   650   int s2 = oil_type_sizeof (type);
   651   double x = 0;
   652 
   653 #if 0
   654   OIL_ERROR ("check array pre_n=%d stride=%d post_n=%d",
   655       pre_n, stride, post_n);
   656 #endif
   657 
   658 #define CHECK(type) do {\
   659   for(i=0;i<post_n;i++){ \
   660     for(j=0;j<pre_n;j++){ \
   661       x += fabs((double)OIL_GET(data, i*stride + j*s2, type) - \
   662           (double)OIL_GET(ref, i*stride + j*s2, type)); \
   663     } \
   664   } \
   665 }while(0)
   666 
   667   switch (type) {
   668     case OIL_TYPE_s8p:
   669       CHECK(int8_t);
   670       break;
   671     case OIL_TYPE_u8p:
   672       CHECK(uint8_t);
   673       break;
   674     case OIL_TYPE_s16p:
   675       CHECK(int16_t);
   676       break;
   677     case OIL_TYPE_u16p:
   678       CHECK(uint16_t);
   679       break;
   680     case OIL_TYPE_s32p:
   681       CHECK(int32_t);
   682       break;
   683     case OIL_TYPE_u32p:
   684       CHECK(uint32_t);
   685       break;
   686     case OIL_TYPE_s64p:
   687       CHECK(int64_t);
   688       break;
   689     case OIL_TYPE_u64p:
   690       CHECK(uint64_t);
   691       break;
   692     case OIL_TYPE_f32p:
   693       CHECK(float);
   694       break;
   695     case OIL_TYPE_f64p:
   696       CHECK(double);
   697       break;
   698     default:
   699       OIL_ERROR ("should not be reached (type == %d)", type);
   700       return 1e9;
   701       break;
   702   }
   703   return x;
   704 }
   705 
   706 static int
   707 check_holes (void *data, OilType type, int pre_n, int stride, int post_n,
   708     int guard)
   709 {
   710   int i;
   711   int chunk_size;
   712   int hole_size;
   713 
   714   chunk_size = pre_n * oil_type_sizeof (type);
   715   hole_size = stride - chunk_size;
   716   if (hole_size == 0) {
   717     return 1;
   718   }
   719 
   720   for(i=0;i<post_n;i++){
   721     if (!check_guard (OIL_OFFSET(data, stride * i + chunk_size),
   722         hole_size, guard)) {
   723       return 0;
   724     }
   725   }
   726 
   727   return 1;
   728 }
   729 
   730 #ifdef __SYMBIAN32__
   731  EXPORT_C
   732 #endif
   733 void *
   734 oil_test_get_source_data (OilTest *test, OilArgType arg_type)
   735 {
   736   uint8_t *ptr;
   737  
   738   ptr = test->params[arg_type].src_data;
   739   ptr += test->params[arg_type].test_header;
   740 
   741   return ptr;
   742 }
   743 
   744 #ifdef __SYMBIAN32__
   745  EXPORT_C
   746 #endif
   747 int
   748 oil_test_get_arg_pre_n (OilTest *test, OilArgType arg_type)
   749 {
   750   return test->params[arg_type].pre_n;
   751 }
   752 
   753 #ifdef __SYMBIAN32__
   754  EXPORT_C
   755 #endif
   756 int
   757 oil_test_get_arg_post_n (OilTest *test, OilArgType arg_type)
   758 {
   759   return test->params[arg_type].post_n;
   760 }
   761 
   762 #ifdef __SYMBIAN32__
   763  EXPORT_C
   764 #endif
   765 int
   766 oil_test_get_arg_stride (OilTest *test, OilArgType arg_type)
   767 {
   768   return test->params[arg_type].stride;
   769 }
   770 
   771 #ifdef __SYMBIAN32__
   772  EXPORT_C
   773 #endif
   774 int
   775 oil_test_get_value (OilTest *test, OilArgType arg_type)
   776 {
   777   return test->params[arg_type].value;
   778 }