⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel.c

📁 adios在windows的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************
 * Simulated Kernel Environment      *
 * Beta 2 (01-11-2001)               *
 * Copyright (c) 2001 Adrian O'Grady *
 *************************************/

// configure the kernel source code
#include "settings.h"

// We don't need most of the win32 stuff (I hope)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <windows.h>
#include "resource.h"

#include <stdio.h>
#include <stdlib.h>


// Defines all the functions of the kernel
#include "kernapi.h"

// Main event functions
BOOL CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK SemDialogFunc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

// Kernel helper functions
void StartKernel(void);
int  GetThreadIndex(HANDLE hand);
int  GetSemaphoreIndex(HANDLE hand);
int  GetTimerIndex(unsigned int ID);
long InitComPort(void);
void FireTimers(void);

// Event functions
void OnGarbageCollection(void);

void OnFrmMain_KillThread(void);
void OnFrmMain_PauseOutput(void);
void OnFrmMain_PauseThread(void);
void OnFrmMain_ResetThread(void);
void OnFrmMain_SelChange(void);
void OnFrmMain_StartKernel(void);

void OnFrmSem_Release(void);
void OnFrmSem_Wait(void);
void OnFrmSem_WindowInit(void);


// Global variables
char szWinName[] = "Win32AdiOS";

HINSTANCE g_hInst;		// Instance of the application
HICON hIconLarge;		// Large Icon for the app
HICON hIconSmall;		// Small icon for the dialog window
HWND g_hwnd;			// Handle to the Dialog window
HWND g_hwndSem;			// Handle to the semaphore window

// Kernel control
BOOL g_KernelStarted;	// Has the kernel started or not?
BOOL g_PauseOutput;		// Is output paused or not?
BOOL g_SemWindowOpen;

// Threading bits
struct TL {
	HANDLE handle;				// The thread handle
	BOOL Running;				// Thread status
	void * (*lpFunc)(__int32);	// Entry function
	__int32 param;				// Parameter
};

HANDLE g_hThreadSem;	// Semaphore for locking the thread list when making changes
int g_Threads;			// How many threads have started?
struct TL ThreadList[ADIOS_THREADS_MAX];	// List of running threads

struct SL {
	HANDLE handle;				// The semaphore handle
	int Value;					// The current semaphore value
	int MaxValue;				// The maximum semaphore value
};

int g_Semaphores;		// How many semaphores have been created
struct SL SemaphoreList[ADIOS_SEMAPHORES_MAX];	// List of semaphores

// Timer bits
struct TML {
	unsigned int ID;						// The timer ID
	void (*lpFunc)(void);		// The timer call function
	int CurrentTime;			// The current value of the timer
	int Interval;				// The interval between timer events
};

HANDLE g_hTimerSem;			// Semaphore for locking the timer list
int g_Timers;				// How many timers are there
unsigned int g_NextTimer;	// The next timer ID to assign
struct TML TimerList[ADIOS_TIMERS_MAX];	// List of timers

// Com port globals
HANDLE g_com;

// This is where it all begins
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
	// Load the icons
	hIconLarge = LoadIcon(hThisInst, "IDI_ICON");
	hIconSmall = LoadIcon(hThisInst, "IDI_ICONSM");
	g_hInst = hThisInst; /* Save the current instance handle */
	g_PauseOutput = FALSE;
	g_KernelStarted = FALSE;
	g_SemWindowOpen = FALSE;
	g_NextTimer = 1;

	// Create the thread semaphore
	g_hThreadSem = CreateSemaphore(NULL, 1, 1, NULL);
	//Create the timer semaphore
	g_hTimerSem = CreateSemaphore(NULL, 1, 1, NULL);
	
	// Display the dialog box
	return DialogBox(g_hInst, "frmMain", NULL, DialogFunc);
}

// Our function to handle most of the events
BOOL CALLBACK DialogFunc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message) {
	case WM_INITDIALOG:
		// Set the icon and store the window handle
		g_hwnd = hDlg;
		SendMessage(hDlg, WM_SETICON, FALSE, (LPARAM)hIconSmall); 
		break;

	case WM_TIMER:
#ifdef ADIOS_USE_GC
		if(wParam == ADIOS_GC_TIMER) // Garbage collection
			OnGarbageCollection();
#endif /* ADIOS_USE_GC */
		if(wParam == ADIOS_TIMERS)
			FireTimers();

		break;

	case WM_CLOSE:
		// Exit the application
		// I had problems before I added this kernel shutdown code
		if (g_KernelStarted == TRUE) OnFrmMain_StartKernel();
		EndDialog(hDlg, 0);
		PostQuitMessage(0);
		return 1;

	case WM_COMMAND:
		switch(LOWORD(wParam)) {
		case IDC_CMDSEM:
			// If the semaphore window isn't open, open it
			if(g_SemWindowOpen == FALSE) DialogBox(g_hInst, "FRMSEM", NULL, SemDialogFunc);
			return 1;

		case IDC_CMDSTART:
			// Start/stop the kernel and sort the buttons out
			OnFrmMain_StartKernel();
			return 1;

		case IDC_CMDPAUSE:
			// Toggle the pause flag and button
			OnFrmMain_PauseOutput();
			return 1;

		case IDC_CMDKILL:
			// Kill a thread
			OnFrmMain_KillThread();
			return 1;

		case IDC_CMDPAUSET:
			// Pause a thread
			OnFrmMain_PauseThread();
			return 1;

		case IDC_CMDRESET:
			// Reset a thread
			OnFrmMain_ResetThread();
			return 1;

		case IDC_LSTTHREADS:
			// All the list box action
			switch (HIWORD(wParam)) {
			case LBN_DBLCLK:
				// Pause a thread when it is double clicked
				OnFrmMain_PauseThread();
				break;

			case LBN_SELCHANGE:
				// Update the buttons when the selection is changed
				OnFrmMain_SelChange();
				break;
			}
			return 1;

		case IDC_CMDCLEAR:
			// Wipe the text from the window
			SetDlgItemText(hDlg, IDC_TXTOUTPUT, "");
			return 1;
		}
		break;
	}
	return 0;
}

BOOL CALLBACK SemDialogFunc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message) {
	case WM_INITDIALOG:
		// Set the icon and store the window handle
		g_hwndSem = hDlg;
		g_SemWindowOpen = TRUE; // Let the rest of the app know this window is open
		OnFrmSem_WindowInit();
		break;

	case WM_COMMAND:
		switch(LOWORD(wParam)) {
		case IDCANCEL:
			// Close the window
			g_SemWindowOpen = FALSE; // Tell every one we're now closed
			EndDialog(hDlg, 0);
			return 1;

		case IDC_CMDWAIT:
			// Call the WaitSem() function to decrement a semaphore
			OnFrmSem_Wait();
			break;

		case IDC_CMDRELEASE:
			// Call the ReleaseSem() function to increment a semaphore
			OnFrmSem_Release();
			break;

		case IDC_CMDREFRESH:
			// Refresh the semaphore list
			OnFrmSem_WindowInit();
			break;

		case IDC_LSTSEM:
			// All the list box action
			switch (HIWORD(wParam)) {
			case LBN_DBLCLK:
				// refresh the list
				OnFrmSem_Release();
				break;
			}
		}
	}
	return 0;
}

//------ Window Event Functions ------//

#ifdef ADIOS_USE_GC
// Garbage Collection
void OnGarbageCollection(void)
{
	// NOTE: This is a very slow way to do this!
	int n, m, i, count;
	char buf[1024];
	DWORD Status;

	// Scan through each thread
	for(n = 0; n < ADIOS_THREADS_MAX; n++){
		// Is there a thread here?
		if(ThreadList[n].handle != 0){
			// Get its current status
			GetExitCodeThread(ThreadList[n].handle, &Status);
			if (Status != STILL_ACTIVE){
				// The thread is no longer active so close its handle
				CloseHandle(ThreadList[n].handle);
				
				// Find out how many items there are in the list box
				count = SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETCOUNT, 0, 0);
				// Loop through each item to find and remove the thread text
				for(m = 0; m < count; m++){
					// Get the text of the current item
					SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETTEXT, m, (LPARAM) (LPCTSTR) buf);
					i = atoi(buf); // Turnit into an integer
					if((HANDLE)i == ThreadList[n].handle){
						// If the handles match, delete the string from the list box
						SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_DELETESTRING, m, 0);

						// Now clear up our thread table
						g_Threads--; // Decrement the thread counter
						// Now copy the last thread launched's data over the top of the killed thread's
						ThreadList[n].handle  = ThreadList[g_Threads].handle;
						ThreadList[n].Running = ThreadList[g_Threads].Running;
						ThreadList[n].lpFunc  = ThreadList[g_Threads].lpFunc;
						ThreadList[n].param   = ThreadList[g_Threads].param;

						// Mark the last thread as truely dead
						ThreadList[g_Threads].handle  = 0;
						ThreadList[g_Threads].Running = FALSE;
					}
				}
			}
		}
	}
}
#endif /* ADIOS_USE_GC */

// Kill the selected thread
void OnFrmMain_KillThread(void)
{
	int i;
	char buf[1024];

	// Lets get the list index of the selected item
	i = SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETCURSEL, 0, 0);
	if(i != -1) { // Make sure an item was selected
		// Get the text of the item
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETTEXT, i, (LPARAM) (LPCTSTR) buf);
		// Delete the item from the list
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_DELETESTRING, i, 0);
		i = atoi(buf);

		// Kill the thread
		KillThread((unsigned int)i);
	}
}

// Pause the output to the screen
void OnFrmMain_PauseOutput(void)
{
	// Has the output been paused yet?
	if (g_PauseOutput == FALSE){
		// Pause the output (This free's up a lot of CPU time!)
		g_PauseOutput = TRUE;
		SetDlgItemText(g_hwnd, IDC_CMDPAUSE, "Start Output");
	} else {
		// Unpause the output
		g_PauseOutput = FALSE;
		SetDlgItemText(g_hwnd, IDC_CMDPAUSE, "Stop Output");
	}
}

// Suspend or resume a thread
void OnFrmMain_PauseThread(void)
{
	int i, n;
	char buf[1024];

	// Get the index of the selected thread from the list box
	i = SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETCURSEL, 0, 0);
	if(i != -1) { // Make sure there is an item selected
		// Get the text of the item for the handle
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETTEXT, i, (LPARAM) (LPCTSTR) buf);
		// Delete the item from the list box (because we'll be changing the text)
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_DELETESTRING, i, 0);
		i = atoi(buf); // Turn the text from the list box into a usable form

		n = GetThreadIndex((HANDLE)i);

		// Time to toggle the thread running state
		if(ThreadList[n].Running == TRUE){
			// The thread was running, so we must stop it
			SuspendThread(ThreadList[n].handle);
			ThreadList[n].Running = FALSE; // Let the system know the thread has stopped
			SetDlgItemText(g_hwnd, IDC_CMDPAUSET, "Unpause"); // Change the button text
			sprintf(buf, "%d (Paused)", i); // Reform the list text
		} else {
			// The thread is currently suspended, so we must restart it
			ResumeThread(ThreadList[n].handle);
			ThreadList[n].Running = TRUE; // Let the system know it's running again
			SetDlgItemText(g_hwnd, IDC_CMDPAUSET, "Pause"); // Change the button text
			sprintf(buf, "%d", i); // Reform the list text
		}
		// Add the modified string back to the list (I'm glad it sorts automatically!)
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_ADDSTRING, 0, (LPARAM)buf);
	}
}

// Relaunch the selected thread
// This works by killing it, then starting it off again
void OnFrmMain_ResetThread(void)
{
	// Oooh, lots of nast bits!
	int i, n;
	char buf[1024];
	void * (*lpFunc)(__int32);
	__int32 param;

	// Lets get the list index of the selected thread
	i = SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETCURSEL, 0, 0);
	if(i != -1) { // Make sure an item was selected
		// Get the text for the thread handle
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETTEXT, i, (LPARAM) (LPCTSTR) buf);
		// Remove the list item
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_DELETESTRING, i, 0);
		i = atoi(buf);

		// We need to store entry function and the parameter for the thread
		n = GetThreadIndex((HANDLE)i);
		lpFunc = ThreadList[n].lpFunc;
		param  = ThreadList[n].param;

		// Time to kill off the thread
		KillThread((unsigned int)ThreadList[n].handle);

		// Now to restart the thread
		StartThread(lpFunc, param);
	}
}

// Update the pause thread button
void OnFrmMain_SelChange(void)
{
	int i;
	char buf[1024];

	// Get the current list box index
	i = SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETCURSEL, 0, 0);
	// Get the text for the item
	SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_GETTEXT, i, (LPARAM) (LPCTSTR) buf);
	// Turn it into an integer
	i = atoi(buf); 

	// Set the pause thread button to either Pause or Unpause
	if(ThreadList[GetThreadIndex((HANDLE)i)].Running == TRUE){
		SetDlgItemText(g_hwnd, IDC_CMDPAUSET, "Pause");
	} else {
		SetDlgItemText(g_hwnd, IDC_CMDPAUSET, "Unpause");
	}
}

// Start/Stop the kernel
void OnFrmMain_StartKernel(void)
{
	// Has the kernel been started yet?
	if (g_KernelStarted == FALSE){
		// Start the kernel
		g_KernelStarted = TRUE;
		StartKernel();
		SetDlgItemText(g_hwnd, IDC_CMDSTART, "Stop Kernel");
	} else {
		// Stop the kernel
		g_KernelStarted = FALSE;
		ExitKernel();
		SetDlgItemText(g_hwnd, IDC_CMDSTART, "Start Kernel");
	}
}

// Release a semaphore
void OnFrmSem_Release(void)
{
	int i;
	char buf[1024];

	// Lets get the list index of the selected item
	i = SendDlgItemMessage(g_hwndSem, IDC_LSTSEM, LB_GETCURSEL, 0, 0);
	if(i != -1) { // Make sure an item was selected

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -