📄 ipc.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 + -