Exemple #1
0
 //--------------------------------------------------------------------------------
 void LogStream::write() const
 {
   if        (lssPerm.getMessageType() <  lssTemp.getMessageType()) {
     std::string msg = ": " + mBuf.str();
     locked_write(msg);
   } else if (lssPerm.getMessageType() == lssTemp.getMessageType() &&
              lssPerm.getSeverity   () <= lssTemp.getSeverity   ()) {
     std::string msg = ": " + mBuf.str();
     locked_write(msg);
   }
 }
Exemple #2
0
//--------------------------------------------------------------------------------
void LogStream::end_write()
{
  if(!myMaskEnabled()) return;

  std::string msg;
  msg  = "- [" + getSource() + "]";
  locked_write(msg);
}
Exemple #3
0
 //--------------------------------------------------------------------------------
 void LogStream::end_write() const
 {
   if(lssPerm.getMessageType() <= LT_DEBUG &&
      lssPerm.getSeverity   () <= LS_LOW) {
     std::string msg  = "- [" + getSource() + "]";
     locked_write(msg);
   }
 }
Exemple #4
0
void critical_section_init(CriticalSection* cs)
{
    locked_write(&cs->lock, 0);
    #ifdef RECURSIVE
    cs->owner = NULL;
    cs->counter = 0;
    #endif
    cs->waiter_chain = NULL;
}
Exemple #5
0
void critical_section_enter(CriticalSection* cs)
{
    while (EXPECT_FALSE(!critical_section_try_enter(cs))) {
        //cs ist gelockt, versuchen, waiter zu werden
        uint val = locked_read(&cs->lock);
        //0 und 3 wären auch noch möglich
        if (EXPECT_TRUE(val == 1 || val == 2)) {
            if (locked_cas(&cs->lock, val, 3)) {
                //geklappt; sind im spin-lock zustand
                //als warter einqueuen, und... warten
                /*volatile*/ struct Waiter puh;
                puh.thread = thread_get_current_handle();
                //cast entfernt warnung
                puh.next = (struct Waiter*)cs->waiter_chain;
                cs->waiter_chain = &puh;
                #ifdef TACTICAL_YIELD
                thread_yield();
                #endif
                assert(locked_read(&cs->lock) == 3);
                locked_write(&cs->lock, 2);
                //zwischen hier und jetzt könnten wir unterbrochen werden
                //  nicht schlimm, wenn der aufwecker einen blockierenden
                //  ipc call benutzt
                LipcMessage msg;
                msg.flags = LIPC_RECEIVE;
                bool res = sys_lipc(&msg);
                //"sparodische" msg ausschliessen
                assert(res && msg.word0 == SOME_MAGIC);
                if (msg.word1 == MSG_CRITICAL_SECTION_DESTROY) {
                    //sonderfall zur zerstörung eines mutex
                    #ifdef PRINT_DEBUG
                    printf("ÄRGS! TOT ZERSTÖRUNG!, thread %p by %p\n",
                        thread_get_current_handle(), msg.send_receive_handle);
                    #endif
                    //was soll ich machen?
                    assert(false);
                    return;
                }
                assert(msg.word1 == MSG_CRITICAL_SECTION_WAKEUP);
                #ifdef PRINT_DEBUG
                printf("woken up, thread %p by %p\n",
                    thread_get_current_handle(), msg.send_receive_handle);
                #endif
                //der aufwecker hat uns aus waiter queue entfernt
                //jetzt versuchen, lock wieder zu bekommen (yield überspringen)
                continue;
            }
        } else {
            assert(val == 0 || val == 3);
        }
        #ifdef PRINT_DEBUG
        printf("thread %p: SPIN lock\n", thread_get_current_handle());
        #endif
        thread_yield();
    }
}
Exemple #6
0
//--------------------------------------------------------------------------------
void LogStream::write()
{
  if(!myMaskEnabled()) return;

  std::string msg;

  msg  = ": " + mBuf.str();

  locked_write(msg);
  
  lssTemp.reset();
}
Exemple #7
0
bool critical_section_try_enter(CriticalSection* cs)
{
    #ifdef RECURSIVE
    if (EXPECT_FALSE(cs->owner == thread_get_current_handle())) {
        cs->counter++;
        return true;
    }
    #endif
    
    if (EXPECT_TRUE(locked_cas(&cs->lock, 0, 3))) {
        //mit 3 wird race condition verhindert:
        #ifdef RECURSIVE
        cs->owner = thread_get_current_handle();
        cs->counter = 1; //<- eig. keine synchr. notwendig
        #endif
        #ifdef TACTICAL_YIELD
        thread_yield();
        #endif
        assert(locked_read(&cs->lock) == 3);
        locked_write(&cs->lock, 1);
        return true;
    } else
        return false;
}
Exemple #8
0
void critical_section_leave(CriticalSection* cs)
{
    #ifdef RECURSIVE
    //annahme: wir besitzen die CS
    cs->counter--;
    if (EXPECT_FALSE(cs->counter != 0))
        //(und wir besitzen immer noch)
        return;
    
    //owner invalidieren (wird verwendet, um in _enter schnell zu erkennen, ob
    //  der lock besessen wird...)
    assert(cs->owner == thread_get_current_handle());
    cs->owner = NULL;
    #endif
    
    //schneller fall: 1->0
    //wenn wir owner sind, ist nur noch 1->2/3 möglich, ohne rückkehr zu 1...
    //  d.h. es reicht, wenn das der erste und letzte versuch für 1->0 ist.
    if (EXPECT_TRUE(locked_cas(&cs->lock, 1, 0)))
        return;
    
    //wir müssen andere thread aufwecken
    //einzige zustandsübergänge: 2->3 und 3->2 (nur wir können noch 3->0)
    while (EXPECT_FALSE(!locked_cas(&cs->lock, 2, 3))) {
        //zustand 3 ist eine art spinlock
        //etwas blöde, da es passieren kann, das der scheduler schon
        //  zurückschaltet, obwohl der andere thread noch nicht fertig ist
        //  mögliche lösung: spinlocker gibt seine thread id an...
        #ifdef PRINT_DEBUG
        printf("thread %p: SPIN release\n", thread_get_current_handle());
        #endif
        thread_yield();
    }
    
    #ifdef TACTICAL_YIELD
    thread_yield();
    #endif
    
    //wir sind im zustand 3, eine art spinlock zustand
    //waiter lesen und section komplett freigeben
    volatile struct Waiter* waiter = cs->waiter_chain;
    //auch wichtig
    #ifdef TACTICAL_YIELD
    thread_yield();
    #endif
    cs->waiter_chain = NULL;
    assert(locked_read(&cs->lock) == 3);
    locked_write(&cs->lock, 0);
    
    //waiter aufwecken
    //wir wecken alle auf; der scheduler entscheidet wer den zuschlag bekommt
    while (waiter) {
        #ifdef TACTICAL_YIELD
        thread_yield();
        #endif
        LipcMessage msg;
        #ifdef PRINT_DEBUG
        printf("thread %p: wake up %p\n", thread_get_current_handle(),
            waiter->thread);
        #endif
        volatile struct Waiter* next = waiter->next;
        msg.send_receive_handle = waiter->thread;
        msg.flags = LIPC_SEND;
        msg.word0 = SOME_MAGIC;
        msg.word1 = MSG_CRITICAL_SECTION_WAKEUP;
        bool res = sys_lipc(&msg);
        assert(res);
        waiter = next;
    }
    
    //erfolg; fertig
    return;
}