Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ clean:

memtester: \
$(OBJECTS) memtester.c tests.h tests.c tests.h conf-cc Makefile load extra-libs
./load memtester tests.o output.o `cat extra-libs`
./load memtester tests.o output.o `cat extra-libs` -lpthread

memtester.o: memtester.c tests.h conf-cc Makefile compile
./compile memtester.c
Expand Down
65 changes: 40 additions & 25 deletions memtester.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ off_t physaddrbase = 0;
/* Function definitions */
void usage(char *me) {
fprintf(stderr, "\n"
"Usage: %s [-p physaddrbase [-d device] [-u]] <mem>[B|K|M|G] [loops]\n",
"Usage: %s [-p physaddrbase [-d device] [-t num_threads] [-u]] <mem>[B|K|M|G] [loops]\n",
me);
exit(EXIT_FAIL_NONSTARTER);
}
Expand All @@ -128,7 +128,8 @@ int main(int argc, char **argv) {
char *env_testmask = 0;
ul testmask = 0;
int o_flags = O_RDWR | O_SYNC;

int num_threads = 1;
int stuck_address_only = 0;
out_initialize();

printf("memtester version " __version__ " (%d-bit)\n", UL_LEN);
Expand All @@ -154,7 +155,7 @@ int main(int argc, char **argv) {
printf("using testmask 0x%lx\n", testmask);
}

while ((opt = getopt(argc, argv, "p:d:u")) != -1) {
while ((opt = getopt(argc, argv, "p:d:t:us")) != -1) {
switch (opt) {
case 'p':
errno = 0;
Expand Down Expand Up @@ -198,11 +199,20 @@ int main(int argc, char **argv) {
}
break;
case 'u':
o_flags &= ~O_SYNC;
break;
o_flags &= ~O_SYNC;
break;
case 't':
num_threads = atoi(optarg);
if (num_threads > 1) {
disable_progress();
}
break;
case 's':
stuck_address_only = 1;
break;
default: /* '?' */
usage(argv[0]); /* doesn't return */
}
}
}

if (device_specified && !use_phys) {
Expand Down Expand Up @@ -274,7 +284,7 @@ int main(int argc, char **argv) {
}
}

printf("want %lluMB (%llu bytes)\n", (ull) wantmb, (ull) wantbytes);
printf("want %lluMB (%llu bytes)\n Running in %d Threads\n", (ull) wantmb, (ull) wantbytes, num_threads);
buf = NULL;

if (use_phys) {
Expand Down Expand Up @@ -383,6 +393,9 @@ int main(int argc, char **argv) {
count = halflen / sizeof(ul);
bufa = (ulv *) aligned;
bufb = (ulv *) ((size_t) aligned + halflen);
if(count % num_threads != 0) {
printf("Warning: thread number not ideal: %ld %% %d != 0, some unit will not be covered!\n", count, num_threads);
}

for(loop=1; ((!loops) || loop <= loops); loop++) {
printf("Loop %lu", loop);
Expand All @@ -392,29 +405,31 @@ int main(int argc, char **argv) {
printf(":\n");
printf(" %-20s: ", "Stuck Address");
fflush(stdout);
if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
if (num_threads > 1 ?!test_stuck_address_mt(aligned, bufsize / sizeof(ul), num_threads): !test_stuck_address(aligned, bufsize / sizeof(ul))) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_ADDRESSLINES;
}
for (i=0;;i++) {
if (!tests[i].name) break;
/* If using a custom testmask, only run this test if the
bit corresponding to this test was set by the user.
*/
if (testmask && (!((1 << i) & testmask))) {
continue;
}
printf(" %-20s: ", tests[i].name);
fflush(stdout);
if (!tests[i].fp(bufa, bufb, count)) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_OTHERTEST;
if (!stuck_address_only) {
for (i=0;;i++) {
if (!tests[i].name) break;
/* If using a custom testmask, only run this test if the
bit corresponding to this test was set by the user.
*/
if (testmask && (!((1 << i) & testmask))) {
continue;
}
printf(" %-20s: ", tests[i].name);
fflush(stdout);
if (num_threads > 1 ? !run_test_mt(tests[i].fp, bufa, bufb, count, num_threads): !tests[i].fp(bufa, bufb, count)) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_OTHERTEST;
}
fflush(stdout);
/* clear buffer */
memset((void *) buf, 255, wantbytes);
}
fflush(stdout);
/* clear buffer */
memset((void *) buf, 255, wantbytes);
}
printf("\n");
fflush(stdout);
Expand Down
4 changes: 4 additions & 0 deletions output.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ void out_initialize()
show_progress = isatty(STDOUT_FILENO);
}

void disable_progress() {
show_progress = 0;
}

void out_test_start()
{
if (show_progress) {
Expand Down
1 change: 1 addition & 0 deletions output.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ void out_test_start();
void out_test_setting();
void out_test_testing();
void out_test_end();
void disable_progress();

void out_wheel_start();
void out_wheel_advance();
Expand Down
69 changes: 69 additions & 0 deletions tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <pthread.h>

#include "types.h"
#include "sizes.h"
#include "memtester.h"
#include "output.h"
#include "tests.h"

#define ONE 0x00000001L

Expand Down Expand Up @@ -103,6 +105,73 @@ int test_stuck_address(ulv *bufa, size_t count) {
out_test_end();
return 0;
}
struct test_stuck_address_args {
unsigned long volatile *bufa;
size_t count;
int* result;
};
void* run_test_stuck_address_write_result(void *args) {
struct test_stuck_address_args *p = (struct test_stuck_address_args *)args;
*(p->result) = test_stuck_address(p->bufa, p->count);
}
int test_stuck_address_mt(unsigned long volatile *bufa, size_t count, int num_threads) {
int result[1024];
pthread_t thread_id[1024];
size_t count_per_threads = count / num_threads;
struct test_stuck_address_args args[1024];
for(int i = 0; i < num_threads; i ++) {
args[i].bufa = bufa + count_per_threads * i;
args[i].count = count_per_threads;
args[i].result = &result[i];
pthread_create(&thread_id[i], NULL, &run_test_stuck_address_write_result, &args[i]);
}

for(int i = 0; i < num_threads; i ++) {
pthread_join(thread_id[i], NULL);
}
for (int i = 0; i < num_threads; i ++) {
if (result[i] != 0) {
return result[i];
}
}
return 0;
}

struct test_thread_args {
test_func fp;
unsigned long volatile *bufa;
unsigned long volatile *bufb;
size_t count;
int* result;
};
void* run_test_write_result(void *args) {
struct test_thread_args *p = (struct test_stuck_address_args *)args;
*(p->result) = (p->fp)(p->bufa, p->bufb, p->count);
}
int run_test_mt(test_func fp, ulv *bufa, ulv *bufb, size_t count, int num_threads) {
int result[1024];
pthread_t thread_id[1024];
size_t count_per_threads = count / num_threads;
struct test_thread_args args[1024];
for(int i = 0; i < num_threads; i ++) {
args[i].fp = fp;
args[i].bufa = bufa + count_per_threads * i;
args[i].bufb = bufb + count_per_threads * i;
args[i].count = count_per_threads;
args[i].result = &result[i];
pthread_create(&thread_id[i], NULL, &run_test_write_result, &args[i]);
}

for(int i = 0; i < num_threads; i ++) {
pthread_join(thread_id[i], NULL);
}
for (int i = 0; i < num_threads; i ++) {
if (result[i] != 0) {
return result[i];
}
}
return 0;
}

int test_random_value(ulv *bufa, ulv *bufb, size_t count) {
ulv *p1 = bufa;
Expand Down
4 changes: 4 additions & 0 deletions tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
/* Function declaration. */

int test_stuck_address(unsigned long volatile *bufa, size_t count);
int test_stuck_address_mt(unsigned long volatile *bufa, size_t count, int num_threads);

int test_random_value(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_xor_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_sub_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
Expand All @@ -36,3 +38,5 @@ int test_bitflip_comparison(unsigned long volatile *bufa, unsigned long volatile
int test_8bit_wide_random(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
int test_16bit_wide_random(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
#endif
typedef int (*test_func)(unsigned long volatile *, unsigned long volatile *, size_t);
int run_test_mt(test_func fp, ulv *bufa, ulv *bufb, size_t count, int num_threads);