I'm currently working on a project where I emulate a RISC-V processor for 
the purpose of using Go when teaching concepts of operating systems.
I'd like for the emulator to resemble a "real" processor to the point that 
a realistic operating system can be implemented with most of the 
interesting challenges that this encompasses.
One of these challenges is the management of translation caches across 
multiple cores which may sometimes require TLB shootdowns.

A quick summary of TLB shootdowns: process P has two threads T1 and T2 that 
run on cores A and B respectively.
When T1 makes a request to deallocate a page, core A has to ensure that T2 
on core B invalidates some cached translations before it marks the page as 
free, lest B (executing T2) might find the translation in cache and write 
to a page that T2 no longer should have access to.

My current approach to this is that instead of using a `sync.Mutex` and 
`Lock()`, I have created a custom `UntilLock(f func())` which takes in a 
function that should be repeatedly executed until the lock is acquired.

Current implementation: https://pastecord.com/hofoloxuru.go

Notice that every mutex where a `Lock`-`Unlock`-pair might wrap an 
interrupt, has to use the `UntilLock` as a `Lock` might cause the goroutine 
to block and never check interrupts.
The issue is further complicated if one resource R might be locked in 
function F and another resource S is locked in function G.
In this case, goroutine A might enter F, successfully acquire R, then 
signal goroutine B.
At the same time, B enters G, successfully acquires S, then signals 
goroutine A.
We have a deadlock.
This is pretty easily resolved though as we just add the interrupt check to 
the loop where F and G wait for the other goroutine to execute their 
handlers.

An idea came to me though...
Life would be much easier if Go had signalling between goroutines.
One could extend the syntax as `h := go f() handler` where `handler`
would have the signature: `func handler(signal int)`
You would then signal it with something like `s := sig h 1` to send a 
signal of 1 to the goroutine associated with h.

Idea for how code would look with signalling: 
https://pastecord.com/qunyqejexo.go

This would completely eliminate the issue I am currently facing and though 
I'm no expert in the field, I believe Go's scheduler could make the 
implementation require very little effort and the overhead would be 
practically non-existent.
This signalling would look a lot like OS signals and is a powerful feature 
that isn't too complex in my opinion.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/128eaa6e-dbaf-45c9-acef-a9c8aeaef251n%40googlegroups.com.

Reply via email to