⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventbarrier.cc

📁 本次实验的目的在于掌握使用nachos中的线程序解决较为复杂的并发问题。实验内容分三部分:实现事件栅栏原语并进行正确性测试;实现闹钟原语并进行正确性测试;利用事件栅栏和闹钟原语来解决电梯问题(详细内容
💻 CC
字号:
#include "EventBarrier.h"
#include "system.h"
#include "copyright.h"

extern int threadnum;

EventBarrier::EventBarrier(char *debugname)
{
    name = debugname;
    state = UNSIGNALED;
    waitnum = 0;
    queue_signal = new List();
    queue_complete = new List();
}

EventBarrier::~EventBarrier()
{
    delete queue_signal;
    delete queue_complete;
}


//EventBarrier::signal()
//设置事件栅栏的状态为SIGNALED
//唤醒所有阻塞于Signal的线程
//阻塞于Complete
//恢复事件栅栏的状态为UNSIGNALED
void EventBarrier::Signal()
{
    Thread *thread;
    state = SIGNALED;
    IntStatus oldLevel = interrupt->SetLevel(IntOff);
    printf("Thread %d唤醒所有阻塞于Signal的线程\n",threadnum);
    while( (thread = (Thread *)queue_signal->Remove()) != NULL)
        scheduler->ReadyToRun(thread);
    printf("Thread %d阻塞于Complete\n",threadnum);
    queue_complete->Append((void *)currentThread);
    currentThread->Sleep();
    (void) interrupt->SetLevel(oldLevel);
    state = UNSIGNALED;
}


//EventBarrier::Wait()
//如果事件栅状态是SIGNALED,则直接返回
//否则,阻塞于signal
void EventBarrier::Wait()
{
    waitnum++;
    if(state == SIGNALED)
    {
        printf("事件栅状态是SIGNALED,直接返回\n");
        return;
    }
    else if(state == UNSIGNALED)
    {
        IntStatus oldLevel = interrupt->SetLevel(IntOff);
        printf("事件栅状态是UNSIGNALED,Thread %d阻塞于signal\n",threadnum);
        queue_signal->Append((void *)currentThread);
        currentThread->Sleep();
        (void) interrupt->SetLevel(oldLevel);
    }
}

//EventBarrier::Complete()
//如果是最后一个调用Complete者,则唤醒所有阻塞于Complete的线程
//否则,阻塞于Complete
void EventBarrier::Complete()
{
    Thread *thread;
    if(waitnum == 1)
    {
        IntStatus oldLevel = interrupt->SetLevel(IntOff);
        printf("Thread %d 是最后一个调用Complete的线程,唤醒所有阻塞于Complete的线程\n",threadnum);
        while( (thread = (Thread *)queue_complete->Remove()) != NULL)
            scheduler->ReadyToRun(thread);
        (void) interrupt->SetLevel(oldLevel);
    }
    else
    {
        waitnum--;
        IntStatus oldLevel = interrupt->SetLevel(IntOff);
        printf("Thread %d 不是最后一个调用Complete的线程,阻塞于Complete\n",threadnum);
        queue_complete->Append((void *)currentThread);
        currentThread->Sleep();
        (void) interrupt->SetLevel(oldLevel); 
    }
}

int EventBarrier::Waiters()
{
    return waitnum;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -