Multithreaded test of stack

pull/2383/head
Vijay Pai 10 years ago
parent 887f86bd21
commit 10a6546cb9
  1. 99
      test/core/support/stack_lockfree_test.c

@ -33,20 +33,23 @@
#include "src/core/support/stack_lockfree.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include "test/core/util/test_config.h"
void test_serial() {
gpr_stack_lockfree *stack = gpr_stack_lockfree_create(128);
/* max stack size supported */
#define MAX_STACK_SIZE 65534
#define MAX_THREADS 32
static void test_serial_sized(int size) {
gpr_stack_lockfree *stack = gpr_stack_lockfree_create(size);
int i;
/* First try popping empty */
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1);
@ -54,22 +57,98 @@ void test_serial() {
gpr_stack_lockfree_push(stack, 3);
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == 3);
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1);
/* Now add repeatedly more items and check them */
for (i=0; i<128; i++) {
for (i=1; i<size; i*=2) {
int j;
for (j=0; j<=i; j++) {
gpr_stack_lockfree_push(stack, j);
}
for (j=0; j<=i; j++) {
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == i-j);
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == i-j);
}
GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1);
}
gpr_stack_lockfree_destroy(stack);
}
static void test_serial() {
int i;
for (i=128; i<MAX_STACK_SIZE; i*=2) {
test_serial_sized(i);
}
test_serial_sized(MAX_STACK_SIZE);
}
struct test_arg {
gpr_stack_lockfree *stack;
int stack_size;
int nthreads;
int rank;
int sum;
};
static void test_mt_body(void *v) {
struct test_arg *arg = (struct test_arg *)v;
int lo, hi;
int i;
int res;
lo = arg->rank*arg->stack_size/arg->nthreads;
hi = (arg->rank+1)*arg->stack_size/arg->nthreads;
for (i=lo; i<hi; i++) {
gpr_stack_lockfree_push(arg->stack, i);
if ((res = gpr_stack_lockfree_pop(arg->stack)) != -1) {
arg->sum += res;
}
}
while ((res = gpr_stack_lockfree_pop(arg->stack)) != -1) {
arg->sum += res;
}
}
static void test_mt_sized(int size, int nth) {
gpr_stack_lockfree *stack;
struct test_arg args[MAX_THREADS];
gpr_thd_id thds[MAX_THREADS];
int sum;
int i;
gpr_thd_options options = gpr_thd_options_default();
stack = gpr_stack_lockfree_create(size);
for (i=0; i<nth; i++) {
args[i].stack = stack;
args[i].stack_size = size;
args[i].nthreads = nth;
args[i].rank = i;
args[i].sum = 0;
}
gpr_thd_options_set_joinable(&options);
for (i = 0; i < nth; i++) {
GPR_ASSERT(gpr_thd_new(&thds[i], test_mt_body, &args[i], &options));
}
sum = 0;
for (i = 0; i < nth; i++) {
gpr_thd_join(thds[i]);
sum = sum + args[i].sum;
}
GPR_ASSERT((unsigned)sum == ((unsigned)size*(size-1))/2);
gpr_stack_lockfree_destroy(stack);
}
static void test_mt() {
int size, nth;
for (nth=1; nth < MAX_THREADS; nth++) {
for (size=128; size < MAX_STACK_SIZE; size*=2) {
test_mt_sized(size,nth);
}
test_mt_sized(MAX_STACK_SIZE,nth);
}
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_serial();
test_mt();
return 0;
}

Loading…
Cancel
Save