Annotation of nono/vm/test_ethernet.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.