memtest.cpp revision 3cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * you may not use this file except in compliance with the License.
6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * You may obtain a copy of the License at
7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * See the License for the specific language governing permissions and
14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * limitations under the License.
15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h>
18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h>
19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h>
20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/time.h>
21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <time.h>
22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h>
23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sched.h>
24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/resource.h>
25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/syscall.h>
26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/types.h>
27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/mman.h>
28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectconst int DCACHE_SIZE = 8*1024;
31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectconst int CPU_FREQ_EST = 195;
32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectconst int BRANCH_CYCLE = 3;
33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#else
34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectconst int DCACHE_SIZE  = 32*1024;
35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectconst int CPU_FREQ_EST = 384;
36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectconst int BRANCH_CYCLE = 2;
37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
39b4950a59dcd4fa7fa4adaec6c8429388c2640291Mathias Agopian//extern "C" void* xmemcpy(void*, void*, size_t);
40b4950a59dcd4fa7fa4adaec6c8429388c2640291Mathias Agopian#define MEMCPY  memcpy
41b4950a59dcd4fa7fa4adaec6c8429388c2640291Mathias Agopian
42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projecttypedef long long nsecs_t;
43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic nsecs_t system_time()
45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    struct timespec t;
47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    t.tv_sec = t.tv_nsec = 0;
48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    clock_gettime(CLOCK_MONOTONIC, &t);
49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectnsecs_t loop_overhead(size_t count) __attribute__((noinline));
533cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Samsnsecs_t loop_overhead(size_t count)
54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    nsecs_t overhead = -system_time();
56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    do {
57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        asm volatile ("":::"memory");
58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } while (--count);
59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    overhead += system_time();
60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return overhead;
613cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams}
62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void preload(volatile char* addr, size_t s)
64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (size_t i=0 ; i<s ; i+=32) {
66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        char c = addr[i];
673cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams        (void)c;
68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
70e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
71e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void usage(char* p) {
72e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf( "Usage: %s <test> <options>\n"
73e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "<test> is one of the following:\n"
74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       cpufreq\n"
75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       memcpy [perf [fast] | test]\n"
76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       memset [perf | test]\n"
77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       memcmp [perf | test]\n"
78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       strlen [perf | test]\n"
79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       malloc [fill]\n"
80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       madvise\n"
81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       resampler\n"
82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       crash\n"
83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       stack (stack smasher)\n"
84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "       crawl\n"
85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            , p);
86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint cpufreq_test(int argc, char** argv);
89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint memcpy_test(int argc, char** argv);
90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint memset_test(int argc, char** argv);
91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint memcmp_test(int argc, char** argv);
92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint strlen_test(int argc, char** argv);
93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint malloc_test(int argc, char** argv);
94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint madvise_test(int argc, char** argv);
95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint crash_test(int argc, char** argv);
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint stack_smasher_test(int argc, char** argv);
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint crawl_test(int argc, char** argv);
983cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Samsint fp_test(int argc, char** argv);
99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark main
103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char** argv)
106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (argc == 1) {
108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage(argv[0]);
109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return 0;
110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int err = -1;
112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if      (!strcmp(argv[1], "cpufreq"))   err = cpufreq_test(argc-1, argv+1);
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "memcpy"))    err = memcpy_test(argc-1, argv+1);
114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "memset"))    err = memset_test(argc-1, argv+1);
115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "memcmp"))    err = memcmp_test(argc-1, argv+1);
116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "strlen"))    err = strlen_test(argc-1, argv+1);
117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "malloc"))    err = malloc_test(argc-1, argv+1);
118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "madvise"))   err = madvise_test(argc-1, argv+1);
119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "crash"))     err = crash_test(argc-1, argv+1);
120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "stack"))     err = stack_smasher_test(argc-1, argv+1);
121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    else if (!strcmp(argv[1], "crawl"))     err = crawl_test(argc-1, argv+1);
1223cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    else if (!strcmp(argv[1], "fp"))     err = fp_test(argc-1, argv+1);
123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (err) {
124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage(argv[0]);
125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark memcpy
132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint validate_memcpy(char* s, char* d, size_t size);
135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint validate_memset(char* s, char c, size_t size);
136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint memcpy_test(int argc, char** argv)
138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int option = 0;
140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (argc >= 2) {
141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!strcmp(argv[1], "perf"))       option = 0;
142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else if (!strcmp(argv[1], "test"))  option = 1;
143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else                                return -1;
144e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
146e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int MAX_SIZE = 1024*1024; // 1MB
147e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int CACHED_SPEED_EST = CPU_FREQ_EST*1024*1024; // 150 MB/s
1483cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    const int UNCACHED_SPEED_EST = (CPU_FREQ_EST/4)*1024*1024; // 60 MB/s
149e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char* src = (char*)malloc(MAX_SIZE+4+8+32);
150e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char* dst = (char*)malloc(MAX_SIZE+4+8+32);
151e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memset(src, 0, MAX_SIZE+4+8+32);
152e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memset(dst, 0, MAX_SIZE+4+8+32);
1533cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
154e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (option == 0) {
155e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        bool fast = (argc>=3 && !strcmp(argv[2], "fast"));
156e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("memcpy() performance test is running, please wait...\n");
157e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
158e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usleep(10000);
159e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        setpriority(PRIO_PROCESS, 0, -20);
160e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        static int FAST_SIZES[] = { 1024, DCACHE_SIZE/2, DCACHE_SIZE, DCACHE_SIZE*2, MAX_SIZE };
161e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
162e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        struct result_t { int size; float res; };
163e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        result_t* results = (result_t*)src;
164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nbr = 0;
165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int size = 0;
166e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; ; i++) {
167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (!fast) {
168e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                if (size<128)          size += 8;
1693cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams                else if (size<1024)    size += 128;
170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                else if (size<16384)   size += 1024;
171e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                else                   size <<= 1;
172e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            } else {
173e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                if (size_t(i) >= sizeof(FAST_SIZES)/sizeof(FAST_SIZES[0]))
174e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    break;
175e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                size = FAST_SIZES[i];
176e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
177e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size > MAX_SIZE) {
178e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
179e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
180e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
181e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const int REPEAT = (((size < DCACHE_SIZE) ?
182e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                        (CACHED_SPEED_EST) : (UNCACHED_SPEED_EST)) / size) / 2;
183e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                // ~0.5 second per test
184e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
185e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const nsecs_t overhead = loop_overhead(REPEAT);
1863cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
187e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            // tweak to make it a bad case
188e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char* ddd = (char*)((long(dst+31)&~31) + 4);
189e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char* sss = (char*)((long(src+31)&~31) + 28);
1903cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
191e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int offset=0 ; offset<=2 ; offset +=2 ) {
192e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                memcpy(dst, src, size); // just make sure to load the caches I/D
193e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nsecs_t t = -system_time();
194e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                register int count = REPEAT;
195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                do {
196b4950a59dcd4fa7fa4adaec6c8429388c2640291Mathias Agopian                    MEMCPY(ddd, sss+offset, size);
197e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                } while (--count);
198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                t += system_time() - overhead;
199e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                const float throughput = (size*1000000000.0f*REPEAT) / (1024*1024*t);
200e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].size = size;
201e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].res = throughput;
202e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nbr++;
203e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
204e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
205e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
206e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%9s %9s %9s\n", "size", "MB/s", "MB/s (nc)");
207e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; i<nbr ; i+=2) {
208e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("%9d %9ld %9ld\n", results[i].size, (long)results[i].res, (long)results[i+1].res);
209e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } else if (option == 1) {
211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("memcpy() validation test is running, please wait...\n");
212e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
213e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        char* curr = (char*)src;
214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; i<MAX_SIZE ; i++) {
215e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char c = rand();
216e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            *curr++ = c != 0x55 ? c : 0xAA;
217e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
218e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        char* s = src + 1024;
219e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        char* d = dst + 1024;
220e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nb = 0;
221e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int size=0 ; size<4096 && !nb ; size++) {
222e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            nb += validate_memcpy(s, d, size);
223e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int o=1 ; o<32 && !nb ; o++) {
224e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nb += validate_memcpy(s+o, d, size);
225e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nb += validate_memcpy(s, d+o, size);
226e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nb += validate_memcpy(s+o, d+o, size);
227e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
228e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
229e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (nb) printf("%d error(s) found\n", nb);
230e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else    printf("success!\n");
231e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
2323cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    fflush(stdout);
233e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(dst);
234e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(src);
235e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
236e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
237e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
238e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint validate_memcpy(char* s, char* d, size_t size)
239e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
240e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int nberr = 0;
241e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memset(d-4, 0x55, size+8);
242b4950a59dcd4fa7fa4adaec6c8429388c2640291Mathias Agopian    MEMCPY(s, d, size);
243e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (memcmp(s,d,size)) {
244e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("*** memcpy(%p,%p,%lu) destination != source\n",s,d,size);
245e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        nberr++;
246e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
247e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    bool r = (d[size]==0x55)&&(d[size+1]==0x55)&&(d[size+2]==0x55)&&(d[size+3]==0x55);
248e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!r) {
249e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("*** memcpy(%p,%p,%lu) clobbered past end of destination!\n",s,d,size);
250e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        nberr++;
251e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
252e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    r = (d[-1]==0x55)&&(d[-2]==0x55)&&(d[-3]==0x55)&&(d[-4]==0x55);
253e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!r) {
254e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("*** memcpy(%p,%p,%lu) clobbered before start of destination!\n",s,d,size);
255e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        nberr++;
256e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
257e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return nberr;
258e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
259e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
260e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
262e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
263e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark memset
264e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
265e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
266e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint memset_test(int argc, char** argv)
267e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
268e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int option = 0;
269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (argc >= 2) {
270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!strcmp(argv[1], "perf"))       option = 0;
271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else if (!strcmp(argv[1], "test"))  option = 1;
272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else                                return -1;
273e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
275e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int MAX_SIZE = 1024*1024; // 1MB
276e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int CACHED_SPEED_EST = CPU_FREQ_EST*1024*1024; // 195 MB/s
2773cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    const int UNCACHED_SPEED_EST = CPU_FREQ_EST*1024*1024; // 195 MB/s
278e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char* dst = (char*)malloc(MAX_SIZE+4+8);
2793cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
280e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (option == 0) {
281e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("memset() performance test is running, please wait...\n");
282e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
283e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usleep(10000);
284e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        setpriority(PRIO_PROCESS, 0, -20);
285e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
286e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        static int FAST_SIZES[] = { 1024, DCACHE_SIZE/2, DCACHE_SIZE, DCACHE_SIZE*2, MAX_SIZE };
287e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        const size_t FAST_SIZES_COUNT = sizeof(FAST_SIZES)/sizeof(FAST_SIZES[0]);
288e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        struct result_t { int size; float res; };
289e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        result_t results[FAST_SIZES_COUNT*2];
290e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nbr = 0;
291e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int size = 0;
292e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; ; i++) {
293e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size_t(i) >= sizeof(FAST_SIZES)/sizeof(FAST_SIZES[0]))
294e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
295e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            size = FAST_SIZES[i];
296e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size > MAX_SIZE) {
297e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
298e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
299e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const int REPEAT = (((size < DCACHE_SIZE) ?
300e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                        (CACHED_SPEED_EST) : (UNCACHED_SPEED_EST)) / size);
301e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                // ~0.5 second per test
302e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
303e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const nsecs_t overhead = loop_overhead(REPEAT);
304e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
305e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int j=0 ; j<2 ; j++) {
306e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                if (j==0)   preload(dst, DCACHE_SIZE*4);   // flush D
307e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                else        preload(dst, size);            // load D
308e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nsecs_t t = -system_time();
309e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                size_t count = REPEAT;
310e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                do {
311e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    memset(dst, 0, size);
312e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                } while (--count);
313e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                t += system_time() - overhead;
314e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
315e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                const float throughput = (size*1000000000.0f*REPEAT) / (1024*1024*t);
316e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].size = size;
317e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].res = throughput;
318e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nbr++;
319e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
320e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
3213cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
322e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%9s %9s %9s\n", "size", "MB/s", "MB/s (cached)");
323e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; i<nbr ; i+=2) {
324e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("%9d %9ld %9ld\n", results[i].size, (long)results[i].res, (long)results[i+1].res);
325e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
326e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } else if (option == 1) {
327e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("memset() validation test is running, please wait...\n");
328e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
329e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        char* d = dst + 1024;
330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nb = 0;
331e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int o=1 ; o<32 ; o++) {
332e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int size=0 ; size<4096 && !nb ; size++) {
333e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nb += validate_memset(d, char(o), size);
334e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nb += validate_memset(d+o, char(o), size);
335e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
336e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
337e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (nb) printf("%d error(s) found\n", nb);
338e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else    printf("success!\n");
339e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
3403cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    fflush(stdout);
341e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(dst);
342e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
343e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
344e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
345e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint validate_memset(char* d, char c, size_t size)
346e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
347e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int nberr = 0;
348e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (size_t i=0; i<size ; d[i++]=0xaa) ;
349e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    d[-1] = 0x55;
350e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    d[size+1] = 0x55;
351e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memset(d, c, size);
352e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (d[size+1]!=0x55) {
353e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("*** memset(%p,%02x,%lu) clobbered past end of destination!\n",d,(int)c,size);
354e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        nberr++;
355e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
356e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (d[-1]!=0x55) {
357e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("*** memset(%p,%02x,%lu) clobbered before start of destination!\n",d,(int)c,size);
358e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        nberr++;
359e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
360e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (size_t i=0 ; i<size ; i++) {
361e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (d[i] != c) {
362e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("*** memset(%p,%02x,%lu) failed at offset %lu\n",d,(int)c,size, i);
363e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            nberr++;
364e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            break;
365e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
366e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
367e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return nberr;
368e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
369e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
370e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
371e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
372e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark memcmp
373e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
374e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
375e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int ref_memcmp(const void *s1, const void *s2, size_t n)
376e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
377e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project  const unsigned char *c1 = (const unsigned char *)s1, *c2 = (const unsigned char *)s2;
378e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project  int d = 0;
379e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
380e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project  while ( n-- ) {
381e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    d = (int)*c1++ - (int)*c2++;
382e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if ( d )
383e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project      break;
384e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project  }
385e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
38648b40fefa1cd8b5371cb468dfcd79369a137566fBruce Beare  return (d < 0 ? -1 : (d > 0 ? 1 : 0));
387e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
388e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
389e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint validate_memcmp(const char* s, const char* d, size_t size)
390e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
391e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
392e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int a = ref_memcmp(s, d, size);
393e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int b = memcmp(s, d, size);
39448b40fefa1cd8b5371cb468dfcd79369a137566fBruce Beare    b = (b < 0 ? -1 : (b > 0 ? 1 : 0));
395e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    //printf("%d, %d\n", a, b);
396e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (a != b) {
397e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("*** memcmp(%p,%p,%lu) failed %d should be %d\n",s,d,size,b,a);
398e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return 1;
399e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
400e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
401e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
402e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
403e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint memcmp_test(int argc, char** argv)
404e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
405e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int option = 0;
406e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (argc >= 2) {
407e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!strcmp(argv[1], "perf"))       option = 0;
408e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else if (!strcmp(argv[1], "test"))  option = 1;
409e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else                                return -1;
410e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
411e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
412e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int MAX_SIZE = 1024*1024; // 1MB
413e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int CACHED_SPEED_EST = CPU_FREQ_EST*1024*1024; // 150 MB/s
4143cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    const int UNCACHED_SPEED_EST = (CPU_FREQ_EST/4)*1024*1024; // 60 MB/s
415e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char* src = (char*)malloc(MAX_SIZE+4+8+32);
416e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char* dst = (char*)malloc(MAX_SIZE+4+8+32);
417e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
418e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (option == 0) {
419e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("memcmp() performance test is running, please wait...\n");
420e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
421e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usleep(10000);
422e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        setpriority(PRIO_PROCESS, 0, -20);
423e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
424e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        static int FAST_SIZES[] = { 1024, DCACHE_SIZE/2, DCACHE_SIZE, DCACHE_SIZE*2, MAX_SIZE };
425e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
426e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        struct result_t { int size; float res; };
427e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        result_t* results = (result_t*)src;
428e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nbr = 0;
429e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int size = 0;
430e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; ; i++) {
431e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size_t(i) >= sizeof(FAST_SIZES)/sizeof(FAST_SIZES[0]))
432e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
433e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            size = FAST_SIZES[i];
434e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size > MAX_SIZE) {
435e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
436e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
437e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
438e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const int REPEAT = (((size < DCACHE_SIZE) ?
439e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                        (CACHED_SPEED_EST) : (UNCACHED_SPEED_EST)) / size) / 2;
440e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                // ~0.5 second per test
441e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
442e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const nsecs_t overhead = loop_overhead(REPEAT);
4433cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
444e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            // tweak to make it a bad case
445e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char* ddd = (char*)((long(dst+31)&~31) + 4);
446e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char* sss = (char*)((long(src+31)&~31) + 28);
4473cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
448e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int offset=0 ; offset<=2 ; offset +=2 ) {
449e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                memcpy(ddd, sss+offset, size); // just make sure to load the caches I/D
450e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nsecs_t t = -system_time();
451e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                register int count = REPEAT;
452e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                char c;
453e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                c = memcmp(ddd, sss+offset, size);
454e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                //printf("size %d, memcmp -> %d\n", size, (int)c);
455e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                do {
456e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    c = memcmp(ddd, sss+offset, size);
457e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    asm volatile (""::"r"(c):"memory");
458e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                } while (--count);
459e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                t += system_time() - overhead;
460e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                const float throughput = (size*1000000000.0f*REPEAT) / (1024*1024*t);
461e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].size = size;
462e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].res = throughput;
463e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nbr++;
464e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
465e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
4663cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
467e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%9s %9s %9s\n", "size", "MB/s", "MB/s (nc)");
468e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; i<nbr ; i+=2) {
469e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("%9d %9ld %9ld\n", results[i].size, (long)results[i].res, (long)results[i+1].res);
470e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
471e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } else {
472e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("memcmp() validation test is running, please wait...\n");
473e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
474e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
475e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        const char* const s = (const char*)src + 1024;
476e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        const char* const d = (const char*)dst + 1024;
477e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nb = 0;
478e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int j=0 ; j<32 ; j++) {
479e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
480e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char *curr0 = (char*)src;
481e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            char *curr1 = (char*)dst;
482e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int i=0 ; i<MAX_SIZE ; i++) {
483e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                char c = rand();
484e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                *curr0++ = c;
485e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                *curr1++ = c;
486e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
487e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (j) {
488e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                src[1024 + j] ^= 0xFF;
489e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
490e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
491e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
492e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int size=0 ; size<32 && !nb ; size++) {
493e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                for (int o=0 ; o<4 ; o++) {
494e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    nb += validate_memcmp(s+o, d+o, size);
495e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                }
496e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project               // memmove((char*)d+1, d, size);
497e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                for (int o=0 ; o<4 ; o++) {
498e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    nb += validate_memcmp(s, d+o, size);
499e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                }
500e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
501e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
502e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (nb) printf("%d error(s) found\n", nb);
503e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else    printf("success!\n");
504e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
5053cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    fflush(stdout);
506e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(dst);
507e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(src);
508e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
509e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
510e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
511e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
512e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
513e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark strlen
514e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
515e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
516e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint strlen_test(int argc, char** argv)
517e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
518e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int option = 0;
519e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (argc >= 2) {
520e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!strcmp(argv[1], "perf"))       option = 0;
521e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else if (!strcmp(argv[1], "test"))  option = 1;
522e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        else                                return -1;
523e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
524e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
525e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int MAX_SIZE = 1024*1024; // 1MB
526e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int CACHED_SPEED_EST = CPU_FREQ_EST*1024*1024; // 195 MB/s
5273cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    const int UNCACHED_SPEED_EST = CPU_FREQ_EST*1024*1024; // 195 MB/s
528e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char* str = (char*)calloc(MAX_SIZE+4+8, 1);
5293cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
530e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (option == 0) {
531e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("strlen() performance test is running, please wait...\n");
532e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fflush(stdout);
533e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usleep(10000);
534e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        setpriority(PRIO_PROCESS, 0, -20);
535e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
536e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        static int FAST_SIZES[] = { 1024, DCACHE_SIZE/2, DCACHE_SIZE, DCACHE_SIZE*2, MAX_SIZE };
537e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        const size_t FAST_SIZES_COUNT = sizeof(FAST_SIZES)/sizeof(FAST_SIZES[0]);
538e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        struct result_t { int size; float res; };
539e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        result_t results[FAST_SIZES_COUNT*2];
540e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int nbr = 0;
541e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        int size = 0;
542e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; ; i++) {
543e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size_t(i) >= sizeof(FAST_SIZES)/sizeof(FAST_SIZES[0]))
544e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
545e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            size = FAST_SIZES[i];
546e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (size > MAX_SIZE) {
547e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                break;
548e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
549e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const int REPEAT = (((size < DCACHE_SIZE) ?
550e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                        (CACHED_SPEED_EST) : (UNCACHED_SPEED_EST)) / size);
551e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                // ~0.5 second per test
552e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
553e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            const nsecs_t overhead = loop_overhead(REPEAT);
554e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
555e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            for (int j=0 ; j<2 ; j++) {
556e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                memset(str, 'A', size-1);
557e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                if (j==0)   preload(str, DCACHE_SIZE*4);   // flush D
558e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                else        preload(str, size);            // load D
559e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
560e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nsecs_t t = -system_time();
561e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                size_t count = REPEAT;
562e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                int c=0;
563e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                do {
564e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    c = strlen(str);
565e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    asm volatile (""::"r"(c):"memory");
566e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                } while (--count);
567e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                t += system_time() - overhead;
568e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
569e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                const float throughput = (size*1000000000.0f*REPEAT) / (1024*1024*t);
570e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].size = size;
571e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                results[nbr].res = throughput;
572e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                nbr++;
573e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
574e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
5753cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
576e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%9s %9s %9s\n", "size", "MB/s", "MB/s (cached)");
577e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        for (int i=0 ; i<nbr ; i+=2) {
578e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("%9d %9ld %9ld\n", results[i].size, (long)results[i].res, (long)results[i+1].res);
579e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
580e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
581e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
5823cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    fflush(stdout);
583e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(str);
584e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
585e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
586e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
587e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
588e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
589e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
590e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark malloc
591e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
592e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
593e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint malloc_test(int argc, char** argv)
594e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
595e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    bool fill = (argc>=2 && !strcmp(argv[1], "fill"));
596e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t total = 0;
597e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t size = 0x40000000;
598e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    while (size) {
599e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        void* addr = malloc(size);
600e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (addr == 0) {
601e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("size = %9lu failed\n", size);
602e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            size >>= 1;
603e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        } else {
604e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            total += size;
605e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("size = %9lu, addr = %p (total = %9lu (%lu MB))\n",
606e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                    size, addr, total, total / (1024*1024));
607e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            if (fill) {
608e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                printf("filling...\n");
609e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                fflush(stdout);
610e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                memset(addr, 0, size);
611e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
612e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            size = size + size>>1;
613e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
614e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
615e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("done. allocated %lu MB\n", total / (1024*1024));
616e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
617e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
618e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
619e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
620e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
621e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark madvise
622e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
623e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
624e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint madvise_test(int argc, char** argv)
625e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
626e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (int i=0 ; i<2 ; i++) {
627e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        size_t size = i==0 ? 4096 : 48*1024*1024; // 48 MB
628e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("Allocating %lu MB... ", size/(1024*1024)); fflush(stdout);
629e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        void* addr1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
630e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%p (%s)\n", addr1, addr1==(void*)-1 ? "failed" : "OK"); fflush(stdout);
631e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
632e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("touching %p...\n", addr1); fflush(stdout);
633e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        memset(addr1, 0x55, size);
634e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
635e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("advising DONTNEED...\n"); fflush(stdout);
636e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        madvise(addr1, size, MADV_DONTNEED);
637e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
638e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("reading back %p...\n", addr1); fflush(stdout);
639e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (*(long*)addr1 == 0) {
640e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("madvise freed some pages\n");
641e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        } else if (*(long*)addr1 == 0x55555555) {
642e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("pages are still there\n");
643e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        } else {
644e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("getting garbage back\n");
645e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
646e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
647e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("Allocating %lu MB... ", size/(1024*1024)); fflush(stdout);
648e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        void* addr2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
649e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%p (%s)\n", addr2, addr2==(void*)-1 ? "failed" : "OK"); fflush(stdout);
650e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
651e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("touching %p...\n", addr2); fflush(stdout);
652e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        memset(addr2, 0xAA, size);
653e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
654e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("unmap %p ...\n", addr2); fflush(stdout);
655e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        munmap(addr2, size);
656e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
657e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("touching %p...\n", addr1); fflush(stdout);
658e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        memset(addr1, 0x55, size);
659e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
660e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("unmap %p ...\n", addr1); fflush(stdout);
661e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        munmap(addr1, size);
662e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
663e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
664e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("Done\n"); fflush(stdout);
665e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
666e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
667e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
668e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
669e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
670e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark cpufreq
671e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
672e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
673e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint cpufreq_test(int argc, char** argv)
674e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
675e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    struct timespec res;
676e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    clock_getres(CLOCK_REALTIME, &res);
677e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("CLOCK_REALTIME  resolution: %lu ns\n", res.tv_nsec);
678e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    clock_getres(CLOCK_MONOTONIC, &res);
679e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("CLOCK_MONOTONIC resolution: %lu ns\n", res.tv_nsec);
680e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    clock_getres(CLOCK_PROCESS_CPUTIME_ID, &res);
681e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("CLOCK_PROCESS_CPUTIME_ID resolution: %lu ns\n", res.tv_nsec);
682e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    clock_getres(CLOCK_THREAD_CPUTIME_ID, &res);
683e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("CLOCK_THREAD_CPUTIME_ID  resolution: %lu ns\n", res.tv_nsec);
684e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
685e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (clock_getres(CLOCK_REALTIME_HR, &res) != 0)
686e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("CLOCK_REALTIME_HR   resolution: %lu ns\n", res.tv_nsec);
6873cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    else
688e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("CLOCK_REALTIME_HR   not supported\n");
6893cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams
690e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (clock_getres(CLOCK_MONOTONIC_HR, &res) != 0)
691e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("CLOCK_MONOTONIC_HR  resolution: %lu ns\n", res.tv_nsec);
6923cadc3a6df0b13deabb1b3423aafa5ff8bbfdf23Jason Sams    else
693e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("CLOCK_MONOTONIC_HR  not supported\n");
694e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
695e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("\nEstimating the CPU frequency, please wait...\n");
696e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    fflush(stdout);
697e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    usleep(10000);
698e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    setpriority(PRIO_PROCESS, 0, -20);
699e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
700e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const int LOOP_CYCLES = 1+BRANCH_CYCLE; // 1 cycle + 3 cycles for the branch
701e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const size_t REPEAT = CPU_FREQ_EST*1000000;   // ~4 seconds (4cycles/loop)
702e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    register size_t count = REPEAT;
703e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    nsecs_t t = system_time();
704e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    do { // this loop generates 1+3 cycles
705e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        asm volatile ("":::"memory");
706e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } while (--count);
707e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    t = system_time() - t;
708e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    const float freq = t ? (1000.0f*float(REPEAT)*LOOP_CYCLES) / t : 0;
709e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("this CPU frequency: %ld MHz\n", long(freq+0.5f));
710e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
711e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
712e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
713e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#if 0
714e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark -
715e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#pragma mark crash_test
716e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#endif
717e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
718e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint crash_test(int argc, char** argv)
719e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
720e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("about to crash...\n");
721e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    asm volatile(
722e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        "mov r0,  #0 \n"
723e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        "mov r1,  #1 \n"
724e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        "mov r2,  #2 \n"
725e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        "mov r3,  #3 \n"
726e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        "ldr r12, [r0] \n"
727e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    );
728e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
729e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
730e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
731e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
732e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint stack_smasher_test(int argc, char** argv)
733e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
734e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int dummy = 0;
735e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("corrupting our stack...\n");
736e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    *(volatile long long*)&dummy = 0;
737e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
738e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
739e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
740e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// --------------------------------------------------------------------
741e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
742e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectextern "C" void thumb_function_1(int*p);
743e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectextern "C" void thumb_function_2(int*p);
744e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectextern "C" void arm_function_3(int*p);
745e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectextern "C" void arm_function_2(int*p);
746e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectextern "C" void arm_function_1(int*p);
747e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
748e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectvoid arm_function_3(int*p) {
749e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int a = 0;
750e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    thumb_function_2(&a);
751e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
752e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
753e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectvoid arm_function_2(int*p) {
754e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int a = 0;
755e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    thumb_function_1(&a);
756e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
757e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
758e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectvoid arm_function_1(int*p) {
759e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int a = 0;
760e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    arm_function_2(&a);
761e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
762e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
763e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint crawl_test(int argc, char** argv)
764e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
765e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int a = 0;
766e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    arm_function_1(&a);
767e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
768e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
769e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
770