Home | History | Annotate | Download | only in stringloops
      1 // SPDX-License-Identifier: GPL-2.0
      2 #include <malloc.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <time.h>
      6 #include "utils.h"
      7 
      8 #define SIZE 256
      9 #define ITERATIONS 10000
     10 
     11 #define LARGE_SIZE (5 * 1024)
     12 #define LARGE_ITERATIONS 1000
     13 #define LARGE_MAX_OFFSET 32
     14 #define LARGE_SIZE_START 4096
     15 
     16 #define MAX_OFFSET_DIFF_S1_S2 48
     17 
     18 int vmx_count;
     19 int enter_vmx_ops(void)
     20 {
     21 	vmx_count++;
     22 	return 1;
     23 }
     24 
     25 void exit_vmx_ops(void)
     26 {
     27 	vmx_count--;
     28 }
     29 int test_memcmp(const void *s1, const void *s2, size_t n);
     30 
     31 /* test all offsets and lengths */
     32 static void test_one(char *s1, char *s2, unsigned long max_offset,
     33 		unsigned long size_start, unsigned long max_size)
     34 {
     35 	unsigned long offset, size;
     36 
     37 	for (offset = 0; offset < max_offset; offset++) {
     38 		for (size = size_start; size < (max_size - offset); size++) {
     39 			int x, y;
     40 			unsigned long i;
     41 
     42 			y = memcmp(s1+offset, s2+offset, size);
     43 			x = test_memcmp(s1+offset, s2+offset, size);
     44 
     45 			if (((x ^ y) < 0) &&	/* Trick to compare sign */
     46 				((x | y) != 0)) { /* check for zero */
     47 				printf("memcmp returned %d, should have returned %d (offset %ld size %ld)\n", x, y, offset, size);
     48 
     49 				for (i = offset; i < offset+size; i++)
     50 					printf("%02x ", s1[i]);
     51 				printf("\n");
     52 
     53 				for (i = offset; i < offset+size; i++)
     54 					printf("%02x ", s2[i]);
     55 				printf("\n");
     56 				abort();
     57 			}
     58 
     59 			if (vmx_count != 0) {
     60 				printf("vmx enter/exit not paired.(offset:%ld size:%ld s1:%p s2:%p vc:%d\n",
     61 					offset, size, s1, s2, vmx_count);
     62 				printf("\n");
     63 				abort();
     64 			}
     65 		}
     66 	}
     67 }
     68 
     69 static int testcase(bool islarge)
     70 {
     71 	char *s1;
     72 	char *s2;
     73 	unsigned long i;
     74 
     75 	unsigned long comp_size = (islarge ? LARGE_SIZE : SIZE);
     76 	unsigned long alloc_size = comp_size + MAX_OFFSET_DIFF_S1_S2;
     77 	int iterations = islarge ? LARGE_ITERATIONS : ITERATIONS;
     78 
     79 	s1 = memalign(128, alloc_size);
     80 	if (!s1) {
     81 		perror("memalign");
     82 		exit(1);
     83 	}
     84 
     85 	s2 = memalign(128, alloc_size);
     86 	if (!s2) {
     87 		perror("memalign");
     88 		exit(1);
     89 	}
     90 
     91 	srandom(time(0));
     92 
     93 	for (i = 0; i < iterations; i++) {
     94 		unsigned long j;
     95 		unsigned long change;
     96 		char *rand_s1 = s1;
     97 		char *rand_s2 = s2;
     98 
     99 		for (j = 0; j < alloc_size; j++)
    100 			s1[j] = random();
    101 
    102 		rand_s1 += random() % MAX_OFFSET_DIFF_S1_S2;
    103 		rand_s2 += random() % MAX_OFFSET_DIFF_S1_S2;
    104 		memcpy(rand_s2, rand_s1, comp_size);
    105 
    106 		/* change one byte */
    107 		change = random() % comp_size;
    108 		rand_s2[change] = random() & 0xff;
    109 
    110 		if (islarge)
    111 			test_one(rand_s1, rand_s2, LARGE_MAX_OFFSET,
    112 					LARGE_SIZE_START, comp_size);
    113 		else
    114 			test_one(rand_s1, rand_s2, SIZE, 0, comp_size);
    115 	}
    116 
    117 	srandom(time(0));
    118 
    119 	for (i = 0; i < iterations; i++) {
    120 		unsigned long j;
    121 		unsigned long change;
    122 		char *rand_s1 = s1;
    123 		char *rand_s2 = s2;
    124 
    125 		for (j = 0; j < alloc_size; j++)
    126 			s1[j] = random();
    127 
    128 		rand_s1 += random() % MAX_OFFSET_DIFF_S1_S2;
    129 		rand_s2 += random() % MAX_OFFSET_DIFF_S1_S2;
    130 		memcpy(rand_s2, rand_s1, comp_size);
    131 
    132 		/* change multiple bytes, 1/8 of total */
    133 		for (j = 0; j < comp_size / 8; j++) {
    134 			change = random() % comp_size;
    135 			s2[change] = random() & 0xff;
    136 		}
    137 
    138 		if (islarge)
    139 			test_one(rand_s1, rand_s2, LARGE_MAX_OFFSET,
    140 					LARGE_SIZE_START, comp_size);
    141 		else
    142 			test_one(rand_s1, rand_s2, SIZE, 0, comp_size);
    143 	}
    144 
    145 	return 0;
    146 }
    147 
    148 static int testcases(void)
    149 {
    150 	testcase(0);
    151 	testcase(1);
    152 	return 0;
    153 }
    154 
    155 int main(void)
    156 {
    157 	test_harness_set_timeout(300);
    158 	return test_harness(testcases, "memcmp");
    159 }
    160