summaryrefslogtreecommitdiff
path: root/translate/grt/config
diff options
context:
space:
mode:
Diffstat (limited to 'translate/grt/config')
-rw-r--r--translate/grt/config/win32.c174
1 files changed, 53 insertions, 121 deletions
diff --git a/translate/grt/config/win32.c b/translate/grt/config/win32.c
index 80ea270..583b885 100644
--- a/translate/grt/config/win32.c
+++ b/translate/grt/config/win32.c
@@ -1,5 +1,5 @@
-/* GRT stack implementation for Win32
- Copyright (C) 2004, 2005 Felix Bertram.
+/* GRT stack implementation for Win32 using fibers.
+ Copyright (C) 2005 Tristan Gingold.
GHDL is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
@@ -16,139 +16,74 @@
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-//-----------------------------------------------------------------------------
-// Project: GHDL - VHDL Simulator
-// Description: Win32 port of stacks package
-// Note: Tristan's original i386/Linux used assembly-code
-// to manually switch stacks for performance reasons.
-// History: 2004feb09, FB, created.
-//-----------------------------------------------------------------------------
#include <windows.h>
-//#include <pthread.h>
-//#include <stdlib.h>
-//#include <stdio.h>
+#include <stdio.h>
+struct stack_type
+{
+ LPVOID fiber; // Win fiber.
+ void (*func)(void *); // Function
+ void *arg; // Function argument.
+};
-//#define INFO printf
-#define INFO (void)
-
-// GHDL names an endless loop calling FUNC with ARG a 'stack'
-// at a given time, only one stack may be 'executed'
-typedef struct
-{ HANDLE thread; // stack's thread
- HANDLE mutex; // mutex to suspend/resume thread
- void (*Func)(void*); // stack's FUNC
- void* Arg; // ARG passed to FUNC
-} Stack_Type_t, *Stack_Type;
-
-Stack_Type_t main_stack_context;
-extern Stack_Type grt_stack_main_stack;
+static struct stack_type main_stack_context;
+extern void grt_set_main_stack (struct stack_type *stack);
-//------------------------------------------------------------------------------
void grt_stack_init(void)
-// Initialize the stacks package.
-// This may adjust stack sizes.
-// Must be called after grt.options.decode.
-// => procedure Stack_Init;
-{ INFO("grt_stack_init\n");
- INFO(" main_stack_context=0x%08x\n", &main_stack_context);
-
- // create event. reset event, as we are currently running
- main_stack_context.mutex = CreateEvent(NULL, // lpsa
- FALSE, // fManualReset
- FALSE, // fInitialState
- NULL); // lpszEventName
-
- grt_stack_main_stack= &main_stack_context;
+{
+ main_stack_context.fiber = ConvertThreadToFiber (NULL);
+ if (main_stack_context.fiber == NULL)
+ {
+ fprintf (stderr, "convertThreadToFiber failed (err=%lu)\n",
+ GetLastError ());
+ abort ();
+ }
+ grt_set_main_stack (&main_stack_context);
}
-//------------------------------------------------------------------------------
-static unsigned long __stdcall grt_stack_loop(void* pv_myStack)
+static VOID __stdcall
+grt_stack_loop (void *v_stack)
{
- Stack_Type myStack= (Stack_Type)pv_myStack;
-
- INFO("grt_stack_loop\n");
-
- INFO(" myStack=0x%08x\n", myStack);
-
- // block until event becomes set again.
- // this happens when this stack is enabled for the first time
- WaitForSingleObject(myStack->mutex, INFINITE);
-
- // run stack's function in endless loop
- while(1)
- { INFO(" call 0x%08x with 0x%08x\n", myStack->Func, myStack->Arg);
- myStack->Func(myStack->Arg);
- }
-
- // we never get here...
- return 0;
+ struct stack_type *stack = (struct stack_type *)v_stack;
+ while (1)
+ {
+ (*stack->func)(stack->arg);
+ }
}
-//------------------------------------------------------------------------------
-Stack_Type grt_stack_create(void* Func, void* Arg)
-// Create a new stack, which on first execution will call FUNC with
-// an argument ARG.
-// => function Stack_Create (Func : Address; Arg : Address) return Stack_Type;
-{ Stack_Type newStack;
- DWORD m_IDThread; // Thread's ID (dummy)
-
- INFO("grt_stack_create\n");
- INFO(" call 0x%08x with 0x%08x\n", Func, Arg);
-
- newStack= malloc(sizeof(Stack_Type_t));
-
- // init function and argument
- newStack->Func= Func;
- newStack->Arg= Arg;
-
- // create event. reset event, so that thread will blocked in grt_stack_loop
- newStack->mutex= CreateEvent(NULL, // lpsa
- FALSE, // fManualReset
- FALSE, // fInitialState
- NULL); // lpszEventName
-
- INFO(" newStack=0x%08x\n", newStack);
-
- // create thread, which executes grt_stack_loop
- newStack->thread= CreateThread(NULL, // lpsa
- 0, // cbStack
- grt_stack_loop, // lpStartAddr
- newStack, // lpvThreadParm
- 0, // fdwCreate
- &m_IDThread); // lpIDThread
-
- return newStack;
+struct stack_type *
+grt_stack_create (void (*func)(void *), void *arg)
+{
+ struct stack_type *res;
+
+ res = malloc (sizeof (struct stack_type));
+ if (res == NULL)
+ return NULL;
+ res->func = func;
+ res->arg = arg;
+ res->fiber = CreateFiber (0, &grt_stack_loop, res);
+ if (res->fiber == NULL)
+ {
+ free (res);
+ return NULL;
+ }
+ return res;
}
-//------------------------------------------------------------------------------
-void grt_stack_switch(Stack_Type To, Stack_Type From)
-// Resume stack TO and save the current context to the stack pointed by
-// CUR.
-// => procedure Stack_Switch (To : Stack_Type; From : Stack_Type);
-{ INFO("grt_stack_switch\n");
- INFO(" from 0x%08x to 0x%08x\n", From, To);
-
- // set 'To' event. this will make the other thread either
- // - start for first time in grt_stack_loop
- // - resume at WaitForSingleObject below
- SetEvent(To->mutex);
-
- // block until 'From' event becomes set again
- // as we are running, our event is reset and we block here
- // when stacks are switched, with above SetEvent, we may proceed
- WaitForSingleObject(From->mutex, INFINITE);
+void
+grt_stack_switch (struct stack_type *to, struct stack_type *from)
+{
+ SwitchToFiber (to->fiber);
}
-//------------------------------------------------------------------------------
-void grt_stack_delete(Stack_Type Stack)
-// Delete stack STACK, which must not be currently executed.
-// => procedure Stack_Delete (Stack : Stack_Type);
-{ INFO("grt_stack_delete\n");
+void
+grt_stack_delete (struct stack_type *stack)
+{
+ DeleteFiber (stack->fiber);
+ stack->fiber = NULL;
}
-//----------------------------------------------------------------------------
#ifndef WITH_GNAT_RUN_TIME
void __gnat_raise_storage_error(void)
{
@@ -161,6 +96,3 @@ void __gnat_raise_program_error(void)
}
#endif
-//----------------------------------------------------------------------------
-// end of file
-