📄 kernel.c
字号:
// 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 + -