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

📄 kernel.c

📁 adios在windows的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		// Get the text of the item
		SendDlgItemMessage(g_hwndSem, IDC_LSTSEM, LB_GETTEXT, i, (LPARAM) (LPCTSTR) buf);
		i = atoi(buf);

		// Release the semaphore
		ReleaseSem((unsigned int)i);
	}
}

// Tell a semaphore to wait
void OnFrmSem_Wait(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
		// Get the text of the item
		SendDlgItemMessage(g_hwndSem, IDC_LSTSEM, LB_GETTEXT, i, (LPARAM) (LPCTSTR) buf);
		i = atoi(buf);

		// tell the semaphore to wait
		WaitSem((unsigned int)i);
	}
}

// Set up the semaphore window (load the list basically)
void OnFrmSem_WindowInit(void)
{
	char buf[1024];
	int n;
	
	// Clear the list box
	SendDlgItemMessage(g_hwndSem, IDC_LSTSEM, LB_RESETCONTENT, 0, 0);
	
	// Load the semaphores into the list
	for(n = 0; n < ADIOS_SEMAPHORES_MAX; n++){
		if(SemaphoreList[n].handle != (HANDLE)0){
			sprintf(buf, "%d (%d/%d)", (int)SemaphoreList[n].handle, SemaphoreList[n].Value, SemaphoreList[n].MaxValue);
			SendDlgItemMessage(g_hwndSem, IDC_LSTSEM, LB_ADDSTRING, 0, (LPARAM)buf);
		}
	}
}


//------ Kernel Helper Functions ------//

// Return the index for a thread based on it's handle
int GetThreadIndex(HANDLE hand)
{
	int n;
	// Simple loop through all threads because the list isn't sorted
	for(n = 0; n < ADIOS_THREADS_MAX; n++){
		if(ThreadList[n].handle == hand) return n;
	}
	return -1;
}

int GetSemaphoreIndex(HANDLE hand)
{
	int n;
	// Simple loop through all semaphores because the list isn't sorted
	for(n = 0; n < ADIOS_SEMAPHORES_MAX; n++){
		if(SemaphoreList[n].handle == hand) return n;
	}
	return -1;
}

int GetTimerIndex(unsigned int ID)
{
	int n;
	// Simple loop through all timers because the list isn't sorted
	for(n = 0; n < ADIOS_TIMERS_MAX; n++){
		if(TimerList[n].ID == ID) return n;
	}
	return -1;
}

// Init the kernel
void StartKernel(void)
{
	int n;

	// There are no threads or semaphores yet
	g_Threads = 0;
	g_Semaphores = 0;

	// Set all thread handles to 0
	for(n = 0; n < ADIOS_THREADS_MAX; n++){
		ThreadList[n].handle = (HANDLE)0;
		ThreadList[n].Running = FALSE;
	}

	// Set all the semaphore handles to 0
	for(n = 0; n < ADIOS_SEMAPHORES_MAX; n++){
		SemaphoreList[n].handle = (HANDLE)0;
	}

	// Set all the timer IDs to 0
	for(n = 0; n < ADIOS_TIMERS_MAX; n++){
		TimerList[n].ID = 0;
		TimerList[n].lpFunc = 0;
	}


	// Welcome to our kernel evironment!
	PrintCR("AdiOS");
	PrintCR("Simulated Kernel Environment");
	PrintCR(ADIOS_VERSION_TEXT);
	PrintCR("");

#ifdef ADIOS_USE_GC
	// Start garbage collection
	SetTimer(g_hwnd, ADIOS_GC_TIMER, ADIOS_GC_FREQ, NULL);
#endif /* ADIOS_USE_GC */
	// Start the timer, timer so that it fires every 10th of a second
	SetTimer(g_hwnd, ADIOS_TIMERS, ADIOS_TIMERS_FREQ, NULL);

#ifdef ADIOS_USE_COM
	Print("Init COM...");
	if(InitComPort() == ADIOS_COM_PORT_OPENED){
		PrintCR("OK");
	} else {
		PrintCR("FAILED");
	}
#endif /* ADIOS_USE_COM */

// Don't bother setting up any threads if there is no application
#ifndef ADIOS_NO_APP
	// Launch the application
	StartThread(&appmain, 0);

#else  /* ADIOS_NO_APP */
	PrintCR("There was no application. Exiting.");
#endif /* ADIOS_NO_APP */
}

#ifdef ADIOS_USE_COM
// Configure and open the com port
long InitComPort(void)
{
	COMMTIMEOUTS ct;			// Structure to hold time outs
	DCB commstate;				// Structure to hold port settings

	// Open the com port
	g_com = CreateFile(ADIOS_COM, GENERIC_READ + GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

	if (g_com != INVALID_HANDLE_VALUE)	// Check the port was opened ok
	{
		// Set up com port time outs
		ct.ReadIntervalTimeout         = 0;
		ct.ReadTotalTimeoutConstant    = ADIOS_COM_TIMEOUT_READ;
		ct.ReadTotalTimeoutMultiplier  = 0;
		ct.WriteTotalTimeoutConstant   = ADIOS_COM_TIMEOUT_WRITE;
		ct.WriteTotalTimeoutMultiplier = 0;
		SetCommTimeouts(g_com, &ct);

		// Set up com port speeds
		GetCommState(g_com, &commstate);
		commstate.BaudRate = ADIOS_COM_BAUDRATE;
		commstate.ByteSize = ADIOS_COM_BITESIZE;
		commstate.Parity   = ADIOS_COM_PARITY;
		commstate.StopBits = ADIOS_COM_STOPBITS;
		SetCommState(g_com, &commstate);

		return ADIOS_COM_PORT_OPENED;
	} else {
		return ADIOS_COM_PORT_FAILED;
	}
}
#endif /* ADIOS_USE_COM */

void FireTimers(void)
{
	int n;
	for (n = 0; n < g_Timers; n++){
		if(TimerList[n].ID != 0){
			TimerList[n].CurrentTime--;
			if(TimerList[n].CurrentTime == 0){
				TimerList[n].CurrentTime = TimerList[n].Interval;
				TimerList[n].lpFunc();
			}
		}
	}
}

//------ Kernel API Starts Here ------//

// Kernel control functions
// Kill all threads, thus exiting/resetting kernel
void ExitKernel(void)
{
	// Move the cursor down a couple of lines to neaten things up
	int n;
	PrintCR("");
	PrintCR("");

#ifdef ADIOS_USE_GC
	// Stop garbage collection
	KillTimer(g_hwnd, ADIOS_GC_TIMER);
#endif /* ADIOS_USE_GC */
	// Stop the timer timer
	KillTimer(g_hwnd, ADIOS_TIMERS);

#ifdef ADIOS_USE_COM
	// Close the com port
	CloseHandle(g_com);
#endif /* ADIOS_USE_COM */

	// Cycle through killing all threads
	for(n = ADIOS_THREADS_MAX - 1; n >= 0; n--){
		if(ThreadList[n].handle != (HANDLE)0){
			KillThread((unsigned int)ThreadList[n].handle);
		}
	}
	
	// Cycle through closing semaphores
	for(n = ADIOS_SEMAPHORES_MAX -1; n >= 0; n--){
		if(SemaphoreList[n].handle != (HANDLE)0){
			CloseHandle(SemaphoreList[n].handle);
			SemaphoreList[n].handle = 0;
		}
	}

	// Clear the list box
	SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_RESETCONTENT, 0, 0);
}

// Display output on the screen. No real text formatting takes place
// Print string with a CR
// Just calls Print() twice, once with the string and once with a CR
void PrintCR(char * Text)
{
	char szCR[] = {13, 10, 0};
	Print(Text);
	Print(szCR);
}

// Print the string without a CR
void Print(char * Text)
{
	// Get the handle for the exit box
	HWND hwnd = GetDlgItem(g_hwnd, IDC_TXTOUTPUT);
	int i = 0;

	if(g_PauseOutput) return; // Leave the function if we're not displaying output

	// Find out how much text there is
	i = GetWindowTextLength(hwnd);
	SetFocus(hwnd);

	// Just so we don't overflow, stop output at 64000 bytes
	if (i > 64000) return;

	// Move the selection to the end
	SendMessage(hwnd, EM_SETSEL, (WPARAM)i, (LPARAM)i);
	// Replace the selection with the Text
	SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM) ((LPSTR) Text)); 
}

// Thread launching function
unsigned int StartThread(void * (*lpFunc)(__int32), __int32 iParam)
{
	unsigned int RetVal;
	char buf[1024];
	DWORD Tid; // We need to store this to launch the thread, but we don't need to keep it

	// We can only allow one thread to edit the thread list at a time
	WaitForSingleObject(g_hThreadSem, INFINITE);

	if(g_Threads != ADIOS_THREADS_MAX){
		// Store all the details in our thread list
		RetVal = (unsigned int)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lpFunc, (LPVOID)iParam, 0, &Tid);
		ThreadList[g_Threads].handle  = (HANDLE)RetVal;
		ThreadList[g_Threads].Running = TRUE;
		ThreadList[g_Threads].lpFunc  = lpFunc;
		ThreadList[g_Threads].param   = iParam;

		// Now to add it to the thread list box
		sprintf(buf, "%d", (int)ThreadList[g_Threads].handle);
		SendDlgItemMessage(g_hwnd, IDC_LSTTHREADS, LB_ADDSTRING, 0, (LPARAM)buf);
		g_Threads++; // Increment the thread counter
	}

	// Now we can release the thread list
	ReleaseSemaphore(g_hThreadSem, 1, NULL);

	return RetVal; // Return the ID of the newly launched thread
}

// Kill off a thread
void KillThread(unsigned int Thread)
{
	int n = GetThreadIndex((HANDLE)Thread);

	// We can only have one thread chaning the thread list at a time
	WaitForSingleObject(g_hThreadSem, INFINITE);

	if(n != -1){
		// First kill the thread
		TerminateThread(ThreadList[n].handle, 0);
		CloseHandle(ThreadList[n].handle);
		
		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;
	}

	// Now we can release the thread list
	ReleaseSemaphore(g_hThreadSem, 1, NULL);
}

// Create a semaphore
unsigned int CreateSem(int Count)
{
	// Set up all the initial values
	SemaphoreList[g_Semaphores].handle = CreateSemaphore(NULL, Count, Count, NULL);
	SemaphoreList[g_Semaphores].Value = Count;
	SemaphoreList[g_Semaphores].MaxValue = Count;
	
	g_Semaphores++; // Increment the semephore counter
	return (unsigned int)SemaphoreList[g_Semaphores - 1].handle;
}

// Kill off a semaphore
void KillSem(unsigned int Sem)
{
	// Find the semaphore index
	int n = GetSemaphoreIndex((HANDLE)Sem);

	if(n != -1){
		// Release the semaphore object from the system
		CloseHandle((HANDLE)SemaphoreList[n].handle);
		
		// Remove the semaphore from the list
		g_Semaphores--;
		SemaphoreList[n].handle = SemaphoreList[g_Semaphores].handle;
		SemaphoreList[n].Value = SemaphoreList[g_Semaphores].Value;
		SemaphoreList[n].MaxValue = SemaphoreList[g_Semaphores].MaxValue;
		SemaphoreList[g_Semaphores].handle = (HANDLE)0;
	}
}

// Decrement semaphore
void WaitSem(unsigned int Sem)
{
	int n = GetSemaphoreIndex((HANDLE)Sem);
	WaitForSingleObject((HANDLE)Sem, INFINITE);

	// Update the value of the semaphore for our list
	if(SemaphoreList[n].Value > 0)
		SemaphoreList[n].Value--;
}

// Release semaphore
void ReleaseSem(unsigned int Sem)
{
	int n = GetSemaphoreIndex((HANDLE)Sem);
	ReleaseSemaphore((HANDLE)Sem, 1, NULL);

	// Update the value of the semaphore for our list
	if(SemaphoreList[n].Value < SemaphoreList[n].MaxValue)
		SemaphoreList[n].Value++;
}

#ifdef ADIOS_USE_COM
// Write to the com port
long WriteCom(char * Data, long len)
{
	unsigned long z = 0;

	// Attempt to write
	WriteFile(g_com, (LPCVOID)Data, (unsigned long)len, &z, NULL);
	if(z != 0){
		// There was some data written
		return (long)z;
	} else {
		// Oh dear, a problem, nothing was written
		return ADIOS_FAIL;
	}
}

long ReadCom(char * Data, long len)
{
	unsigned long z = 0;

	// Attempt to read
	ReadFile(g_com, (LPVOID)Data, (unsigned long)len, &z, NULL);
	if(z != 0){
		// Return how much was written
		return (long)z;
	} else {
		// No data written, return an error
		return ADIOS_FAIL;
	}
}
#endif /* ADIOS_USE_COM */

// Timer functions
unsigned int StartTimer(void (*lpFunc)(void), int Interval)
{
	// Lock out the timers table
	WaitForSingleObject(g_hTimerSem, INFINITE);

	// Set up all the initial values
	TimerList[g_Timers].ID = g_NextTimer++;
	TimerList[g_Timers].Interval = Interval;
	TimerList[g_Timers].CurrentTime = Interval;
	TimerList[g_Timers].lpFunc = lpFunc;
	
//	PrintCR("Timer Started");
	g_Timers++; // Increment the timer counter
	
	// Now we can release the thread list
	ReleaseSemaphore(g_hTimerSem, 1, NULL);
	
	return TimerList[g_Timers - 1].ID;
}

void StopTimer(unsigned int ID)
{
	// Find the semaphore index
	int n;
	
	// Lock out the timers table
	WaitForSingleObject(g_hTimerSem, INFINITE);

	n = GetTimerIndex(ID);
	
	if(n != -1){
		// Remove the timer from the list
		g_Timers--;
		TimerList[n].ID = TimerList[g_Timers].ID;
		TimerList[n].CurrentTime = TimerList[g_Timers].CurrentTime;
		TimerList[n].Interval = TimerList[g_Timers].Interval;
		TimerList[n].lpFunc = TimerList[g_Timers].lpFunc;

//		PrintCR("Timer Stopped");
		TimerList[g_Timers].ID = 0;
	}

	// Now we can release the timer list
	ReleaseSemaphore(g_hTimerSem, 1, NULL);
}

⌨️ 快捷键说明

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