|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // EthernetDevice::CRC32() のテスト。 ! 8: ! 9: #include "header.h" ! 10: #include "bitops.h" ! 11: #include "macaddr.h" ! 12: #include "stopwatch.h" ! 13: #include <signal.h> ! 14: #include <sys/time.h> ! 15: ! 16: // パフォーマンステストの秒数 ! 17: #define PERF_SEC (2) ! 18: ! 19: class EthernetDevice ! 20: { ! 21: public: ! 22: static uint32 CRC32(const uint8 *buf, size_t buflen); ! 23: static uint32 CRC32(const MacAddr& mac); ! 24: }; ! 25: ! 26: #define SELFTEST ! 27: #include "ethernet.cpp" ! 28: ! 29: // testnum は 0 が通常の CRC、1 が MAC アドレス用 CRC。 ! 30: static void ! 31: do_test(int testnum) ! 32: { ! 33: struct { ! 34: uint8 src[6]; ! 35: uint32 expected; ! 36: } table[] = { ! 37: { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x3a7abc72 }, ! 38: { { 0x33, 0x33, 0x00, 0x00, 0x00, 0x01 }, 0xf99baaba }, ! 39: }; ! 40: int failed = 0; ! 41: ! 42: if (testnum == 0) { ! 43: printf("Test(buf)"); ! 44: } else { ! 45: printf("Test(mac)"); ! 46: } ! 47: ! 48: for (size_t i = 0; i < countof(table); i++) { ! 49: const uint8 *src = table[i].src; ! 50: uint32 expected = table[i].expected; ! 51: uint32 actual; ! 52: if (testnum == 0) { ! 53: actual = EthernetDevice::CRC32(src, 6); ! 54: } else { ! 55: MacAddr mac(src); ! 56: actual = EthernetDevice::CRC32(mac); ! 57: } ! 58: ! 59: if (actual != expected) { ! 60: if (failed == 0) { ! 61: printf("\n"); ! 62: } ! 63: printf("FAILED: %02x%02x%02x%02x%02x%02x expects %08x but got %08x", ! 64: src[0], src[1], src[2], src[3], src[4], src[5], ! 65: expected, actual); ! 66: ! 67: // 念のため反転して一致するか。 ! 68: uint32 revact = bitrev32(actual); ! 69: if (revact == expected) { ! 70: printf(" (bit-reversed)"); ! 71: } ! 72: ! 73: printf(" !\n"); ! 74: failed++; ! 75: } ! 76: } ! 77: if (failed == 0) { ! 78: printf("..OK\n"); ! 79: } ! 80: } ! 81: ! 82: static volatile uint32 perf_signaled; ! 83: static uint64 perf_count; ! 84: static Stopwatch sw; ! 85: ! 86: static void ! 87: signal_alarm(int signo) ! 88: { ! 89: perf_signaled = 1; ! 90: } ! 91: ! 92: static void ! 93: start_perf_func(const char *name) ! 94: { ! 95: printf("%s\t... ", name); ! 96: fflush(stdout); ! 97: ! 98: perf_count = 0; ! 99: perf_signaled = 0; ! 100: signal(SIGALRM, signal_alarm); ! 101: struct itimerval it = {}; ! 102: it.it_value.tv_sec = PERF_SEC; ! 103: ! 104: sw.Restart(); ! 105: setitimer(ITIMER_REAL, &it, NULL); ! 106: } ! 107: ! 108: static void ! 109: end_perf_func() ! 110: { ! 111: sw.Stop(); ! 112: ! 113: uint64 usec = sw.Elapsed() / 1000; ! 114: printf("%6.2f times/usec\n", (double)perf_count / usec); ! 115: } ! 116: ! 117: // ターゲット長がMACアドレスで従来の CRC32(buf)。 ! 118: static void ! 119: do_perf_mac_old() ! 120: { ! 121: union { ! 122: uint8 buf[6]; ! 123: uint32 u32; ! 124: }; ! 125: ! 126: memset(&buf, 0, sizeof(buf)); ! 127: MacAddr mac(buf); ! 128: start_perf_func("macaddr.old"); ! 129: while (perf_signaled == 0) { ! 130: volatile uint32 crc; ! 131: crc = EthernetDevice::CRC32(buf, sizeof(buf)); ! 132: perf_count++; ! 133: u32 = crc; ! 134: } ! 135: end_perf_func(); ! 136: } ! 137: ! 138: // ターゲット長がMACアドレスで CRC32(mac)。 ! 139: static void ! 140: do_perf_mac_new() ! 141: { ! 142: union { ! 143: uint8 buf[6]; ! 144: uint32 u32; ! 145: }; ! 146: ! 147: memset(&buf, 0, sizeof(buf)); ! 148: MacAddr mac(buf); ! 149: start_perf_func("macaddr.new"); ! 150: while (perf_signaled == 0) { ! 151: volatile uint32 crc; ! 152: crc = EthernetDevice::CRC32(mac); ! 153: perf_count++; ! 154: u32 = crc; ! 155: } ! 156: end_perf_func(); ! 157: } ! 158: ! 159: // ターゲット長が1500バイトの場合。 ! 160: static void ! 161: do_perf_buf() ! 162: { ! 163: union { ! 164: uint8 buf[1500]; ! 165: uint32 u32; ! 166: }; ! 167: ! 168: memset(&buf, 0, sizeof(buf)); ! 169: start_perf_func("1500bytes"); ! 170: while (perf_signaled == 0) { ! 171: uint32 crc; ! 172: crc = EthernetDevice::CRC32(buf, sizeof(buf)); ! 173: perf_count++; ! 174: u32 = crc; ! 175: } ! 176: end_perf_func(); ! 177: } ! 178: ! 179: int ! 180: main(int ac, char *av[]) ! 181: { ! 182: do_test(0); ! 183: do_test(1); ! 184: do_perf_buf(); ! 185: do_perf_mac_old(); ! 186: do_perf_mac_new(); ! 187: return 0; ! 188: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.