SB16: Use a snooze alarm to block the current thread while playing.

This commit is contained in:
Andreas Kling 2019-07-13 20:15:17 +02:00
parent 54e79a4640
commit dcfa93e71f
2 changed files with 29 additions and 7 deletions

View file

@ -1,5 +1,6 @@
#include "SB16.h"
#include "IO.h"
#include <Kernel/Devices/SB16.h>
#include <Kernel/IO.h>
#include <Kernel/Thread.h>
#include <Kernel/VM/MemoryManager.h>
//#define SB16_DEBUG
@ -48,6 +49,7 @@ static SB16* s_the;
SB16::SB16()
: IRQHandler(5)
, CharacterDevice(42, 42) // ### ?
, m_interrupt_alarm(*this)
{
s_the = this;
initialize();
@ -141,11 +143,7 @@ void SB16::wait_for_irq()
#ifdef SB16_DEBUG
kprintf("SB16: waiting for interrupt...\n");
#endif
// FIXME: Add timeout.
while (!m_interrupted) {
// FIXME: Put this process into a Blocked state instead, it's stupid to wake up just to check a flag.
Scheduler::yield();
}
current->snooze_until(m_interrupt_alarm);
#ifdef SB16_DEBUG
kprintf("SB16: got interrupt!\n");
#endif
@ -196,3 +194,8 @@ ssize_t SB16::write(FileDescription&, const u8* data, ssize_t length)
wait_for_irq();
return length;
}
bool SB16InterruptAlarm::is_ringing() const
{
return m_device.got_interrupt({});
}

View file

@ -1,11 +1,26 @@
#pragma once
#include <AK/CircularQueue.h>
#include <Kernel/Alarm.h>
#include <Kernel/Devices/CharacterDevice.h>
#include <Kernel/IRQHandler.h>
#include <Kernel/VM/PhysicalAddress.h>
#include <Kernel/VM/PhysicalPage.h>
class SB16;
class SB16InterruptAlarm final : public Alarm {
public:
SB16InterruptAlarm(SB16& device)
: m_device(device)
{
}
virtual bool is_ringing() const override;
private:
SB16& m_device;
};
class SB16 final : public IRQHandler
, public CharacterDevice {
public:
@ -20,6 +35,8 @@ public:
virtual ssize_t write(FileDescription&, const u8*, ssize_t) override;
virtual bool can_write(FileDescription&) const override { return true; }
bool got_interrupt(Badge<SB16InterruptAlarm>) const { return m_interrupted; }
private:
// ^IRQHandler
virtual void handle_irq() override;
@ -37,4 +54,6 @@ private:
RefPtr<PhysicalPage> m_dma_buffer_page;
bool m_interrupted { false };
int m_major_version { 0 };
SB16InterruptAlarm m_interrupt_alarm;
};