0
void Mythread::threadSchedule(int n)
{
    if(threadMap_.size() > 1)
    {
        int lastId = current_;  
        if(current_ != (--threadMap_.end())->first)
        {
            auto it = threadMap_.find(current_);
            current_ = (++it)->first;
        }
        else
        {
            current_ = threadMap_.begin()->first;
        }

        swapcontext(threadMap_[lastId].get(),threadMap_[current_].get());
    }
}

I recently saw a user-level thread implemented with ucontext, I just don't understand how the threads switch. In the code above, after this swapcontext done its job, the context of threadMap_[lastId].get()rather should be inside the threadSchedule? But the context is in the thread with lastID break point. It's just so confused that "current context" which swapcontext(ucontext_t *oucp, ucontext_t *ucp) saved to the oucp is not the context inside the function threadSchedule(int n) now but the old thread's context. The whole code is in https://github.com/Miaoshuai/Coroutine

Deateg
  • 1
  • 1
  • I'd remove it. From [`swapcontext`](https://linux.die.net/man/3/swapcontext): "_Conforming To: SUSv2, POSIX.1-2001. POSIX.1-2008 removes the specifications of `makecontext()` and `swapcontext()`, citing portability issues, and recommending that applications be rewritten to use POSIX threads instead._" – Ted Lyngmo Oct 27 '20 at 10:46
  • Thanks, I know what it is, but I just don't understand the code above – Deateg Oct 27 '20 at 10:49
  • It looks like a manually implemented thread scheduler and `swapcontext` activates the thread in `threadMap_[current_]`. – Ted Lyngmo Oct 27 '20 at 10:52
  • I took a look at the code and it looks pretty incomplete so I assume that you don't have any dependencies to it? I'd just drop it and use the thread support in the standard library instead. – Ted Lyngmo Oct 27 '20 at 11:01
  • Right, and what about the ucontext of threadMap_[lastId]?I thought it is the context inside the Mythread::threadSchedule, but actually it's the thread's context. – Deateg Oct 27 '20 at 11:03
  • Yes, I know that. I recently have a work related to this, I want to figure out it, but i stuck in the thread switch with ucontext. – Deateg Oct 27 '20 at 11:06
  • The context stored in the `std::map> threadMap_` with `threadMap[lastId].get()` is the previously active context. – Ted Lyngmo Oct 27 '20 at 11:11
  • thanks, bro, but why is that? "The swapcontext() function saves the current context in the structure pointed to by oucp, and then activates the context pointed to by ucp." The current context is the context of Mythread::threadSchedule(int n), isn't it? – Deateg Oct 27 '20 at 11:20
  • I'm not sure I follow what you mean. The `n` isn't used. What the function does (badly) is to pick the next thread from its map and make it active and storing the previosly active threads context in its place in the map. The whole `if ... else ...` could be rewritten: `int lastId = current_; current_ = (current_ + 1) % threadMap.size(); swapcontext(threadMap_[lastId].get(),threadMap_[current_].get());` if I read it correctly. It's a mystery why it's using such a relatively expensive construct as a `map` to do something a simple `vector` would do better. – Ted Lyngmo Oct 27 '20 at 11:36
  • Thanks for your time. I think my expressions is too bad. What I mean is why "The context stored in the std::map> threadMap_ with threadMap[lastId].get() is the previously active context", since now the program is running in another function which is the threadSchedule, than the current context save by swapcontext() in threadMap_[lastId].get() still related to the previously active thread? – Deateg Oct 27 '20 at 11:59
  • If I understand you correctly, then yes. `swapcontext` will in fact not return until the next time the old context is made active again. I just noticed that there's an example program at the `man` page for `swapcontext`. It should make it clear. – Ted Lyngmo Oct 27 '20 at 12:08
  • Thanks a lot! I might understand a little bit. It's just so confused that "current context" which swapcontext(ucontext_t *oucp, ucontext_t *ucp) saved to the oucp is not the context inside the function threadSchedule(int n) now but the old thread's context. – Deateg Oct 27 '20 at 12:43
  • You're welcome! The way I interpret it is that is indeed the context within the `threadSchedule` function that is saved in `oucp`. I may have misunderstood you earlier. I'd just copy the program example they have there and play around with it some to get the hang of it. – Ted Lyngmo Oct 27 '20 at 13:00

0 Answers0