Commit a051b555 authored by Ben Gamari's avatar Ben Gamari Committed by Ben Gamari
Browse files

testsuite: Ensure that hs_try_putmvar003 terminates

Test Plan: Validate

Reviewers: austin, simonmar

Reviewed By: simonmar

Subscribers: simonmar, rwbarton, thomie

GHC Trac Issues: #13434

Differential Revision: https://phabricator.haskell.org/D3724
parent d7b17517
...@@ -51,7 +51,7 @@ makeExternalCall q = mask_ $ do ...@@ -51,7 +51,7 @@ makeExternalCall q = mask_ $ do
data CallbackQueue data CallbackQueue
foreign import ccall "mkCallbackQueue" foreign import ccall "mkCallbackQueue"
mkCallbackQueue :: Int -> IO (Ptr CallbackQueue) mkCallbackQueue :: Int -> Int -> IO (Ptr CallbackQueue)
foreign import ccall "destroyCallbackQueue" foreign import ccall "destroyCallbackQueue"
destroyCallbackQueue :: Ptr CallbackQueue -> IO () destroyCallbackQueue :: Ptr CallbackQueue -> IO ()
...@@ -77,7 +77,7 @@ foreign export ccall callbackPutMVar :: StablePtr PrimMVar -> IO () ...@@ -77,7 +77,7 @@ foreign export ccall callbackPutMVar :: StablePtr PrimMVar -> IO ()
experiment :: Bool -> Int -> Int -> Int -> IO () experiment :: Bool -> Int -> Int -> Int -> IO ()
experiment use_foreign_export x y z = do experiment use_foreign_export x y z = do
mvars <- replicateM x $ async $ do mvars <- replicateM x $ async $ do
bracket (mkCallbackQueue (fromEnum use_foreign_export)) bracket (mkCallbackQueue (fromEnum use_foreign_export) (z*y))
destroyCallbackQueue $ \q -> do destroyCallbackQueue $ \q -> do
mvars <- replicateM y $ async $ mvars <- replicateM y $ async $
replicateM_ z $ void $ makeExternalCall q replicateM_ z $ void $ makeExternalCall q
......
...@@ -9,6 +9,9 @@ struct callback_queue { ...@@ -9,6 +9,9 @@ struct callback_queue {
pthread_mutex_t lock; pthread_mutex_t lock;
pthread_cond_t cond; pthread_cond_t cond;
int use_foreign_export; int use_foreign_export;
// How many requests will be submitted to this queue?
// (e.g. n_threads * n_requests_per_thread)
int n_requests;
struct callback *pending; struct callback *pending;
}; };
...@@ -24,7 +27,7 @@ void* callback(struct callback_queue *q) ...@@ -24,7 +27,7 @@ void* callback(struct callback_queue *q)
struct callback *cb; struct callback *cb;
pthread_mutex_lock(&q->lock); pthread_mutex_lock(&q->lock);
do { for (int i=0; i < q->n_requests; i++) {
if (q->pending == NULL) { if (q->pending == NULL) {
pthread_cond_wait(&q->cond,&q->lock); pthread_cond_wait(&q->cond,&q->lock);
} }
...@@ -39,7 +42,7 @@ void* callback(struct callback_queue *q) ...@@ -39,7 +42,7 @@ void* callback(struct callback_queue *q)
} }
free(cb); free(cb);
} }
} while (1); }
pthread_mutex_unlock(&q->lock); pthread_mutex_unlock(&q->lock);
hs_thread_done(); hs_thread_done();
...@@ -48,7 +51,7 @@ void* callback(struct callback_queue *q) ...@@ -48,7 +51,7 @@ void* callback(struct callback_queue *q)
typedef void* threadfunc(void *); typedef void* threadfunc(void *);
struct callback_queue* mkCallbackQueue(int use_foreign_export) struct callback_queue* mkCallbackQueue(int use_foreign_export, int n_requests)
{ {
struct callback_queue *q = malloc(sizeof(struct callback_queue)); struct callback_queue *q = malloc(sizeof(struct callback_queue));
pthread_t t; pthread_t t;
...@@ -56,6 +59,7 @@ struct callback_queue* mkCallbackQueue(int use_foreign_export) ...@@ -56,6 +59,7 @@ struct callback_queue* mkCallbackQueue(int use_foreign_export)
pthread_cond_init(&q->cond, NULL); pthread_cond_init(&q->cond, NULL);
q->pending = NULL; q->pending = NULL;
q->use_foreign_export = use_foreign_export; q->use_foreign_export = use_foreign_export;
q->n_requests = n_requests;
pthread_create(&t, NULL, (threadfunc*)callback, q); pthread_create(&t, NULL, (threadfunc*)callback, q);
return q; return q;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment