Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problem to use Mutex. #289

Closed
mengke-mk opened this issue Aug 5, 2016 · 5 comments
Closed

problem to use Mutex. #289

mengke-mk opened this issue Aug 5, 2016 · 5 comments

Comments

@mengke-mk
Copy link

I intend to use the following code to figure out how to lock a mutex, but...

#include <Grappa.hpp>
#include <unistd.h>

using namespace Grappa;

int main(int argc, char *argv[]){
    init(&argc, &argv);
    run([]{
        GlobalAddress<Mutex> x = make_global(new Mutex);
        on_all_cores([x]{
                delegate::call(x,[](Mutex *mu){ lock(mu); });
                sleep(2); // some computing ...
                delegate::call(x,[](Mutex *mu){ unlock(mu); });          
        });
    });
    finalize();
}

OK, so far so good, but I got the following errors when I use mpiexec -n 4 ./test to run this case.

F0805 21:12:16.028504 24754 TaskingScheduler.hpp:166] Check failed: in_no_switch_region_ == false (1 vs. 0) Trying to context switch in no-switch region
*** Check failure stack trace: ***
*** Aborted at 1470402736 (unix time) try "date -d @1470402736" if you are using GNU date ***
PC: @           0x44c548 google::DumpStackTrace()
    @           0x414071 Grappa::impl::failure_function()
    @           0x442d1b google::LogMessage::Fail()
    @           0x442c7a google::LogMessage::SendToLog()
    @           0x4426c6 google::LogMessage::Flush()
    @           0x4454bf google::LogMessageFatal::~LogMessageFatal()
    @           0x40b16f Grappa::lock<>()
    @           0x409670 _ZZN6Grappa4impl4callIZNS0_4callILNS_8SyncModeE0EXadL_ZNS0_9local_gceEEENS_5MutexEvZZZ4mainENKUlvE_clEvENKUlvE_clEvEUlPS4_E_EEDTclfp0_cldtfp_7pointerEEE13GlobalAddressIT1_ET3_MSD_KFT2_PSB_EEUlvE_EEvsT_MSJ_KFvvEENKUlvE_clEv
    @           0x4096a3 _ZN6Grappa7MessageIZNS_4impl4callIZNS1_4callILNS_8SyncModeE0EXadL_ZNS1_9local_gceEEENS_5MutexEvZZZ4mainENKUlvE_clEvENKUlvE_clEvEUlPS5_E_EEDTclfp0_cldtfp_7pointerEEE13GlobalAddressIT1_ET3_MSE_KFT2_PSC_EEUlvE_EEvsT_MSK_KFvvEEUlvE_E15deliver_locallyEv
    @           0x41fe47 Grappa::impl::RDMAAggregator::deliver_locally()
    @           0x4156f5 poller()
    @           0x432bfe Grappa::impl::tramp()
    @           0x43946c (unknown)
I0805 21:12:16.037377 24754 Grappa.cpp:262] Exiting via failure function

Did I do something wrong?

@nelsonje
Copy link
Member

nelsonje commented Aug 5, 2016

Delegate operations can't contain blocking code---the lock() call may block. You can wrap it in a spawn() call to spawn a new task, which will be able to block.

@bholt
Copy link
Member

bholt commented Aug 5, 2016

There's also the version of call that takes a Mutex of some sort and creates a heap-allocated continuation if it has to block: https://github.com/uwsampa/grappa/blob/master/system/Delegate.hpp#L159

I can't find any instances where it was used. I think I planned to use it in GlobalVector, but ended up manually using SuspendedDelegate: https://github.com/uwsampa/grappa/blob/master/system/GlobalVector.hpp#L146

We do have an alternate version of call that creates a task so it can be suspended, but as the documentation for that method indicates, this can be a problem because there's a chance of running out of workers, leading to deadlock (which happened frequently whenever I tried spawning dependent tasks inside of other tasks), so I encourage you to tread very lightly there.

@mengke-mk
Copy link
Author

mengke-mk commented Aug 6, 2016

@bholt could you show me a example how to use the version of call that takes a Mutex to try lock on remote mutex? I am confused about the way this functions works after reading the code.
Actually, I just want a function that lock( GlobalAddress<Mutex> m ) does, but I found that I can't use this function to lock on remote mutex since there is just a CHECK(false).
https://github.com/uwsampa/grappa/blob/master/system/Mutex.hpp#L106

@bholt
Copy link
Member

bholt commented Aug 6, 2016

It's definitely pretty wonky. I meant to wrap it in some nicer functions but never got around to it. It was intended to be as general-purpose as possible, so it takes 2 lambdas: one lambda is like a delegate, but its only purpose is to return a pointer to the Mutex that you want to lock/wait on. Then, when the mutex is unlocked, the second lambda parameter will get invoked, which should probably lock the mutex. But due to me being lazy a long time ago, you also have to return something non-void. So, long story short, I think this should work to do a remote lock as a blocking delegate:

GlobalAddress<Mutex> mptr = /* get global address somehow */;
bool result = delegate::call(mptr.core(),
  // runs on remote node; computes local pointer to mutex
  // (in this case just getting the pointer component of the
  // GlobalAddress, but could be whatever you want)
  [mptr]{ return mptr.pointer(); },
  // runs once the mutex is unlocked; should probably lock it,
  // but then you can also do whatever other work you want,
  // such as returning a value from this remote node. 
  // in this case I just return "true" (have to return something)
  [](Mutex* m){
    lock(m);
    return true;
  });

(caveat: I haven't tested this beyond making sure it compiles)

@mengke-mk
Copy link
Author

mengke-mk commented Aug 8, 2016

So, this function must return something non-void? Now I know how to deal with my remote mutex, Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants