Skip to content
Commits on Source (59)
......@@ -160,42 +160,7 @@ AX_CHECK_XDMA
AX_ENABLE_TASK_CALLBACK
# Extrae check
MPITRACE_HOME=""
MPITRACE_INC=""
MPITRACE_LIB=""
MPITRACE_BIN=""
AC_ARG_WITH([extrae],
AS_HELP_STRING([--with-extrae=dir], [Directory of Extrae installation]),
[
extrae_version_h=$withval/include/extrae_version.h
AS_IF([test -e $extrae_version_h],[
extrae_version_string=$(sed -ne '/^\s*#\s*define\s\+EXTRAE_VERSION .*$/p' $extrae_version_h)
extrae_version=$(echo $extrae_version_string | sed -e 's/#define EXTRAE_VERSION EXTRAE_VERSION_NUMBER(\([0-9]*\),\([0-9]*\),\([0-9]*\).*$/\1\2\3/')
AS_IF([test "$extrae_version" -ge 240],[
MPITRACE_HOME="$withval"
MPITRACE_INC="$withval/include"
MPITRACE_LIB="$withval/lib"
AS_IF([test -d "$MPITRACE_HOME/lib64"],[
MPITRACE_LIB="$MPITRACE_HOME/lib64"
])
MPITRACE_BIN="$withval/bin"
AC_MSG_RESULT([checking if Extrae library is compatible... yes])
],[
AC_MSG_ERROR([checking if Extrae library is compatible... no (Extrae > 2.4 needed)])
])
],[
AC_MSG_ERROR([checking if Extrae library is compatible... no (Extrae > 2.4 needed)])
])
]
)
AC_SUBST([MPITRACE_HOME])
AC_SUBST([MPITRACE_INC])
AC_SUBST([MPITRACE_LIB])
AC_SUBST([MPITRACE_BIN])
AM_CONDITIONAL([instrumentation_EXTRAE], test x"$MPITRACE_HOME" != x)
AX_CHECK_EXTRAE
# Check NextSim support
AC_ARG_WITH([nextsim],
......
#
# SYNOPSIS
#
# AX_CHECK_EXTRAE
#
# DESCRIPTION
#
# Check Extrae support
#
AC_DEFUN([AX_CHECK_EXTRAE],
[
AC_REQUIRE([AC_PROG_AWK])
MPITRACE_HOME=""
MPITRACE_INC=""
MPITRACE_LIB=""
MPITRACE_BIN=""
AC_MSG_CHECKING([for Extrae])
AC_ARG_WITH([extrae],
AS_HELP_STRING([--with-extrae=PATH], [build with Extrae support]),
[], dnl Implicit: with_extrae=$withvalue
[with_extrae=no]
)
AC_MSG_RESULT([$with_extrae])
AS_IF([test "x$with_extrae" != xno], [
# Extrae 2.4 or higher is needed
# Header extrae_version.h exists until Extrae 3.4 and again since 3.5.3
# API Extrae_get_version exists since Extrae 3.4
AC_MSG_CHECKING([for Extrae version])
extrae_version_h="$with_extrae/include/extrae_version.h"
AS_IF([test -e "$extrae_version_h"], [
# Obtain version through Extrae header
extrae_version=$($AWK -v FS='[[(),]]' \
'/EXTRAE_VERSION_NUMBER\([[0-9]],[[0-9]],[[0-9]]\)/{print $[2]"."$[3]"."$[4];}' \
$extrae_version_h)
AS_IF([test -z "$extrae_version"], [
extrae_version=$($AWK \
'
BEGIN{major=""; minor=""; micro="";}
/EXTRAE_MAJOR [[0-9]]/{major=$[3];}
/EXTRAE_MINOR [[0-9]]/{minor=$[3];}
/EXTRAE_MICRO [[0-9]]/{micro=$[3];}
END{if (length(major)>0 && length(minor)>0 && length(micro)>0)
print major"."minor"."micro;}
' $extrae_version_h)
])
], [
# Obtain version through Extrae API
AC_LANG_PUSH([C])
AC_LANG_CONFTEST([
AC_LANG_SOURCE([[
#include <stdio.h>
void Extrae_get_version (unsigned *major, unsigned *minor, unsigned *revision);
int main()
{
unsigned major, minor, revision;
Extrae_get_version(&major, &minor, &revision);
printf("%1d.%1d.%1d\n", major, minor, revision);
return 0;
}
]])
])
AC_LANG_POP([C])
AS_IF([$CC conftest.c -o conftest \
-lnanostrace -L$with_extrae/lib -Wl,-rpath,$with_extrae/lib \
2>&AS_MESSAGE_LOG_FD 1>&2], [
extrae_version=$(./conftest)
])
rm -f conftest
])
AC_MSG_RESULT([$extrae_version])
AS_IF([test -z "$extrae_version"],[
AC_MSG_ERROR([could not find Extrae installation])
])
AC_MSG_CHECKING([if Extrae library is compatible])
AX_COMPARE_VERSION([$extrae_version],[ge],[2.4], [
MPITRACE_HOME="$withval"
MPITRACE_INC="$withval/include"
MPITRACE_LIB="$withval/lib"
AS_IF([test -d "$MPITRACE_HOME/lib64"],[
MPITRACE_LIB="$MPITRACE_HOME/lib64"
])
MPITRACE_BIN="$withval/bin"
AC_MSG_RESULT([yes])
],[
AC_MSG_ERROR([no (Extrae >= 2.4 needed)])
])
])
AC_SUBST([MPITRACE_HOME])
AC_SUBST([MPITRACE_INC])
AC_SUBST([MPITRACE_LIB])
AC_SUBST([MPITRACE_BIN])
AM_CONDITIONAL([instrumentation_EXTRAE], test x"$MPITRACE_HOME" != x)
])
......@@ -69,6 +69,7 @@ nanos_c_sources = \
c/nanos_reduction.cpp\
c/nanos_sched.cpp\
c/nanos_dependence.cpp\
c/nanos_polling.cpp\
c/iomp_symbols.cpp\
$(END)
......
......@@ -171,6 +171,10 @@ typedef struct {
void *arch;
} nanos_constraint_t;
typedef void* nanos_block_cond_t;
#define NANOS_COND_NULL (nanos_block_cond_t)0
//! \}
#ifdef __cplusplus
......@@ -189,6 +193,8 @@ extern "C" {
NANOS_API_DECL(char *, nanos_get_mode, ( void ));
NANOS_API_DECL(void, nanos_debug, ( const char *message ));
// Functions related to WD
NANOS_API_DECL(nanos_wd_t, nanos_current_wd, (void));
NANOS_API_DECL(int, nanos_get_wd_id, (nanos_wd_t wd));
......@@ -198,6 +204,12 @@ NANOS_API_DECL(void, nanos_set_wd_priority, (nanos_wd_t wd, int p));
NANOS_API_DECL(nanos_err_t, nanos_get_wd_description, ( const char **description, nanos_wd_t wd ));
/* Vladimir Marjanovic MB3 prototype*/
// \brief Marks a task as communication task
NANOS_API_DECL(void, nanos_comm_task, (void));
/* Vladimir Marjanovic MB3 prototype*/
// Finder functions
NANOS_API_DECL(nanos_slicer_t, nanos_find_slicer, ( const char * slicer ));
NANOS_API_DECL(nanos_ws_t, nanos_find_worksharing, ( const char * label ) );
......@@ -222,6 +234,9 @@ NANOS_API_DECL(nanos_err_t, nanos_create_for, ( void ));
NANOS_API_DECL(nanos_err_t, nanos_set_internal_wd_data, ( nanos_wd_t wd, void *data ));
NANOS_API_DECL(nanos_err_t, nanos_get_internal_wd_data, ( nanos_wd_t wd, void **data ));
NANOS_API_DECL(nanos_err_t, nanos_get_task_local_storage, ( void **data, size_t *size ));
NANOS_API_DECL(nanos_err_t, nanos_yield, ( void ));
NANOS_API_DECL(nanos_err_t, nanos_slicer_get_specific_data, ( nanos_slicer_t slicer, void ** data ));
......@@ -256,6 +271,10 @@ NANOS_API_DECL(nanos_err_t, nanos_enter_sync_init, ( bool *b ));
NANOS_API_DECL(nanos_err_t, nanos_wait_sync_init, ( void ));
NANOS_API_DECL(nanos_err_t, nanos_release_sync_init, ( void ));
NANOS_API_DECL(nanos_block_cond_t, nanos_get_current_blocking_context, ());
NANOS_API_DECL(void, nanos_block_current_task, ( nanos_block_cond_t ));
NANOS_API_DECL(void, nanos_unblock_task, ( nanos_block_cond_t ));
NANOS_API_DECL(nanos_err_t, nanos_memory_fence, (void));
NANOS_API_DECL(nanos_err_t, nanos_team_get_num_supporting_threads, ( int *n ) );
......@@ -426,6 +445,53 @@ NANOS_API_DECL(void, nanos_print_bt, (void));
NANOS_API_DECL(void, nanos_enable_verbose_copies, (void));
NANOS_API_DECL(void, nanos_disable_verbose_copies, (void));
// Polling service functions
//! \brief Register a function and parameter of that function that the runtime
//! must call periodically to perform operations in a non-blocking fashion
//!
//! Registers a function that the runtime will called periodically. The purpose
//! is to support operations in a non-blocking way. For instance to check for
//! certain events that are not possible to check in a blocking way, or that it
//! is not desirable to do so.
//!
//! The service_data parameter is an opaque pointer that is passed to the function
//! as is.
//!
//! The same function can be registered several times with different service_data
//! parameters, and each combination will be considered as a different
//! registration. That is, a registered service instance consists of a service
//! function and a specific service_data.
//!
//! The service will remain registered as long as the function returns false and
//! the service has not been explicitly deregistered through a call to
//! nanos_unregister_polling_service.
//!
//! \param[in] service_name a string that identifies the kind of service that will
//! be serviced
//! \param[in] service the function that the runtime should call periodically
//! \param service_data an opaque pointer to data that is passed to the service
//! function
NANOS_API_DECL(void, nanos_register_polling_service, (char const *service_name, nanos_polling_service_t service_function, void *service_data) );
//! \brief Unregister a function and parameter of that function previously
//! registered through a call to nanos_register_polling_service.
//!
//! Unregister a service instance identified by the service_function and
//! service_data previously registered through a call to
//! nanos_register_polling_service. The service_function must not have returned
//! true when called with the given service_data, since that return value is
//! equivalent to a call to this function.
//!
//! \param[in] service_name a string that identifies the kind of service
//! \param[in] service the function that the runtime should stop calling
//! periodically with the given service_data
//! \param service_data an opaque pointer to the data that was passed to the
//! service function
NANOS_API_DECL(void, nanos_unregister_polling_service, (char const *service_name, nanos_polling_service_t service_function, void *service_data) );
#ifdef __cplusplus
}
#endif
......
......@@ -64,3 +64,7 @@ NANOS_API_DEF(void, nanos_handle_error, ( nanos_err_t err ))
abort();
}
NANOS_API_DEF(void, nanos_debug, ( const char *message ))
{
}
/*************************************************************************************/
/* Copyright 2017 Barcelona Supercomputing Center */
/* */
/* This file is part of the NANOS++ library. */
/* */
/* NANOS++ is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU Lesser General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version. */
/* */
/* NANOS++ is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with NANOS++. If not, see <http://www.gnu.org/licenses/>. */
/*************************************************************************************/
/*! \file nanos_polling.cpp
* \brief Polling service implementation
*/
#include "pollingservice.hpp"
#include "nanos-int.h"
#include "nanos.h"
nanos::PollingService* nanos::PollingServiceManager::_service = NULL;
spin_mutex nanos::PollingServiceManager::_mutex;
NANOS_API_DEF(void, nanos_register_polling_service, (char const *service_name, nanos_polling_service_t service_function, void *service_data) )
{
nanos::PollingServiceManager::registerService(service_name, service_function, service_data);
}
NANOS_API_DEF(void, nanos_unregister_polling_service, (char const *service_name, nanos_polling_service_t service_function, void *service_data) )
{
nanos::PollingServiceManager::unregisterService(service_name, service_function, service_data);
}
......@@ -363,6 +363,35 @@ NANOS_API_DEF(nanos_err_t, nanos_get_lock_address, ( void *addr, nanos_lock_t **
return NANOS_OK;
}
NANOS_API_DEF(nanos_block_cond_t, nanos_get_current_blocking_context, ())
{
UserWaitCondition* condition = new UserWaitCondition();
condition->reference();
return static_cast<nanos_block_cond_t>(condition);
}
NANOS_API_DEF(void, nanos_block_current_task, ( nanos_block_cond_t cond ))
{
UserWaitCondition* condition = static_cast<UserWaitCondition*>(cond);
myThread->getCurrentWD()->tieTo(*myThread);
condition->waitConditionAndSignalers();
delete condition;
cond = NANOS_COND_NULL;
}
NANOS_API_DEF(void, nanos_unblock_task, ( nanos_block_cond_t cond ))
{
UserWaitCondition* condition = static_cast<UserWaitCondition*>(cond);
condition->satisfy();
condition->signal();
condition->unreference();
condition->unlock();
}
/*!
* \}
*/
......@@ -74,6 +74,16 @@ NANOS_API_DEF(int, nanos_get_wd_id, ( nanos_wd_t wd ))
return id;
}
/* Vladimir Marjanovic MB3 prototype*/
// Marks a task as communication task
NANOS_API_DEF(void, nanos_comm_task, ( void ))
{
nanos_wd_t cwd = myThread->getCurrentWD();
WD *lwd = ( WD * )cwd;
lwd->setCommFlag(true);
}
/* Vladimir Marjanovic MB3 prototype*/
/*! \brief Returns the description of the specified WD.
*
* \param [out] string description
......@@ -392,6 +402,23 @@ NANOS_API_DEF(nanos_err_t, nanos_get_internal_wd_data, ( nanos_wd_t wd, void **d
return NANOS_OK;
}
/*! \brief Get WorkDescriptor's task local storage
*
*/
NANOS_API_DEF(nanos_err_t, nanos_get_task_local_storage, ( void **data, size_t *size ))
{
NANOS_INSTRUMENT( InstrumentStateAndBurst inst("api","get_task_local_storage",NANOS_RUNTIME) );
WD *wd = myThread->getCurrentWD();
std::pair<void*,size_t> tlsInfo = wd->getTaskLocalStorageInfo();
*data = tlsInfo.first;
*size = tlsInfo.second;
return NANOS_OK;
}
/*! \brief Yields current thread (if other WorkDescriptor is ready to be executed)
*
*/
......
......@@ -30,6 +30,7 @@
#include "atomic.hpp"
#include "config.hpp"
#include "system_decl.hpp"
namespace nanos {
namespace ext {
......
......@@ -22,6 +22,7 @@
#include "debug.hpp"
#include "openclevent_decl.hpp"
#include "openclthread.hpp"
#include "asyncthread_decl.hpp"
......
......@@ -19,10 +19,11 @@
#include "openclprocessor.hpp"
#include "basethread.hpp"
#include "openclthread.hpp"
#include "pthread.hpp"
#include "instrumentationmodule_decl.hpp"
#include "openclevent.hpp"
#include "openclthread.hpp"
#include "os.hpp"
#include "pthread.hpp"
using namespace nanos;
using namespace nanos::ext;
......
......@@ -144,6 +144,7 @@ devinclude_HEADERS = \
invalidationcontroller_fwd.hpp \
task_reduction_decl.hpp \
task_reduction.hpp \
pollingservice.hpp \
$(END)
common_sources=\
......
......@@ -82,7 +82,7 @@ bool AsyncThread::inlineWorkDependent( WD &work )
}
void AsyncThread::idle()
void AsyncThread::idle( bool debug )
{
NANOS_INSTRUMENT( if ( _pendingEventsCounter > 0 ) { )
ASYNC_THREAD_CREATE_EVENT( ASYNC_THREAD_CHECK_EVTS_EVENT );
......@@ -517,7 +517,7 @@ WD * AsyncThread::getNextWD ()
return NULL;
}
bool AsyncThread::hasNextWD ()
bool AsyncThread::hasNextWD () const
{
//if ( canGetWork() ) return BaseThread::hasNextWD();
return false;
......
......@@ -94,7 +94,7 @@ namespace nanos {
virtual void yield() { this->idle(); }
virtual void idle();
virtual void idle( bool debug = false );
virtual void processTransfers ();
......@@ -138,7 +138,7 @@ namespace nanos {
// Additional checkings for next WDs
void addNextWD ( WD *next );
WD * getNextWD ();
bool hasNextWD ();
bool hasNextWD () const;
// Set whether the thread will schedule WDs or not used by getImmediateSuccessor()
// If so, WD's dependencies should be kept till WD is finished
......
......@@ -21,6 +21,7 @@
#include "instrumentation.hpp"
#include "system.hpp"
#include "basethread.hpp"
#include "recursivelock_decl.hpp"
#include <alloca.h>
using namespace nanos;
......
......@@ -247,7 +247,7 @@ typedef struct {
bool is_final:1;
bool is_recover:1;
bool is_implicit:1;
bool reserved3:1;
bool is_comm_thread:1;
bool reserved4:1;
bool reserved5:1;
bool reserved6:1;
......@@ -336,6 +336,18 @@ typedef struct {
void *data;
} nanos_init_desc_t;
/* Polling interface service function type */
//! \brief Function that the runtime calls periodically
//!
//! \param service_data a pointer to data that the function uses and that
//! also identifies an instance of this service registration
//!
//! \returns true to signal that the purpose of the function has been
//! achieved and that the function should not be called again with the given
//! service_data
typedef int (*nanos_polling_service_t)(void *service_data);
//! \}
#endif
......@@ -27,6 +27,7 @@
#include <vector>
#include "functor_decl.hpp"
#include "globalregt_decl.hpp"
#include "recursivelock_decl.hpp"
#include "requestqueue_decl.hpp"
#include "networkapi.hpp"
#include "packer_decl.hpp"
......
/*************************************************************************************/
/* Copyright 2017 Barcelona Supercomputing Center */
/* */
/* This file is part of the NANOS++ library. */
/* */
/* NANOS++ is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU Lesser General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version. */
/* */
/* NANOS++ is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with NANOS++. If not, see <http://www.gnu.org/licenses/>. */
/*************************************************************************************/
#ifndef POLLINGSERVICE_HPP
#define POLLINGSERVICE_HPP
#include "debug.hpp"
#include "spin_mutex.hpp"
#include "nanos-int.h"
#include "mutex.hpp"
namespace nanos {
class PollingService {
public:
PollingService( const char* service_name, nanos_polling_service_t function, void* data ) :
_function(function),
_data(data)
{
}
// Calls the polling service function.
// Returns true when the service have to be automatically unregistered.
bool operator()() {
return _function(_data) != 0;
}
private:
nanos_polling_service_t _function;
void* _data;
};
// Naive implementation that only supports a single polling service.
// Aborts if more than a single service is registered.
class PollingServiceManager {
public:
static void registerService( const char* name, nanos_polling_service_t function, void* data ) {
UniqueLock<spin_mutex> guard(_mutex);
if( !_service ) {
_service = new PollingService( name, function, data );
} else {
fatal( "This polling implementation only supports a single service." );
}
}
static void unregisterService( const char* name, nanos_polling_service_t function, void* data ) {
UniqueLock<spin_mutex> guard(_mutex);
unregisterService();
}
static void poll() {
// Call service function.
UniqueLock<spin_mutex> guard(_mutex, try_to_lock );
if( guard.owns_lock() && _service != NULL ) {
int rval = (*_service)();
if( rval != 0 ) {
unregisterService();
}
}
}
private:
static void unregisterService() {
delete _service;
_service = NULL;
}
static spin_mutex _mutex;
static PollingService* _service;
};
} // namespace nanos
#endif // POLLINGSERVICE_HPP
......@@ -136,7 +136,7 @@ ContainerDense< T >::ContainerDense( CopyData const &cd ) : _container(64, T())
}
if ( pthread_rwlock_init( &_containerLock, NULL ) ) {
message0("error initializing containerlock ");
fatal("can not continue")
fatal("can not continue");
}
}
......
......@@ -75,7 +75,12 @@ void Scheduler::_submit ( WD &wd, bool force_queue )
wd.setReady();
/* handle tied tasks */
//disable studid tied
// Tied constraints produce problems with comm_thread
// modified scheduling
#if 0
BaseThread *wd_tiedto = wd.isTiedTo();
if ( wd.isTied() && wd_tiedto != mythread ) {
if ( wd_tiedto->getTeam() == NULL ) {
wd_tiedto->addNextWD( &wd );
......@@ -84,6 +89,7 @@ void Scheduler::_submit ( WD &wd, bool force_queue )
}
return;
}
#endif
/* By checking if there's available WDs in the queue before queuing the current one,
* we ensure that we only trigger a wakeup if at least the current thread will not remain
......@@ -157,7 +163,10 @@ void Scheduler::_submit ( WD ** wds, size_t numElems )
{
WD* wd = wds[i];
wd->_mcontrol.preInit();
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
// If the wd is tied to anyone
BaseThread *wd_tiedto = wd->isTiedTo();
if ( wd->isTied() && wd_tiedto != mythread ) {
......@@ -171,6 +180,7 @@ void Scheduler::_submit ( WD ** wds, size_t numElems )
}
continue;
}
#endif
// Otherwise, use mythread
threadList[i] = mythread;
}
......@@ -327,7 +337,7 @@ inline void Scheduler::idleLoop ()
if ( !next && thread->getTeam() != NULL ) {
memoryFence();
if ( sys.getSchedulerStats()._readyTasks > 0 ) {
//if ( sys.getSchedulerStats()._readyTasks > 0 ) {
NANOS_INSTRUMENT ( total_scheds++; )
NANOS_INSTRUMENT ( unsigned long long begin_sched = (unsigned long long) ( OS::getMonotonicTime() * 1.0e9 ); )
......@@ -340,7 +350,7 @@ inline void Scheduler::idleLoop ()
NANOS_INSTRUMENT ( unsigned long long end_sched = (unsigned long long) ( OS::getMonotonicTime() * 1.0e9 ); )
NANOS_INSTRUMENT (time_scheds += ( end_sched - begin_sched ); )
}
//}
}
// Trigger a wakeup if there's more WDs in the queue
......@@ -643,7 +653,12 @@ void Scheduler::preOutlineWorkWithThread ( BaseThread * thread, WD *wd )
// OLD: and we don't violate rules about tied WD
// we tie to when outlining, because we will notify the tied thread when the execution completes
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
wd->tieTo( *thread );
#endif
thread->setCurrentWD( *wd );
if (!wd->started())
wd->init();
......@@ -679,7 +694,12 @@ void Scheduler::preOutlineWork ( WD *wd )
// OLD: and we don't violate rules about tied WD
// we tie to when outlining, because we will notify the tied thread when the execution completes
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
wd->tieTo( *thread );
#endif
thread->setCurrentWD( *wd );
if (!wd->started())
wd->init();
......@@ -708,7 +728,13 @@ bool Scheduler::tryPreOutlineWork ( WD *wd )
debug( "switching(try pre outline) from task " << &(thread->getThreadWD()) << ":" << thread->getThreadWD().getId() << " to " << wd << ":" << wd->getId() );
result = true;
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
wd->tieTo( *thread );
#endif
thread->setCurrentWD( *wd );
if ( !wd->started() ) {
wd->init();
......@@ -825,7 +851,12 @@ bool Scheduler::inlineWork ( WD *wd, bool schedule )
// This ensures that when we return from the inlining is still the same thread
// and we don't violate rules about tied WD
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
if ( oldwd->isTiedTo() != NULL && (wd->isTiedTo() == NULL)) wd->tieTo(*oldwd->isTiedTo());
#endif
// Set current WD to new WD
thread->setCurrentWD( *wd );
......@@ -881,7 +912,12 @@ bool Scheduler::inlineWorkAsync ( WD *wd, bool schedule )
// This ensures that when we return from the inlining is still the same thread
// and we don't violate rules about tied WD
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
if ( oldwd->isTiedTo() != NULL && ( wd->isTiedTo() == NULL ) ) wd->tieTo( *oldwd->isTiedTo() );
#endif
//thread->setCurrentWD( *wd );
......@@ -982,7 +1018,12 @@ void Scheduler::switchToThread ( BaseThread *thread )
// Tie wd to target thread
WD *wd = myThread->getCurrentWD();
// Tied constraints produce problems with comm_thread modified
// scheduling
#if 0
wd->tieTo( *thread );
#endif
// Get a candidate to execute in current thread
WD *next = myThread->getTeam()->getSchedulePolicy().atYield( myThread, wd );
......