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

📄 ipc.c

📁 一个操作系统的源代码
💻 C
字号:
/** ipc.c ** ** Original Author: Guido de Jong ** Date: 01/06/99 ** ** Description: ** Interprocess Communication **  ** This program is free software, you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version ** 2 of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be ** useful, but WITHOUT ANY WARRANTY; without even the implied ** warranty or MERCHANTABILITY or FITNESS FOR A PARTICULAR ** PURPOSE.  See the GNU General Public License for more ** details. ** ** You should have received a copy of the GNU General Public ** License along with this program; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place, Suite 330, ** Boston, MA 02111-1307 USA ** *********************************************************Apostle OS**/#include <address_space.h>#include <ipc.h>#include <mem.h>#include <paging.h>#include <process.h>#include <request.h>#include <scheduler.h>#ifdef DEBUG#include <debug/conio.h>#endif/* IPC parameters */#define ipc_opt (eax & 0xffff)#define ipc_rpc (eax & IPC_CALL_REMOTE)#define ipc_p   ((Process*)edx)#define ipc_t   ((int)ecx)#define ipc_act ((Activation*)ebx)#define ipc_sfp ((FlexiblePage)esi)#define ipc_dfp ((FlexiblePage)edi)#define min(a,b) ((a) < (b) ? (a) : (b))#define max(a,b) ((a) > (b) ? (a) : (b))int MemoryIPC(dword *as_from, FlexiblePage fp_from,              dword *as_to, FlexiblePage fp_to, IPC_Options opt){  size_t size;  void *from, *to;  if ((as_from == systemSpace) && ((int)fp_from == -1))    {      /* map/grant free pages */      int i;      to = FP_ADDR(fp_to);      size = FP_SIZE(fp_to);      for (i = 0; i < size; i++)        {          if ((from = pmalloc()))            {              /* map/grant just one page at a time */              if (opt & IPC_SND_MAPPING)                {                  map(as_from, from, as_to, to, 1,                      ((opt & IPC_SND_NO_ACCESS) ? 0 : PAGE_USER) | \                      ((opt & IPC_SND_READ_ONLY) ? 0 : PAGE_WRITABLE) | PAGE_PRESENT);                }              else if (opt & IPC_SND_GRANTING)                {                  grant(as_from, from, as_to, to, 1,                        ((opt & IPC_SND_NO_ACCESS) ? 0 : PAGE_USER) | \                        ((opt & IPC_SND_READ_ONLY) ? 0 : PAGE_WRITABLE) | PAGE_PRESENT);                }            }          else            {              /* out of memory; unmap everything and return */              flush(as_to, FP_ADDR(fp_to), i, FALSE, TRUE);              return 0;            }          to += PAGE_SIZE;        }      return 1;    }  else if ((as_from == systemSpace) && ((dword)FP_ADDR(fp_from) >= 0x20000000))    /* systen space ends at 0x20000000 */    return 0;  else    {      /* setup variables */      if (FP_SIZE(fp_from) > FP_SIZE(fp_to))        {#ifdef DEBUG          DebugPrintF("IPC error: sender flex page (%d) > receiver flex page (%d)\n", FP_SIZE(fp_from), FP_SIZE(fp_to));#endif          return 0;        }      from = FP_ADDR(fp_from);      if (fp_to == 0x0820)        to = from;	/* idempotently */      else        to = FP_ADDR(fp_to);      size = FP_SIZE(fp_from);      /* OK, here we go... */      if (opt & IPC_SND_MAPPING)        {          map(as_from, from, as_to, to, size,              ((opt & IPC_SND_NO_ACCESS) ? 0 : PAGE_USER) | \              ((opt & IPC_SND_READ_ONLY) ? 0 : PAGE_WRITABLE) | PAGE_PRESENT);        }      else if (opt & IPC_SND_GRANTING)        {          grant(as_from, from, as_to, to, size,                ((opt & IPC_SND_NO_ACCESS) ? 0 : PAGE_USER) | \                ((opt & IPC_SND_READ_ONLY) ? 0 : PAGE_WRITABLE) | PAGE_PRESENT);        }      /* map/grant should have worked... */      return 1;    }  return 0;}int IO_IPC(){  /* not implemented */  return 0;}int SendTo(dword eax, dword edx, dword ecx, dword ebx,           dword ebp, dword esi, dword edi){  Request *rcv;#ifdef DEBUG  DebugPrintF("SendTo called: %08x\n", (dword)ipc_p);#endif  if ((rcv = FindReceiveRequest(&kernelRequests, ipc_p, IPC_SND_RCV(ipc_opt))))    {      int retval = 0;      /* memory message */      if (ipc_opt & IPC_SND_MEMORY)        {          if (MemoryIPC(ipc_p->addressSpace, ipc_sfp,                        rcv->process->addressSpace, rcv->fpage, ipc_opt))            retval |= IPC_MEMORY_OK;        }      /* IO message */      if (ipc_opt & IPC_SND_IO)        {          IO_IPC();          retval |= IPC_IO_OK;        }      /* register message */      if (ipc_opt & IPC_SND_REGISTERS)        {          rcv->resumeActivation.ebx = ebx;          rcv->resumeActivation.ebp = ebp;          rcv->resumeActivation.esi = esi;          rcv->resumeActivation.edi = edi;          retval |= IPC_REGISTERS_OK;        }      /* remote procedure call */      if (ipc_rpc)        {          rcv->resumeActivation.ecx = (dword)currentActivation;          retval |= IPC_CALL_OK;        }      /* resume partner process */      rcv->resumeActivation.edx = (dword)currentProcess;      ResumeRequest(rcv, retval);      return retval;    }  else    {      if ((ipc_t > 0) || (ipc_opt & IPC_SND_WAIT4EVER))        Wait(ipc_t, ipc_p, ipc_opt, ipc_sfp);    }  return 0;}int ReceiveFrom(dword eax, dword edx, dword ecx, dword ebx,                dword ebp, dword esi, dword edi){  Request *snd;#ifdef DEBUG  DebugPrintF("ReceiveFrom called: %08x\n", (dword)ipc_p);#endif  if ((snd = FindSendRequest(&kernelRequests, ipc_p, IPC_RCV_SND(ipc_opt))))    {      int retval = 0;      /* memory message */      if (ipc_opt & IPC_SND_MEMORY)        {          if (MemoryIPC(snd->process->addressSpace, snd->fpage,                        ipc_p->addressSpace, ipc_dfp, snd->options))            retval |= IPC_MEMORY_OK;        }      /* IO message */      if (ipc_opt & IPC_RCV_IO)        {          IO_IPC();          retval |= IPC_IO_OK;        }            /* register message */      if (ipc_opt & IPC_RCV_REGISTERS)        {          /* not implemented */          retval |= IPC_REGISTERS_OK;        }      /* resume partner process */      snd->resumeActivation.edx = (dword)currentProcess;      ResumeRequest(snd, retval);      return retval;    }  else    {      if ((ipc_t > 0) || (ipc_opt & IPC_RCV_WAIT4EVER))        Wait(ipc_t, ipc_p, ipc_opt, ipc_dfp);    }  return 0;}int CallRemote(dword eax, dword edx, dword ecx, dword ebx,               dword ebp, dword esi, dword edi){#ifdef DEBUG  DebugPrintF("CallRemote called: %08x\n", (dword)ipc_p);#endif  if (ipc_p)    {      /* send message */      if (SendTo(ipc_opt | IPC_CALL_REMOTE, edx, ecx, ebx, ebp, esi, edi))        /* wait for reply from called process */        return ReceiveFrom(ipc_opt | IPC_CALL_REMOTE, edx, ecx, ebx, ebp, esi, edi);    }  else /* multiplexer is called */    {      int retval = 0;      /* request memory */      if (ipc_opt & IPC_RCV_MEMORY)        {          if (MemoryIPC(systemSpace, ipc_sfp,                        currentProcess->addressSpace, ipc_dfp, IPC_RCV_SND(ipc_opt)))            retval |= IPC_MEMORY_OK;        }       /* request IO ports */      if (ipc_opt & IPC_RCV_IO)        {          IO_IPC();          retval |= IPC_IO_OK;        }      return retval;    }  return 0;}int SendReceive(dword eax, dword edx, dword ecx, dword ebx,                dword ebp, dword esi, dword edi){  /* send reply with timeout 0 */  if (SendTo(eax, edx, 0, ebx, ebp, esi, edi))    /* wait for next message from any process */    return ReceiveFrom(eax, 0, ecx, ebx, ebp, esi, edi);  return 0;}

⌨️ 快捷键说明

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