test/blobfs: Use a lock instead of volatiles

Thread sanitizer detected a number of race conditions in this
test. Use a simple lock to pass messages between threads instead
because that's easier to get right.

Change-Id: Ia1f905f7b3787b4e89cf5ca1d16a1f24e0a562f9
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/362437
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Ben Walker 2017-05-24 16:15:38 -07:00
parent 830912e28a
commit b0355c0266

View File

@ -58,8 +58,8 @@ struct ut_request {
int from_ut; int from_ut;
}; };
volatile struct ut_request *g_req = NULL; static struct ut_request *g_req = NULL;
volatile int g_phase = 0; static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static void static void
send_request(fs_request_fn fn, void *arg) send_request(fs_request_fn fn, void *arg)
@ -72,10 +72,10 @@ send_request(fs_request_fn fn, void *arg)
req->arg = arg; req->arg = arg;
req->done = 0; req->done = 0;
req->from_ut = 0; req->from_ut = 0;
pthread_mutex_lock(&g_mutex);
g_req = req; g_req = req;
spdk_mb(); pthread_mutex_unlock(&g_mutex);
g_phase = !g_phase;
spdk_mb();
} }
static void static void
@ -87,12 +87,19 @@ ut_send_request(fs_request_fn fn, void *arg)
req.arg = arg; req.arg = arg;
req.done = 0; req.done = 0;
req.from_ut = 1; req.from_ut = 1;
pthread_mutex_lock(&g_mutex);
g_req = &req; g_req = &req;
spdk_mb(); pthread_mutex_unlock(&g_mutex);
g_phase = !g_phase;
spdk_mb(); while (1) {
while (req.done == 0) pthread_mutex_lock(&g_mutex);
; if (req.done == 1) {
pthread_mutex_unlock(&g_mutex);
break;
}
pthread_mutex_unlock(&g_mutex);
}
} }
static void static void
@ -248,21 +255,21 @@ static void *
spdk_thread(void *arg) spdk_thread(void *arg)
{ {
struct ut_request *req; struct ut_request *req;
int phase = 0;
spdk_allocate_thread(); spdk_allocate_thread();
while (1) { while (1) {
spdk_mb(); pthread_mutex_lock(&g_mutex);
if (phase != g_phase) { if (g_req != NULL) {
req = (void *)g_req; req = g_req;
req->fn(req->arg); req->fn(req->arg);
req->done = 1; req->done = 1;
spdk_mb();
if (!req->from_ut) { if (!req->from_ut) {
free(req); free(req);
} }
phase = !phase; g_req = NULL;
} }
pthread_mutex_unlock(&g_mutex);
} }
return NULL; return NULL;