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

📄 main.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This file contains the main program of the process manager and some related * procedures.  When MINIX starts up, the kernel runs for a little while, * initializing itself and its tasks, and then it runs PM and FS.  Both PM * and FS initialize themselves as far as they can. PM asks the kernel for * all free memory and starts serving requests. * * The entry points into this file are: *   main:	starts PM running *   setreply:	set the reply to be sent to process making an PM system call */#include "pm.h"#include <minix/keymap.h>#include <minix/callnr.h>#include <minix/com.h>#include <signal.h>#include <stdlib.h>#include <fcntl.h>#include <sys/resource.h>#include <string.h>#include "mproc.h"#include "param.h"#include "../../kernel/const.h"#include "../../kernel/config.h"#include "../../kernel/type.h"#include "../../kernel/proc.h"FORWARD _PROTOTYPE( void get_work, (void)				);FORWARD _PROTOTYPE( void pm_init, (void)				);FORWARD _PROTOTYPE( int get_nice_value, (int queue)			);FORWARD _PROTOTYPE( void get_mem_chunks, (struct memory *mem_chunks) 	);FORWARD _PROTOTYPE( void patch_mem_chunks, (struct memory *mem_chunks, 	struct mem_map *map_ptr) 	);#define click_to_round_k(n) \	((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))/*===========================================================================* *				main					     * *===========================================================================*/PUBLIC int main(){/* Main routine of the process manager. */  int result, s, proc_nr;  struct mproc *rmp;  sigset_t sigset;  pm_init();			/* initialize process manager tables */  /* This is PM's main loop-  get work and do it, forever and forever. */  while (TRUE) {	get_work();		/* wait for an PM system call */	/* Check for system notifications first. Special cases. */	if (call_nr == SYN_ALARM) {		pm_expire_timers(m_in.NOTIFY_TIMESTAMP);		result = SUSPEND;		/* don't reply */	} else if (call_nr == SYS_SIG) {	/* signals pending */		sigset = m_in.NOTIFY_ARG;		if (sigismember(&sigset, SIGKSIG))  (void) ksig_pending();		result = SUSPEND;		/* don't reply */	}	/* Else, if the system call number is valid, perform the call. */	else if ((unsigned) call_nr >= NCALLS) {		result = ENOSYS;	} else {		result = (*call_vec[call_nr])();	}	/* Send the results back to the user to indicate completion. */	if (result != SUSPEND) setreply(who, result);	swap_in();		/* maybe a process can be swapped in? */	/* Send out all pending reply messages, including the answer to	 * the call just made above.  The processes must not be swapped out.	 */	for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {		/* In the meantime, the process may have been killed by a		 * signal (e.g. if a lethal pending signal was unblocked)		 * without the PM realizing it. If the slot is no longer in		 * use or just a zombie, don't try to reply.		 */		if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) ==		   (REPLY | IN_USE)) {			if ((s=send(proc_nr, &rmp->mp_reply)) != OK) {				panic(__FILE__,"PM can't reply to", proc_nr);			}			rmp->mp_flags &= ~REPLY;		}	}  }  return(OK);}/*===========================================================================* *				get_work				     * *===========================================================================*/PRIVATE void get_work(){/* Wait for the next message and extract useful information from it. */  if (receive(ANY, &m_in) != OK) panic(__FILE__,"PM receive error", NO_NUM);  who = m_in.m_source;		/* who sent the message */  call_nr = m_in.m_type;	/* system call number */  /* Process slot of caller. Misuse PM's own process slot if the kernel is   * calling. This can happen in case of synchronous alarms (CLOCK) or or    * event like pending kernel signals (SYSTEM).   */  mp = &mproc[who < 0 ? PM_PROC_NR : who];}/*===========================================================================* *				setreply				     * *===========================================================================*/PUBLIC void setreply(proc_nr, result)int proc_nr;			/* process to reply to */int result;			/* result of call (usually OK or error #) */{/* Fill in a reply message to be sent later to a user process.  System calls * may occasionally fill in other fields, this is only for the main return * value, and for setting the "must send reply" flag. */  register struct mproc *rmp = &mproc[proc_nr];  rmp->mp_reply.reply_res = result;  rmp->mp_flags |= REPLY;	/* reply pending */  if (rmp->mp_flags & ONSWAP)	swap_inqueue(rmp);	/* must swap this process back in */}/*===========================================================================* *				pm_init					     * *===========================================================================*/PRIVATE void pm_init(){/* Initialize the process manager.  * Memory use info is collected from the boot monitor, the kernel, and * all processes compiled into the system image. Initially this information * is put into an array mem_chunks. Elements of mem_chunks are struct memory, * and hold base, size pairs in units of clicks. This array is small, there * should be no more than 8 chunks. After the array of chunks has been built * the contents are used to initialize the hole list. Space for the hole list * is reserved as an array with twice as many elements as the maximum number * of processes allowed. It is managed as a linked list, and elements of the * array are struct hole, which, in addition to storage for a base and size in  * click units also contain space for a link, a pointer to another element.*/  int s;  static struct boot_image image[NR_BOOT_PROCS];  register struct boot_image *ip;  static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,			SIGEMT, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2 };  static char ign_sigs[] = { SIGCHLD, SIGWINCH };  static char mess_sigs[] = { SIGTERM, SIGHUP, SIGABRT, SIGQUIT };  register struct mproc *rmp;  register int i;  register char *sig_ptr;  phys_clicks total_clicks, minix_clicks, free_clicks;  message mess;  struct mem_map mem_map[NR_LOCAL_SEGS];  struct memory mem_chunks[NR_MEMS];  /* Initialize process table, including timers. */  for (rmp=&mproc[0]; rmp<&mproc[NR_PROCS]; rmp++) {	tmr_inittimer(&rmp->mp_timer);  }  /* Build the set of signals which cause core dumps, and the set of signals   * that are by default ignored.   */  sigemptyset(&core_sset);  for (sig_ptr = core_sigs; sig_ptr < core_sigs+sizeof(core_sigs); sig_ptr++)	sigaddset(&core_sset, *sig_ptr);  sigemptyset(&ign_sset);  for (sig_ptr = ign_sigs; sig_ptr < ign_sigs+sizeof(ign_sigs); sig_ptr++)	sigaddset(&ign_sset, *sig_ptr);  /* Obtain a copy of the boot monitor parameters and the kernel info struct.     * Parse the list of free memory chunks. This list is what the boot monitor    * reported, but it must be corrected for the kernel and system processes.   */  if ((s=sys_getmonparams(monitor_params, sizeof(monitor_params))) != OK)      panic(__FILE__,"get monitor params failed",s);  get_mem_chunks(mem_chunks);  if ((s=sys_getkinfo(&kinfo)) != OK)      panic(__FILE__,"get kernel info failed",s);  /* Get the memory map of the kernel to see how much memory it uses. */  if ((s=get_mem_map(SYSTASK, mem_map)) != OK)  	panic(__FILE__,"couldn't get memory map of SYSTASK",s);  minix_clicks = (mem_map[S].mem_phys+mem_map[S].mem_len)-mem_map[T].mem_phys;  patch_mem_chunks(mem_chunks, mem_map);  /* Initialize PM's process table. Request a copy of the system image table 

⌨️ 快捷键说明

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