1
1

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.
Этот коммит содержится в:
George Bosilca 2016-06-02 11:53:56 +09:00
родитель 2e1b1d34c6
Коммит d9fb59bea5
2 изменённых файлов: 23 добавлений и 15 удалений

Просмотреть файл

@ -27,18 +27,18 @@ int sync_wait_st(ompi_wait_sync_t *sync)
while(sync->count > 0) {
opal_progress();
}
return OPAL_SUCCESS;
return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR;
}
int sync_wait_mt(ompi_wait_sync_t *sync)
{
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 */
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);
if( NULL == wait_sync_list ) {
sync->next = sync->prev = sync;
@ -52,32 +52,34 @@ int sync_wait_mt(ompi_wait_sync_t *sync)
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
* - our sync has been triggered.
*/
check_status:
if( sync != wait_sync_list ) {
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
* list, or/and I was promoted as the progress manager.
* At this point either the sync was completed in which case
* we should remove it from the wait list, or/and I was
* promoted as the progress manager.
*/
if( sync->count <= 0 ) { /* Completed? */
pthread_mutex_unlock(&sync->lock);
goto i_am_done;
}
/* promoted ! */
assert(sync == wait_sync_list);
/* either promoted, or spurious wakeup ! */
goto check_status;
}
pthread_mutex_unlock(&sync->lock);
while(sync->count > 0) { /* progress till completion */
opal_progress(); /* don't progress with the sync lock locked or you'll deadlock */
}
assert(sync == wait_sync_list);
i_am_done:
/* My sync is now complete. Trim the list: remove self, wake next */
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);
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); \
} 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( 0 == (OPAL_ATOMIC_ADD_32(&sync->count, -updates)) ) {
WAIT_SYNC_SIGNAL(sync);
if( OPAL_LIKELY(OPAL_SUCCESS == status) ) {
if( 0 != (OPAL_ATOMIC_ADD_32(&sync->count, -updates)) ) {
return;
}
} else {
OPAL_ATOMIC_CMPSET_32(&(sync->count), 0, 0);
sync->status = -1;
WAIT_SYNC_SIGNAL(sync);
}
WAIT_SYNC_SIGNAL(sync);
}
END_C_DECLS