Update the synchronization primitive
Add comments and make sure we correctly return the status of the synchronization primitive, especially if it was completed with error.
Этот коммит содержится в:
родитель
2e1b1d34c6
Коммит
d9fb59bea5
@ -27,18 +27,18 @@ int sync_wait_st(ompi_wait_sync_t *sync)
|
|||||||
while(sync->count > 0) {
|
while(sync->count > 0) {
|
||||||
opal_progress();
|
opal_progress();
|
||||||
}
|
}
|
||||||
return OPAL_SUCCESS;
|
return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sync_wait_mt(ompi_wait_sync_t *sync)
|
int sync_wait_mt(ompi_wait_sync_t *sync)
|
||||||
{
|
{
|
||||||
if(sync->count <= 0)
|
if(sync->count <= 0)
|
||||||
return OPAL_SUCCESS;
|
return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR;
|
||||||
|
|
||||||
/* lock so nobody can signal us during the list updating */
|
/* lock so nobody can signal us during the list updating */
|
||||||
pthread_mutex_lock(&sync->lock);
|
pthread_mutex_lock(&sync->lock);
|
||||||
|
|
||||||
/* Insert sync to the list */
|
/* Insert sync on the list of pending synchronization constructs */
|
||||||
OPAL_THREAD_LOCK(&wait_sync_lock);
|
OPAL_THREAD_LOCK(&wait_sync_lock);
|
||||||
if( NULL == wait_sync_list ) {
|
if( NULL == wait_sync_list ) {
|
||||||
sync->next = sync->prev = sync;
|
sync->next = sync->prev = sync;
|
||||||
@ -52,32 +52,34 @@ int sync_wait_mt(ompi_wait_sync_t *sync)
|
|||||||
OPAL_THREAD_UNLOCK(&wait_sync_lock);
|
OPAL_THREAD_UNLOCK(&wait_sync_lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we are not responsible for progresing, let's go silent until something worth noticing happen:
|
* If we are not responsible for progresing, go silent until something worth noticing happen:
|
||||||
* - this thread has been promoted to take care of the progress
|
* - this thread has been promoted to take care of the progress
|
||||||
* - our sync has been triggered.
|
* - our sync has been triggered.
|
||||||
*/
|
*/
|
||||||
|
check_status:
|
||||||
if( sync != wait_sync_list ) {
|
if( sync != wait_sync_list ) {
|
||||||
pthread_cond_wait(&sync->condition, &sync->lock);
|
pthread_cond_wait(&sync->condition, &sync->lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At this point either the sync was completed in which case we should remove it from the wait
|
* At this point either the sync was completed in which case
|
||||||
* list, or/and I was promoted as the progress manager.
|
* we should remove it from the wait list, or/and I was
|
||||||
|
* promoted as the progress manager.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( sync->count <= 0 ) { /* Completed? */
|
if( sync->count <= 0 ) { /* Completed? */
|
||||||
pthread_mutex_unlock(&sync->lock);
|
pthread_mutex_unlock(&sync->lock);
|
||||||
goto i_am_done;
|
goto i_am_done;
|
||||||
}
|
}
|
||||||
/* promoted ! */
|
/* either promoted, or spurious wakeup ! */
|
||||||
assert(sync == wait_sync_list);
|
goto check_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&sync->lock);
|
pthread_mutex_unlock(&sync->lock);
|
||||||
while(sync->count > 0) { /* progress till completion */
|
while(sync->count > 0) { /* progress till completion */
|
||||||
opal_progress(); /* don't progress with the sync lock locked or you'll deadlock */
|
opal_progress(); /* don't progress with the sync lock locked or you'll deadlock */
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sync == wait_sync_list);
|
assert(sync == wait_sync_list);
|
||||||
|
|
||||||
i_am_done:
|
i_am_done:
|
||||||
/* My sync is now complete. Trim the list: remove self, wake next */
|
/* My sync is now complete. Trim the list: remove self, wake next */
|
||||||
OPAL_THREAD_LOCK(&wait_sync_lock);
|
OPAL_THREAD_LOCK(&wait_sync_lock);
|
||||||
@ -91,5 +93,5 @@ int sync_wait_mt(ompi_wait_sync_t *sync)
|
|||||||
}
|
}
|
||||||
OPAL_THREAD_UNLOCK(&wait_sync_lock);
|
OPAL_THREAD_UNLOCK(&wait_sync_lock);
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -73,17 +73,23 @@ OPAL_DECLSPEC int sync_wait_st(ompi_wait_sync_t *sync);
|
|||||||
PTHREAD_MUTEX_INIT(&(sync)->lock, NULL); \
|
PTHREAD_MUTEX_INIT(&(sync)->lock, NULL); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
static inline void wait_sync_update(ompi_wait_sync_t *sync, int updates, int req_status)
|
/**
|
||||||
|
* Update the status of the synchronization primitive. If an error is
|
||||||
|
* reported the synchronization is completed and the signal
|
||||||
|
* triggered. The status of the synchronization will be reported to
|
||||||
|
* the waiting threads.
|
||||||
|
*/
|
||||||
|
static inline void wait_sync_update(ompi_wait_sync_t *sync, int updates, int status)
|
||||||
{
|
{
|
||||||
if( OPAL_LIKELY(OPAL_SUCCESS == req_status) ) {
|
if( OPAL_LIKELY(OPAL_SUCCESS == status) ) {
|
||||||
if( 0 == (OPAL_ATOMIC_ADD_32(&sync->count, -updates)) ) {
|
if( 0 != (OPAL_ATOMIC_ADD_32(&sync->count, -updates)) ) {
|
||||||
WAIT_SYNC_SIGNAL(sync);
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
OPAL_ATOMIC_CMPSET_32(&(sync->count), 0, 0);
|
OPAL_ATOMIC_CMPSET_32(&(sync->count), 0, 0);
|
||||||
sync->status = -1;
|
sync->status = -1;
|
||||||
WAIT_SYNC_SIGNAL(sync);
|
|
||||||
}
|
}
|
||||||
|
WAIT_SYNC_SIGNAL(sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
END_C_DECLS
|
END_C_DECLS
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user