> - is the handler executed in the goroutine of the target? That's the idea yes.
> But then how does that interact with the goroutine which is already running? Does it only execute when the goroutine is next blocked in a select { }, for example? In that case, why not just add a new branch to the select? This does not act as a channel at all, this would be a sort of new primitive I suppose? It would require some help from the scheduler to manage the handling of it, but yes it would only happen when the goroutine blocks, sleeps, or is otherwise in a state of waiting. I believe C# uses the underlying OS to achieve something similar: https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.interrupt?view=net-6.0 An issue I can see with this now is that it may leave the signallee in an unknown or undesired state which could easily lead to bugs. Additionally, it seems C# uses exceptions to achieve this feat. Further, the concurrency of Go might be cluttered by adding issues of reentrancy into the mix, something that doesn't really occur with non-interruptible goroutines. In any case, I've done some more thinking and decided that my issue would currently best be solved with partial usage of something like a `TryMutex`. With very careful implementation, I still believe signalling would be a valuable addition to the language. On Thursday, March 17, 2022 at 9:19:26 AM UTC+1 Brian Candler wrote: > I don't understand the semantics of this. At what point is the handler > function executed and in which goroutine? In other words, when you call `s > := sig h 1`: > > - is the handler executed in the goroutine of the caller? Then how is it > different from `s := h(1)` ? > - is the handler executed in the goroutine of the target? But then how > does that interact with the goroutine which is already running? Does it > only execute when the goroutine is next blocked in a select { }, for > example? In that case, why not just add a new branch to the select? > - is the handler executed asynchronously in a completely new goroutine? > Then how is it different from this? > > go func() { c<-h(1) } > s := <-c > > > On Thursday, 17 March 2022 at 01:36:50 UTC mumbling...@gmail.com wrote: > >> 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/88c02d75-0f7c-4700-aca0-7e660178513cn%40googlegroups.com.