Multiple stack pointers in a single Process / AppDomain

M.S 21 Reputation points
2022-06-24T18:47:05.74+00:00

Hi all,

I have a question about whether the .NET CLR supports having multiple stacks within an application. By stack, I mean the idea of storage, usually growing downwards in memory, for holding function/procedure arguments, return values, local variables etc.

First, I should give some background on what I'm doing:

I've written a parser for a subset of VHDL that builds an abstract representation of design unit (VHDL's term for a compiled file).

I'm now considering how to implement code generation on top of the .NET CLR so that I can run the compiled VHDL in similar way to what a simulator such as GHDL, ModelSim, QuestaSim, Riviera Pro etc. would do.

In VHDL, a design unit may have multiple "processes" (not be confused with the programming idea of a process). The execution model is that, logically, a process may run concurrently with other processes, but in most implementations all processes are actually executed in the context of a single thread, which switches between processes at certain points during their execution. There are various reasons for this, and I can't explain them succinctly here, so please take my word for that.

This means that each process requires its own stack and stack pointer. If process A gets suspended, the (single) thread of execution will switch to another process B and start using B's stack pointer. In this way, a single thread can execute all processes in a design unit without corrupting their stacks.

So my question is this:

Does the .NET CLR have any way to create multiple stacks within an application, and is there a mechanism by which a thread within the application can change the stack that is using on the fly?

.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,141 questions
0 comments No comments
{count} votes

4 additional answers

Sort by: Most helpful
  1. M.S 21 Reputation points
    2022-06-24T20:24:04.067+00:00

    Hi Bruce,

    Thanks for the answer. Yes, I think I probably am trying to implement a form of coroutine.

    Having looked at what opcodes exist, it seems to me that implementing a language that has coroutines using .NET IL as the underlying machine is possible, but not in a natural way that maps well to the IL execution model.

    I'll consider other approaches, such as generating x86_64 machine code.

    0 comments No comments

  2. Bruce (SqlWork.com) 61,731 Reputation points
    2022-06-25T14:55:15.57+00:00

    Here is an implementation of coroutines using async enumerators

    https://dev.to/noseratio/asynchronous-coroutines-with-c-8-0-and-iasyncenumerable-2e04

    0 comments No comments

  3. M.S 21 Reputation points
    2022-06-26T11:30:55.28+00:00

    Hi Bruce,

    I did see that article when Googling the subject. However, it doesn't look very performant! I'm writing a compiler, so I need to implement a coroutine mechanism that will have low time cost. Space cost is also a consideration, but a secondary one.

    In any case, I believe I have come up with a way to do that on top of .NET IL - on entry to a process (a.k.a. coroutine) I have IL code implementing a switch to the appropriate point in the method that implements the process. The appropriate point is determined by the process's state (is it resuming from suspension etc.).

    The .NET stack is used only for making non-coroutine calls (guaranteed not to result in suspension of the process). Each process has its own stack, allocated from the heap, for coroutine calls and local variables that must persist when the coroutine is suspended.

    This is about the most efficient scheme I could come up with given the constraints of the execution model of the .NET IL.

    Thanks.

    0 comments No comments

  4. Bruce (SqlWork.com) 61,731 Reputation points
    2022-06-26T16:12:08.747+00:00

    The most common implementation of coroutines in high level languages is the generator/yield pattern. See this thread for implementation

    https://stackoverflow.com/questions/1596863/working-pattern-of-yield-return

    0 comments No comments