Commit 3fe19105 by Thomas König

Use au->lock exclusively for locking in async I/O.

2020-02-18  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/93599
	* io/async.c (destroy_adv_cond): Do not destroy lock.
	(async_io): Make sure au->lock is locked for finishing of thread.
	Do not lock/unlock around signalling emptysignal. Unlock au->lock
	before return.
	(init_adv_cond): Do not initialize lock.
	(enqueue_transfer): Unlock after signal.
	(enqueue_done_id): Likewise.
	(enqueue_done): Likewise.
	(enqueue_close): Likewise.
	(enqueue_data_transfer): Likewise.
	(async_wait_id): Do not lock/unlock around signalling au->work.
	(async_wait): Unlock after signal.
	* io/async.h (SIGNAL): Add comment about needed au->lock.
	Remove locking/unlocking of advcond->lock.
	(WAIT_SIGNAL_MUTEX): Add comment. Remove locking/unlocking of
	advcond->lock.  Unlock mutex only at the end.  Loop on
	__ghread_cond_wait returning zero.
	(REVOKE_SIGNAL): Add comment. Remove locking/unlocking of
	advcond->lock.
	(struct adv_cond): Remove mutex from struct.

asdf
parent 9b8e2dea
2020-02-18 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/93599
* io/async.c (destroy_adv_cond): Do not destroy lock.
(async_io): Make sure au->lock is locked for finishing of thread.
Do not lock/unlock around signalling emptysignal. Unlock au->lock
before return.
(init_adv_cond): Do not initialize lock.
(enqueue_transfer): Unlock after signal.
(enqueue_done_id): Likewise.
(enqueue_done): Likewise.
(enqueue_close): Likewise.
(enqueue_data_transfer): Likewise.
(async_wait_id): Do not lock/unlock around signalling au->work.
(async_wait): Unlock after signal.
* io/async.h (SIGNAL): Add comment about needed au->lock.
Remove locking/unlocking of advcond->lock.
(WAIT_SIGNAL_MUTEX): Add comment. Remove locking/unlocking of
advcond->lock. Unlock mutex only at the end. Loop on
__ghread_cond_wait returning zero.
(REVOKE_SIGNAL): Add comment. Remove locking/unlocking of
advcond->lock.
(struct adv_cond): Remove mutex from struct.
2020-02-12 Sandra Loosemore <sandra@codesourcery.com> 2020-02-12 Sandra Loosemore <sandra@codesourcery.com>
PR libstdc++/79193 PR libstdc++/79193
......
...@@ -80,7 +80,6 @@ update_pdt (st_parameter_dt **old, st_parameter_dt *new) { ...@@ -80,7 +80,6 @@ update_pdt (st_parameter_dt **old, st_parameter_dt *new) {
static void static void
destroy_adv_cond (struct adv_cond *ac) destroy_adv_cond (struct adv_cond *ac)
{ {
T_ERROR (__gthread_mutex_destroy, &ac->lock);
T_ERROR (__gthread_cond_destroy, &ac->signal); T_ERROR (__gthread_cond_destroy, &ac->signal);
} }
...@@ -156,6 +155,7 @@ async_io (void *arg) ...@@ -156,6 +155,7 @@ async_io (void *arg)
case AIO_CLOSE: case AIO_CLOSE:
NOTE ("Received AIO_CLOSE"); NOTE ("Received AIO_CLOSE");
LOCK (&au->lock);
goto finish_thread; goto finish_thread;
default: default:
...@@ -175,7 +175,6 @@ async_io (void *arg) ...@@ -175,7 +175,6 @@ async_io (void *arg)
else if (ctq->type == AIO_CLOSE) else if (ctq->type == AIO_CLOSE)
{ {
NOTE ("Received AIO_CLOSE during error condition"); NOTE ("Received AIO_CLOSE during error condition");
UNLOCK (&au->lock);
goto finish_thread; goto finish_thread;
} }
} }
...@@ -189,9 +188,7 @@ async_io (void *arg) ...@@ -189,9 +188,7 @@ async_io (void *arg)
au->tail = NULL; au->tail = NULL;
au->head = NULL; au->head = NULL;
au->empty = 1; au->empty = 1;
UNLOCK (&au->lock);
SIGNAL (&au->emptysignal); SIGNAL (&au->emptysignal);
LOCK (&au->lock);
} }
finish_thread: finish_thread:
au->tail = NULL; au->tail = NULL;
...@@ -199,6 +196,7 @@ async_io (void *arg) ...@@ -199,6 +196,7 @@ async_io (void *arg)
au->empty = 1; au->empty = 1;
SIGNAL (&au->emptysignal); SIGNAL (&au->emptysignal);
free (ctq); free (ctq);
UNLOCK (&au->lock);
return NULL; return NULL;
} }
...@@ -223,7 +221,6 @@ static void ...@@ -223,7 +221,6 @@ static void
init_adv_cond (struct adv_cond *ac) init_adv_cond (struct adv_cond *ac)
{ {
ac->pending = 0; ac->pending = 0;
__GTHREAD_MUTEX_INIT_FUNCTION (&ac->lock);
__GTHREAD_COND_INIT_FUNCTION (&ac->signal); __GTHREAD_COND_INIT_FUNCTION (&ac->signal);
} }
...@@ -279,8 +276,8 @@ enqueue_transfer (async_unit *au, transfer_args *arg, enum aio_do type) ...@@ -279,8 +276,8 @@ enqueue_transfer (async_unit *au, transfer_args *arg, enum aio_do type)
au->tail = tq; au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal)); REVOKE_SIGNAL (&(au->emptysignal));
au->empty = false; au->empty = false;
UNLOCK (&au->lock);
SIGNAL (&au->work); SIGNAL (&au->work);
UNLOCK (&au->lock);
} }
/* Enqueue an st_write_done or st_read_done which contains an ID. */ /* Enqueue an st_write_done or st_read_done which contains an ID. */
...@@ -303,8 +300,8 @@ enqueue_done_id (async_unit *au, enum aio_do type) ...@@ -303,8 +300,8 @@ enqueue_done_id (async_unit *au, enum aio_do type)
au->empty = false; au->empty = false;
ret = au->id.high++; ret = au->id.high++;
NOTE ("Enqueue id: %d", ret); NOTE ("Enqueue id: %d", ret);
UNLOCK (&au->lock);
SIGNAL (&au->work); SIGNAL (&au->work);
UNLOCK (&au->lock);
return ret; return ret;
} }
...@@ -324,8 +321,8 @@ enqueue_done (async_unit *au, enum aio_do type) ...@@ -324,8 +321,8 @@ enqueue_done (async_unit *au, enum aio_do type)
au->tail = tq; au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal)); REVOKE_SIGNAL (&(au->emptysignal));
au->empty = false; au->empty = false;
UNLOCK (&au->lock);
SIGNAL (&au->work); SIGNAL (&au->work);
UNLOCK (&au->lock);
} }
/* Enqueue a CLOSE statement. */ /* Enqueue a CLOSE statement. */
...@@ -344,8 +341,8 @@ enqueue_close (async_unit *au) ...@@ -344,8 +341,8 @@ enqueue_close (async_unit *au)
au->tail = tq; au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal)); REVOKE_SIGNAL (&(au->emptysignal));
au->empty = false; au->empty = false;
UNLOCK (&au->lock);
SIGNAL (&au->work); SIGNAL (&au->work);
UNLOCK (&au->lock);
} }
/* The asynchronous unit keeps the currently active PDT around. /* The asynchronous unit keeps the currently active PDT around.
...@@ -374,9 +371,9 @@ enqueue_data_transfer_init (async_unit *au, st_parameter_dt *dt, int read_flag) ...@@ -374,9 +371,9 @@ enqueue_data_transfer_init (async_unit *au, st_parameter_dt *dt, int read_flag)
au->tail->next = tq; au->tail->next = tq;
au->tail = tq; au->tail = tq;
REVOKE_SIGNAL (&(au->emptysignal)); REVOKE_SIGNAL (&(au->emptysignal));
au->empty = 0; au->empty = false;
UNLOCK (&au->lock);
SIGNAL (&au->work); SIGNAL (&au->work);
UNLOCK (&au->lock);
} }
/* Collect the errors that may have happened asynchronously. Return true if /* Collect the errors that may have happened asynchronously. Return true if
...@@ -430,9 +427,7 @@ async_wait_id (st_parameter_common *cmp, async_unit *au, int i) ...@@ -430,9 +427,7 @@ async_wait_id (st_parameter_common *cmp, async_unit *au, int i)
NOTE ("Waiting for id %d", i); NOTE ("Waiting for id %d", i);
if (au->id.waiting < i) if (au->id.waiting < i)
au->id.waiting = i; au->id.waiting = i;
UNLOCK (&au->lock);
SIGNAL (&(au->work)); SIGNAL (&(au->work));
LOCK (&au->lock);
WAIT_SIGNAL_MUTEX (&(au->id.done), WAIT_SIGNAL_MUTEX (&(au->id.done),
(au->id.low >= au->id.waiting || au->empty), &au->lock); (au->id.low >= au->id.waiting || au->empty), &au->lock);
LOCK (&au->lock); LOCK (&au->lock);
...@@ -454,8 +449,8 @@ async_wait (st_parameter_common *cmp, async_unit *au) ...@@ -454,8 +449,8 @@ async_wait (st_parameter_common *cmp, async_unit *au)
if (cmp == NULL) if (cmp == NULL)
cmp = au->error.cmp; cmp = au->error.cmp;
SIGNAL (&(au->work));
LOCK (&(au->lock)); LOCK (&(au->lock));
SIGNAL (&(au->work));
if (au->empty) if (au->empty)
{ {
......
...@@ -229,44 +229,44 @@ ...@@ -229,44 +229,44 @@
#if ASYNC_IO #if ASYNC_IO
/* au->lock has to be held when calling this macro. */
#define SIGNAL(advcond) do{ \ #define SIGNAL(advcond) do{ \
INTERN_LOCK (&(advcond)->lock); \
(advcond)->pending = 1; \ (advcond)->pending = 1; \
DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE "SIGNAL: " DEBUG_NORM \ DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE "SIGNAL: " DEBUG_NORM \
#advcond, __FUNCTION__, __LINE__, (void *) advcond); \ #advcond, __FUNCTION__, __LINE__, (void *) advcond); \
T_ERROR (__gthread_cond_broadcast, &(advcond)->signal); \ T_ERROR (__gthread_cond_broadcast, &(advcond)->signal); \
INTERN_UNLOCK (&(advcond)->lock); \
} while (0) } while (0)
/* Has to be entered with mutex locked. */
#define WAIT_SIGNAL_MUTEX(advcond, condition, mutex) do{ \ #define WAIT_SIGNAL_MUTEX(advcond, condition, mutex) do{ \
__label__ finish; \ __label__ finish; \
INTERN_LOCK (&((advcond)->lock)); \
DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_BLUE "WAITING: " DEBUG_NORM \ DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_BLUE "WAITING: " DEBUG_NORM \
#advcond, __FUNCTION__, __LINE__, (void *) advcond); \ #advcond, __FUNCTION__, __LINE__, (void *) advcond); \
if ((advcond)->pending || (condition)){ \ if ((advcond)->pending || (condition)) \
UNLOCK (mutex); \
goto finish; \ goto finish; \
} \ while (1) \
UNLOCK (mutex); \ { \
while (!__gthread_cond_wait(&(advcond)->signal, &(advcond)->lock)) { \ int err_ret = __gthread_cond_wait(&(advcond)->signal, mutex); \
{ int cond; \ if (err_ret) internal_error (NULL, "WAIT_SIGNAL_MUTEX failed"); \
LOCK (mutex); cond = condition; UNLOCK (mutex); \ if (condition) \
if (cond){ \ { \
DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE "REC: " DEBUG_NORM \ DEBUG_PRINTF ("%s%-75s %20s():%-5d %18p\n", aio_prefix, DEBUG_ORANGE \
"REC: " DEBUG_NORM \
#advcond, __FUNCTION__, __LINE__, (void *)advcond); \ #advcond, __FUNCTION__, __LINE__, (void *)advcond); \
break; \ break; \
} \ } \
} \ } \
} \
finish: \ finish: \
(advcond)->pending = 0; \ (advcond)->pending = 0; \
INTERN_UNLOCK (&((advcond)->lock)); \ UNLOCK (mutex); \
} while (0) } while (0)
/* au->lock has to be held when calling this macro. */
#define REVOKE_SIGNAL(advcond) do{ \ #define REVOKE_SIGNAL(advcond) do{ \
INTERN_LOCK (&(advcond)->lock); \
(advcond)->pending = 0; \ (advcond)->pending = 0; \
INTERN_UNLOCK (&(advcond)->lock); \
} while (0) } while (0)
#else #else
...@@ -330,7 +330,6 @@ struct adv_cond ...@@ -330,7 +330,6 @@ struct adv_cond
{ {
#if ASYNC_IO #if ASYNC_IO
int pending; int pending;
__gthread_mutex_t lock;
__gthread_cond_t signal; __gthread_cond_t signal;
#endif #endif
}; };
......
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