diff options
author | gingold | 2005-12-20 15:05:23 +0000 |
---|---|---|
committer | gingold | 2005-12-20 15:05:23 +0000 |
commit | 517a3edcd4d7d97cdfe3301e362859eb816aeb29 (patch) | |
tree | 252ea5dd1b5d37e536395f5842a75a6fcb8ccb56 /translate/grt/config | |
parent | cb45d7c240f4aabbd1dd716dd8bf7ab5b2107ff2 (diff) | |
download | ghdl-517a3edcd4d7d97cdfe3301e362859eb816aeb29.tar.gz ghdl-517a3edcd4d7d97cdfe3301e362859eb816aeb29.tar.bz2 ghdl-517a3edcd4d7d97cdfe3301e362859eb816aeb29.zip |
bugs fix for ghw writer
Diffstat (limited to 'translate/grt/config')
-rw-r--r-- | translate/grt/config/win32.c | 174 |
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 - |