2004-11-22 03:37:56 +03:00
|
|
|
/*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
|
|
|
* All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
|
|
|
* All rights reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-11-22 03:37:56 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2004-10-20 05:03:09 +04:00
|
|
|
#include "ompi_config.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-01-20 03:03:23 +03:00
|
|
|
#ifdef HAVE_SCHED_H
|
2004-12-07 18:39:57 +03:00
|
|
|
#include <sched.h>
|
2005-01-20 03:03:23 +03:00
|
|
|
#endif
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2004-04-06 20:32:40 +04:00
|
|
|
#include "event/event.h"
|
|
|
|
#include "mca/pml/pml.h"
|
2004-06-07 19:33:53 +04:00
|
|
|
#include "runtime/ompi_progress.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
#include "include/constants.h"
|
2004-12-12 18:29:29 +03:00
|
|
|
|
2004-10-28 19:40:46 +04:00
|
|
|
static int ompi_progress_event_flag = OMPI_EVLOOP_ONCE;
|
2005-02-16 20:42:07 +03:00
|
|
|
static ompi_lock_t progress_lock;
|
2005-03-14 23:57:21 +03:00
|
|
|
static ompi_progress_callback_t *callbacks = NULL;
|
|
|
|
static size_t callbacks_len = 0;
|
|
|
|
static size_t callbacks_size = 0;
|
2004-12-12 18:29:29 +03:00
|
|
|
|
2005-02-16 20:42:07 +03:00
|
|
|
int
|
|
|
|
ompi_progress_init(void)
|
|
|
|
{
|
|
|
|
ompi_atomic_init(&progress_lock, OMPI_ATOMIC_UNLOCKED);
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-10-28 19:40:46 +04:00
|
|
|
void ompi_progress_events(int flag)
|
|
|
|
{
|
2004-12-14 19:35:38 +03:00
|
|
|
ompi_progress_event_flag = flag;
|
2004-10-28 19:40:46 +04:00
|
|
|
}
|
2004-12-12 18:29:29 +03:00
|
|
|
|
|
|
|
|
2004-06-07 19:33:53 +04:00
|
|
|
void ompi_progress(void)
|
2004-04-06 20:32:40 +04:00
|
|
|
{
|
2005-03-14 23:57:21 +03:00
|
|
|
size_t i;
|
|
|
|
|
2004-12-03 00:43:29 +03:00
|
|
|
/* progress any outstanding communications */
|
2005-02-09 05:09:07 +03:00
|
|
|
int ret, events = 0;
|
2005-02-16 20:42:07 +03:00
|
|
|
#if OMPI_HAVE_THREAD_SUPPORT
|
|
|
|
/* NOTE: BWB - XXX - FIXME: Currently, there are some progress functions
|
|
|
|
(the event library, for one) that are not reentrant. It is not known
|
|
|
|
if the PTL progress functions are all reentrant or not. The I/O
|
|
|
|
code should all be reentrant. Because of the uncertainty, we are
|
|
|
|
preventing more than one thread of execution from progressing the
|
|
|
|
via ompi_progress (which is usually only called when there are
|
|
|
|
no PROGRESS_THREADS running). This should be made more fine-grained
|
|
|
|
at some point in the future. */
|
|
|
|
if (! ompi_atomic_trylock(&progress_lock)) {
|
|
|
|
/* someone is already progressing - return */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if OMPI_ENABLE_PROGRESS_THREADS == 0
|
2004-12-12 18:29:29 +03:00
|
|
|
if (ompi_progress_event_flag != 0) {
|
|
|
|
ret = ompi_event_loop(ompi_progress_event_flag);
|
|
|
|
if (ret > 0) {
|
|
|
|
events += ret;
|
|
|
|
}
|
|
|
|
}
|
2004-12-07 18:39:57 +03:00
|
|
|
#endif
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
for (i = 0 ; i < callbacks_len ; ++i) {
|
2005-03-18 06:43:59 +03:00
|
|
|
if (NULL != callbacks[i]) {
|
|
|
|
ret = (callbacks[i])();
|
|
|
|
if (ret > 0) {
|
|
|
|
events += ret;
|
|
|
|
}
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 /* replaced by callback code */
|
2004-12-12 18:29:29 +03:00
|
|
|
ret = mca_pml.pml_progress();
|
|
|
|
if (ret > 0) {
|
|
|
|
events += ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Progress IO requests, if there are any */
|
2005-02-09 05:09:07 +03:00
|
|
|
ret = mca_io_base_request_progress();
|
|
|
|
if (ret > 0) {
|
|
|
|
events += ret;
|
2004-12-12 18:29:29 +03:00
|
|
|
}
|
2005-03-14 23:57:21 +03:00
|
|
|
#endif
|
2004-12-07 18:39:57 +03:00
|
|
|
|
2005-02-23 11:21:02 +03:00
|
|
|
#if OMPI_HAVE_THREAD_SUPPORT
|
2005-02-16 20:42:07 +03:00
|
|
|
/* release the lock before yielding, for obvious reasons */
|
|
|
|
ompi_atomic_unlock(&progress_lock);
|
2005-02-23 11:21:02 +03:00
|
|
|
#endif /* OMPI_HAVE_THREAD_SUPPORT */
|
2005-02-16 20:42:07 +03:00
|
|
|
|
2005-01-13 18:30:49 +03:00
|
|
|
#if 1
|
2004-12-03 00:43:29 +03:00
|
|
|
/* TSW - disable this until can validate that it doesn't impact SMP
|
|
|
|
* performance
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* if there is nothing to do - yield the processor - otherwise
|
|
|
|
* we could consume the processor for the entire time slice. If
|
|
|
|
* the processor is oversubscribed - this will result in a best-case
|
|
|
|
* latency equivalent to the time-slice.
|
|
|
|
*/
|
2004-12-12 18:29:29 +03:00
|
|
|
if(events == 0) {
|
2005-01-20 03:03:23 +03:00
|
|
|
#ifndef WIN32
|
|
|
|
/* TODO: Find the windows equivalent for this */
|
2004-12-03 00:43:29 +03:00
|
|
|
sched_yield();
|
2005-01-20 03:03:23 +03:00
|
|
|
#endif
|
2004-12-12 18:29:29 +03:00
|
|
|
}
|
2004-12-03 00:43:29 +03:00
|
|
|
#endif
|
2004-04-06 20:32:40 +04:00
|
|
|
}
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: This function is not in any way thread-safe. Do not allow
|
|
|
|
* multiple calls to ompi_progress_register and/or ompi_progress
|
|
|
|
* concurrently. This will be fixed in the near future.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
ompi_progress_register(ompi_progress_callback_t cb)
|
|
|
|
{
|
|
|
|
/* see if we need to allocate more space */
|
|
|
|
if (callbacks_len + 1 > callbacks_size) {
|
|
|
|
ompi_progress_callback_t *tmp;
|
|
|
|
tmp = realloc(callbacks, callbacks_size + 4);
|
|
|
|
if (tmp == NULL) return OMPI_ERR_TEMP_OUT_OF_RESOURCE;
|
|
|
|
|
|
|
|
callbacks = tmp;
|
|
|
|
callbacks_size += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
callbacks[callbacks_len++] = cb;
|
|
|
|
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
2005-03-18 06:43:59 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
ompi_progress_unregister(ompi_progress_callback_t cb)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0 ; i < callbacks_len ; ++i) {
|
|
|
|
if (cb == callbacks[i]) {
|
|
|
|
callbacks[i] = NULL;
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OMPI_ERR_NOT_FOUND;
|
|
|
|
}
|