Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sources/kernel/include/drivers/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class CGPIO_Handler

// pocka na udalost (zablokuje proces)
void Wait_For_Event(IFile* file, uint32_t pin);

// zrusi "registraci" cekani procesu
void Cancel_Wait_For_Event(IFile *file, uint32_t pin);
};

// globalni instance pro hlavni GPIO port
Expand Down
16 changes: 14 additions & 2 deletions sources/kernel/include/fs/drivers/gpio_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,24 @@ class CGPIO_File final : public IFile
return false;
}

virtual void Wait_Enqueue_Current() override
{
IFile::Wait_Enqueue_Current();
sGPIO.Wait_For_Event(this, mPinNo);
}

virtual bool Wait_Dequeue_Process(uint32_t pid) override
{
// je treba odregistrovat i u GPIO handleru, pokud je tam zaregistrovan
sGPIO.Cancel_Wait_For_Event(this, mPinNo);
return IFile::Wait_Dequeue_Process(pid);
}

virtual bool Wait(uint32_t count) override
{
Wait_Enqueue_Current();
sGPIO.Wait_For_Event(this, mPinNo);

// zablokujeme, probudi nas az notify
// zablokujeme, probudi nas az notify
sProcessMgr.Block_Current_Process();
return true;
}
Expand Down
13 changes: 9 additions & 4 deletions sources/kernel/include/fs/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class IFile

spinlock_t mWait_Lock;

protected:
void Wait_Enqueue_Current();

public:
IFile(NFile_Type_Major type) : mType(type) { spinlock_init(&mWait_Lock); };
virtual ~IFile() = default;
Expand All @@ -77,11 +74,19 @@ class IFile
virtual bool IOCtl(NIOCtl_Operation dir, void* ctlptr) { return false; };
// vycka na udalost nad timto souborem (specificke pro danou implementaci)
virtual bool Wait(uint32_t count) { return true; };
// pokusí se získat resource bez blokování; vrací true pokud se podařilo získat resource, false s přípravou na čekání pokud ne
virtual bool TryWaitAllReserve(uint32_t count) { return false; };
// získá resource po notifikaci (je použito po notikaci z WaitAll volani)
virtual bool WaitAllAcquire(uint32_t count) { return true; };

// notifikuje <count> cekajici nad timto souborem (pokud nejaky cekajici je)
virtual uint32_t Notify(uint32_t count);

// zjisti typ souboru
virtual void Wait_Enqueue_Current();
// odstraneni zadaneho procesu ze seznamu cekajicich bez probouzeni
virtual bool Wait_Dequeue_Process(uint32_t pid);

// zjisti typ souboru
NFile_Type_Major Get_File_Type() const { return mType; };

// TODO: seek, atd...
Expand Down
2 changes: 2 additions & 0 deletions sources/kernel/include/process/condvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,7 @@ class CCondition_Variable : public IFile
virtual bool IOCtl(NIOCtl_Operation dir, void* ctlptr) override { return false; };

virtual bool Wait(uint32_t count) override;
virtual bool TryWaitAllReserve(uint32_t count) override;
virtual bool WaitAllAcquire(uint32_t count) override;
virtual uint32_t Notify(uint32_t count);
};
2 changes: 2 additions & 0 deletions sources/kernel/include/process/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@ class CMutex : public IFile
virtual bool IOCtl(NIOCtl_Operation dir, void* ctlptr) override { return false; };

virtual bool Wait(uint32_t count) override { return Lock(); }
virtual bool TryWaitAllReserve(uint32_t count) override;
virtual bool WaitAllAcquire(uint32_t count) override;
virtual uint32_t Notify(uint32_t count) { return Unlock(); };
};
1 change: 1 addition & 0 deletions sources/kernel/include/process/pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ class CPipe final : public IFile
virtual uint32_t Write(const char* buffer, uint32_t num) override;
virtual bool Close() override;
virtual bool Wait(uint32_t count) override;
virtual bool TryWaitAllReserve(uint32_t count) override;
virtual uint32_t Notify(uint32_t count) override;
};
3 changes: 3 additions & 0 deletions sources/kernel/include/process/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ struct TTask_Struct
unsigned int sched_counter; // pocitadlo - jakmile je proces naplanovan, zkopiruje se do nej priorita a kazdy tik casovace snizuje toto cislo o 1; na 0 se preplanuje na jiny proces
unsigned int sched_static_priority; // staticka priorita procesu (dana pri jeho vytvareni)
IFile* opened_files[Max_Process_Opened_Files]; // otevrene soubory; index je zaroven handle
uint32_t multi_wait_fd_bitmap; // bitmapa souboru, na ktere proces ceka pri WaitAll - cekani na vice souboru najednou
bool is_multi_file_wait; // indikuje, ze proces ceka na vice souboru najednou (WaitAll)
uint32_t multi_wait_ready_fd; // soubor, ktery byl prvni pripraven k operaci pri cekani na vice souboru (WaitAll)
int exit_code; // navratovy kod procesu; nastaveny pri volani terminate nebo pri vyvolanem data/prefetch abortu a jinych
uint32_t sleep_timer; // casovac pro uspane procesy - jakmile systemovy citac prekroci tuto hodnotu, proces je odblokovan
// maximalni podporovany rozsah cekani je 0x7FFFFFFF, jelikoz muze citac pretect; diference je vzdy pocitana i s moznosti preteceni
Expand Down
5 changes: 4 additions & 1 deletion sources/kernel/include/process/process_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class CProcess_Manager
// blokuje soucasny proces (zatim v generickem stavu "Blocked"), preplanuje na jiny proces
void Block_Current_Process();
// notifikuje blokovany proces (napr. spici nad mutexem, souborem, ...)
bool Notify_Process(uint32_t pid);
bool Notify_Process(uint32_t pid, IFile* notifier_file);

// namapuje otevreny soubor na handle
uint32_t Map_File_To_Current(IFile* file);
Expand All @@ -90,6 +90,9 @@ class CProcess_Manager

// ziska info z planovace
bool Get_Scheduler_Info(NGet_Sched_Info_Type type, void* target);

// zpracuje WaitAll syscall
void Handle_WaitAll_SWI(uint32_t r0, uint32_t r1, uint32_t r2, TSWI_Result &target);
};

extern CProcess_Manager sProcessMgr;
2 changes: 2 additions & 0 deletions sources/kernel/include/process/semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ class CSemaphore final : public IFile
virtual uint32_t Write(const char* buffer, uint32_t num) override;
virtual bool Close() override;
virtual bool Wait(uint32_t count) override;
virtual bool TryWaitAllReserve(uint32_t count) override;
virtual bool WaitAllAcquire(uint32_t count) override;
virtual uint32_t Notify(uint32_t count) override;
};
5 changes: 5 additions & 0 deletions sources/kernel/include/process/swi.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ enum class NSWI_Filesystem_Service
// IN: r0 = handle otevreneho souboru, r1 = pocet zdroju, r2 = nova deadline po probuzeni (nebo Deadline_Unchanged pokud se nema menit, nebo Indefinite pokud se ma zrusit)
// OUT: r0 = indikator uspechu (NSWI_Result_Code)
Wait = 6,

// Cekani na udalost nad vice soubory najednou
// IN: r0 = pole handlu otevrenych souboru, nad kterymi se ceka, r1 = pocet handlu v poli, r2 = nova deadline po probuzeni (nebo Deadline_Unchanged pokud se nema menit, nebo Indefinite pokud se ma zrusit)
// OUT: r0 = handle souboru, kvuli kteremu je proces probuzen nebo Invalid_Handle pri chybe/problemu
WaitAll = 7,
};

// mozne IOCtl operace nad souborem
Expand Down
34 changes: 33 additions & 1 deletion sources/kernel/src/drivers/gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ void CGPIO_Handler::Enable_Event_Detect(uint32_t pin, NGPIO_Interrupt_Type type)
if (!Get_GP_IRQ_Detect_Location(pin, type, reg, bit))
return;

mGPIO[reg] = (1 << bit);
mGPIO[reg] |= (1 << bit);

// TODO: vyresit tohle trochu lepe
sInterruptCtl.Enable_IRQ(hal::IRQ_Source::GPIO_0);
Expand Down Expand Up @@ -248,11 +248,43 @@ void CGPIO_Handler::Wait_For_Event(IFile* file, uint32_t pin)
wf->prev = nullptr;
wf->next = mWaiting_Files;

if (mWaiting_Files)
mWaiting_Files->prev = wf;

mWaiting_Files = wf;

spinlock_unlock(&mLock);
}

void CGPIO_Handler::Cancel_Wait_For_Event(IFile* file, uint32_t pin) {
spinlock_lock(&mLock);

TWaiting_File* wf = mWaiting_Files;
TWaiting_File* tmpwf;

while (wf != nullptr) {
if (wf->file == file && wf->pin_idx == pin) {
if (wf->prev)
wf->prev->next = wf->next;
if (wf->next)
wf->next->prev = wf->prev;

tmpwf = wf;

if (mWaiting_Files == wf)
mWaiting_Files = wf->next;

wf = wf->next;

delete tmpwf;
} else {
wf = wf->next;
}
}

spinlock_unlock(&mLock);
}

void CGPIO_Handler::Handle_IRQ()
{
TWaiting_File* wf, *tmpwf;
Expand Down
32 changes: 31 additions & 1 deletion sources/kernel/src/fs/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,36 @@ void IFile::Wait_Enqueue_Current()
spinlock_unlock(&mWait_Lock);
}

bool IFile::Wait_Dequeue_Process(uint32_t pid) {
spinlock_lock(&mWait_Lock);

TWaiting_Task* itr = mWaiting_Tasks;
bool found = false;

while (itr) {
if (itr->pid == pid) {
found = true;

if (itr->prev) {
itr->prev->next = itr->next;
} else {
mWaiting_Tasks = itr->next;
}

if (itr->next) {
itr->next->prev = itr->prev;
}

delete itr;
break;
}
itr = itr->next;
}

spinlock_unlock(&mWait_Lock);
return found;
}

uint32_t IFile::Notify(uint32_t count)
{
spinlock_lock(&mWait_Lock);
Expand All @@ -203,7 +233,7 @@ uint32_t IFile::Notify(uint32_t count)
uint32_t notified_count = 0;
while (itr && notified_count < count)
{
sProcessMgr.Notify_Process(itr->pid);
sProcessMgr.Notify_Process(itr->pid, this);

tmp = itr;

Expand Down
10 changes: 10 additions & 0 deletions sources/kernel/src/process/condvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ bool CCondition_Variable::Wait(uint32_t count)
return true;
}

bool CCondition_Variable::TryWaitAllReserve(uint32_t count) {
mMutex->Unlock();
return false;
}

bool CCondition_Variable::WaitAllAcquire(uint32_t count) {
mMutex->Lock();
return true;
}

uint32_t CCondition_Variable::Notify(uint32_t count)
{
return IFile::Notify(count);
Expand Down
20 changes: 20 additions & 0 deletions sources/kernel/src/process/mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ bool CMutex::Lock()
return true;
}

bool CMutex::TryWaitAllReserve(uint32_t count) {
auto* cur = sProcessMgr.Get_Current_Process();
const unsigned int cpid = cur->pid;

// tady vracím true, protože proces už mutex drží
if (mHolder_PID == cpid)
return true;

if (spinlock_try_lock(&mLock_State) == Lock_Locked)
return false;

mHolder_PID = cpid;
return true;
}

bool CMutex::WaitAllAcquire(uint32_t count) {
// udela to same jako TryWaitAllReserve, pokusi se zamknout mutex
return TryWaitAllReserve(count);
}

bool CMutex::Try_Lock()
{
auto* cur = sProcessMgr.Get_Current_Process();
Expand Down
14 changes: 14 additions & 0 deletions sources/kernel/src/process/pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ bool CPipe::Wait(uint32_t count)
return true;
}

bool CPipe::TryWaitAllReserve(uint32_t count) {
spinlock_lock(&mBuffer_Lock);

if (mSem_Busy->Get_Current_Count() >= count)
{
spinlock_unlock(&mBuffer_Lock);
return true;
}

spinlock_unlock(&mBuffer_Lock);
return false;
}


uint32_t CPipe::Notify(uint32_t count)
{
return IFile::Notify(count);
Expand Down
Loading