📄 win32.c
字号:
/* GRT stack implementation for Win32 Copyright (C) 2004, 2005 Felix Bertram. 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 Software Foundation; either version 2, or (at your option) any later version. GHDL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free 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>//#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;//------------------------------------------------------------------------------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;}//------------------------------------------------------------------------------static unsigned long __stdcall grt_stack_loop(void* pv_myStack){ 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;}//------------------------------------------------------------------------------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;}//------------------------------------------------------------------------------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_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 __gnat_raise_storage_error(void){ abort ();}void __gnat_raise_program_error(void){ abort ();}//------------------------------------------------------------------------------// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -