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

📄 kernelmultitasker.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 5 页
字号:
	// If it's the kernel, we're finished	kernelPanic(tmpMsg);      else	{	  kernelError(kernel_error, tmpMsg);	  if (kernelGraphicsAreEnabled())	    kernelErrorDialog("Application Exception", tmpMsg);	}      // If the process was in kernel code, and we are not processing an      // interrupt, take ownership of the process' stack memory and do a      // stack trace      if (!kernelProcessingInterrupt &&	  (deadProcess->taskStateSegment.EIP >= KERNEL_VIRTUAL_ADDRESS))	{	  kernelMemoryChangeOwner(deadProcess->processId,				  exceptionProc->processId, 1,				  deadProcess->userStack, &stackMemory);	  // If possible, we will do a stack memory dump to disk.  Don't try	  // this if we were servicing an interrupt when we faulted	  if (stackMemory)	    {	      kernelStackTrace((stackMemory +				((void *) deadProcess->taskStateSegment.ESP -				 deadProcess->userStack)),			       (stackMemory + deadProcess->userStackSize -				sizeof(void *)));	      // Release the stack memory	      kernelMemoryRelease(stackMemory);	    }	}      // The scheduler may now dismantle the process      deadProcess->state = proc_finished;      kernelProcessingInterrupt = 0;      // Make sure that when we return, we return to the scheduler      exceptionProc->taskStateSegment.oldTSS = schedulerProc->tssSelector;      // Mark the process as finished and yield the timeslice back to the      // scheduler.  The scheduler will take care of dismantling the process      exceptionProc->state = proc_sleeping;      kernelMultitaskerYield();    }}void kernelMultitaskerDumpProcessList(void){  // This routine is used to dump an internal listing of the current  // process to the output.  kernelTextOutputStream *currentOutput = NULL;  kernelProcess *tmpProcess = NULL;  char buffer[1024];  int count;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return;  // Get the current output stream  currentOutput = kernelTextGetCurrentOutput();  if (numQueued > 0)    {      kernelTextStreamPrintLine(currentOutput, "Process list:");      for (count = 0; count < numQueued; count ++)	{	  tmpProcess = processQueue[count];	  	  sprintf(buffer, "\"%s\"  PID=%d UID=%d priority=%d "		  "priv=%d parent=%d\n        %d%% CPU State=",		  (char *) tmpProcess->processName,		  tmpProcess->processId, tmpProcess->userId,		  tmpProcess->priority, tmpProcess->privilege,		  tmpProcess->parentProcessId, tmpProcess->cpuPercent);	  // Get the state	  switch(tmpProcess->state)	    {	    case proc_running:	      strcat(buffer, "running");	      break;	    case proc_ready:	      strcat(buffer, "ready");	      break;	    case proc_waiting:	      strcat(buffer, "waiting");	      break;	    case proc_sleeping:	      strcat(buffer, "sleeping");	      break;	    case proc_stopped:	      strcat(buffer, "stopped");	      break;	    case proc_finished:	      strcat(buffer, "finished");	      break;	    case proc_zombie:	      strcat(buffer, "zombie");	      break;	    default:	      strcat(buffer, "unknown");	      break;	    }	  kernelTextStreamPrintLine(currentOutput, buffer);	}    }  else    // This doesn't seem at all likely.    kernelTextStreamPrintLine(currentOutput, "No processes remaining");  kernelTextStreamNewline(currentOutput);  return;}int kernelMultitaskerCreateProcess(const char *name, int privilege,				   processImage *execImage){  // This function is called to set up an (initially) single-threaded  // process in the multitasker.  This is the routine used by external  // sources -- the loader for example -- to define new processes.  This   // new process thread we're creating will have its state set to "stopped"   // after this call.  The caller should use the   // kernelMultitaskerChangeThreadState routine to start the new thread.    // This function returns the processId of the new process on success,   // negative otherwise.  int status = 0;  int processId = 0;  kernelProcess *newProcess = NULL;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);  // Make sure the parameters are valid  if ((name == NULL) || (execImage == NULL))    return (status = ERR_NULLPARAMETER);  // Make sure that an unprivileged process is not trying to create a  // privileged one  if ((kernelCurrentProcess->privilege == PRIVILEGE_USER) &&      (privilege == PRIVILEGE_SUPERVISOR))    {      kernelError(kernel_error, "An unprivileged process cannot create a "		  "privileged process");      return (status == ERR_PERMISSION);    }  // Create the new process  processId = createNewProcess(name, PRIORITY_DEFAULT, privilege, execImage,			       1); // create page directory  // Get the pointer to the new process from its process Id  newProcess = getProcessById(processId);  if (newProcess == NULL)    // We couldn't get access to the new process    return (status = ERR_NOCREATE);  // Create the process' environment  status =    kernelEnvironmentCreate(newProcess->processId, (variableList *)			    &(newProcess->environment), (variableList *)			    &(kernelCurrentProcess->environment));  if (status < 0)    // Couldn't create an environment structure for this process    return (status);  // Don't assign input or output streams to this process.  There are  // multiple possibilities here, and the caller will have to either block  // (which takes care of such things) or sort it out for themselves.  // Return whatever was returned by the previous call  return (processId);}int kernelMultitaskerSpawn(void *startAddress, const char *name, int argc,			   void *argv[]){  // This function is used to spawn a new thread from the current  // process.  The function needs to be told the starting address of  // the code to execute, and an optional argument to pass to the   // spawned function.  It returns the new process Id on success,  // negative otherwise.  int status = 0;  int processId = 0;  kernelProcess *newProcess = NULL;  processImage execImage;  int count;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);  // The start address CAN be NULL, if it is the zero offset in a  // process' private address space.  // Make sure the pointer to the name is not NULL  if (name == NULL)    // We cannot continue here    return (status = ERR_NULLPARAMETER);  // If the number of arguments is not zero, make sure the arguments  // pointer is not NULL  if (argc && !argv)    return (status = ERR_NULLPARAMETER);  // Make sure the current process isn't NULL  if (kernelCurrentProcess == NULL)    return (status = ERR_NOSUCHPROCESS);  kernelMemClear(&execImage, sizeof(processImage));  execImage.virtualAddress = startAddress;  execImage.entryPoint = startAddress;  execImage.code = NULL;  execImage.codeSize = 0;  execImage.data = NULL;  execImage.dataSize = 0;  execImage.imageSize = 0;  // Set up arguments  execImage.argc = (argc + 1);  execImage.argv[0] = (char *) name;  for (count = 0; count < argc; count ++)    execImage.argv[count + 1] = argv[count];  // OK, now we should create the new process  processId = createNewProcess(name, kernelCurrentProcess->priority,			       kernelCurrentProcess->privilege,			       &execImage, 0);  if (processId < 0)    return (status = processId);    // Get the pointer to the new process from its process Id  newProcess = getProcessById(processId);  // Make sure it's valid  if (newProcess == NULL)    // We couldn't get access to the new process    return (status = ERR_NOCREATE);  // Change the type to thread  newProcess->type = proc_thread;    // Increment the descendent counts   incrementDescendents(newProcess);  // Since we assume that the thread is invoked as a function call,   // subtract 4 additional bytes from the stack pointer to account for  // the space where the return address would normally go.  newProcess->taskStateSegment.ESP -= 4;  // Copy the environment  newProcess->environment = kernelCurrentProcess->environment;  // The new process should share (but not own) the same text streams as the  // parent  newProcess->textInputStream = kernelCurrentProcess->textInputStream;  newProcess->textOutputStream = kernelCurrentProcess->textOutputStream;  // Make the new thread runnable  newProcess->state = proc_ready;  // Return the new process' Id.  return (newProcess->processId);}int kernelMultitaskerSpawnKernelThread(void *startAddress, const char *name, 				       int argc, void *argv[]){  // This function is a wrapper around the regular spawn() call, which  // causes threads to be spawned as children of the kernel, instead of  // children of the calling process.  This is important for threads that  // are spawned from code which belongs to the kernel.  int status = 0;  int interrupts = 0;  kernelProcess *myProcess;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);  // What is the current process?  myProcess = kernelCurrentProcess;  // Disable interrupts while we're monkeying  kernelProcessorSuspendInts(interrupts);  // Change the current process to the kernel process  kernelCurrentProcess = kernelProc;  // Spawn  status = kernelMultitaskerSpawn(startAddress, name, argc, argv);  // Reset the current process  kernelCurrentProcess = myProcess;  // Reenable interrupts  kernelProcessorRestoreInts(interrupts);  // Done  return (status);}int kernelMultitaskerGetProcess(int processId, process *userProcess){  // Return the requested process.  int status = 0;  kernelProcess *kernProcess = NULL;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);    // Check params  if (userProcess == NULL)    return (status = ERR_NULLPARAMETER);  // Try to match the requested process Id number with a real  // live process structure  kernProcess = getProcessById(processId);  if (kernProcess == NULL)    // That means there's no such process    return (status = ERR_NOSUCHENTRY);  // Make it into a user space process  kernelProcess2Process(kernProcess, userProcess);  return (status = 0);}int kernelMultitaskerGetProcessByName(const char *processName,				      process *userProcess){  // Return the requested process.  int status = 0;  kernelProcess *kernProcess = NULL;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);    // Check params  if ((processName == NULL) || (userProcess == NULL))    return (status = ERR_NULLPARAMETER);  // Try to match the requested process Id number with a real  // live process structure  kernProcess = getProcessByName(processName);  if (kernProcess == NULL)    // That means there's no such process    return (status = ERR_NOSUCHENTRY);  // Make it into a user space process  kernelProcess2Process(kernProcess, userProcess);  return (status = 0);}int kernelMultitaskerGetProcesses(void *buffer, unsigned buffSize){  // Return user-space process structures into the supplied buffer  int status = 0;  kernelProcess *kernProcess = NULL;  process *userProcess = NULL;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);    // Check params  if (buffer == NULL)    return (status = ERR_NULLPARAMETER);  for (status = 0; status < numQueued; status ++)    {      kernProcess = processQueue[status];      userProcess = (buffer + (status * sizeof(process)));      if ((void *) userProcess >= (buffer + buffSize))	break;      kernelProcess2Process(kernProcess, userProcess);    }  return (status);}int kernelMultitaskerGetCurrentProcessId(void){  // This is a very simple routine that can be called by external   // programs to get the PID of the current running process.  Of course,  // internal functions can perform this action very easily themselves.  int status = 0;  // Make sure multitasking has been enabl

⌨️ 快捷键说明

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