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

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: 
1.1.1.3 ! root      113:        uint64 usec = nsec_to_usec(sw.Elapsed_nsec());
1.1       root      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: 
1.1.1.2   root      126:        memset(buf, 0, sizeof(buf));
1.1       root      127:        start_perf_func("macaddr.old");
                    128:        while (perf_signaled == 0) {
                    129:                volatile uint32 crc;
                    130:                crc = EthernetDevice::CRC32(buf, sizeof(buf));
                    131:                perf_count++;
                    132:                u32 = crc;
                    133:        }
                    134:        end_perf_func();
                    135: }
                    136: 
                    137: // ターゲット長がMACアドレスで CRC32(mac)。
                    138: static void
                    139: do_perf_mac_new()
                    140: {
                    141:        union {
                    142:                uint8 buf[6];
                    143:                uint32 u32;
                    144:        };
                    145: 
1.1.1.2   root      146:        memset(buf, 0, sizeof(buf));
1.1       root      147:        MacAddr mac(buf);
                    148:        start_perf_func("macaddr.new");
                    149:        while (perf_signaled == 0) {
                    150:                volatile uint32 crc;
                    151:                crc = EthernetDevice::CRC32(mac);
                    152:                perf_count++;
                    153:                u32 = crc;
                    154:        }
                    155:        end_perf_func();
                    156: }
                    157: 
                    158: // ターゲット長が1500バイトの場合。
                    159: static void
                    160: do_perf_buf()
                    161: {
                    162:        union {
                    163:                uint8 buf[1500];
                    164:                uint32 u32;
                    165:        };
                    166: 
1.1.1.2   root      167:        memset(buf, 0, sizeof(buf));
1.1       root      168:        start_perf_func("1500bytes");
                    169:        while (perf_signaled == 0) {
                    170:                uint32 crc;
                    171:                crc = EthernetDevice::CRC32(buf, sizeof(buf));
                    172:                perf_count++;
                    173:                u32 = crc;
                    174:        }
                    175:        end_perf_func();
                    176: }
                    177: 
                    178: int
                    179: main(int ac, char *av[])
                    180: {
                    181:        do_test(0);
                    182:        do_test(1);
                    183:        do_perf_buf();
                    184:        do_perf_mac_old();
                    185:        do_perf_mac_new();
                    186:        return 0;
                    187: }

unix.superglobalmegacorp.com

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