📄 request.c
字号:
/** request.c ** ** Original Author: Kasper Verdich Lund ** Date: 11.17.99 ** ** Description: ** ** 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 <activation.h>#include <ipc.h>#include <mem.h>#include <process.h>#include <request.h>#include <scheduler.h>#include <tss.h>#include <types.h>#ifdef DEBUG#include <debug/conio.h>#endifRequest* NewRequest(int ticks, Activation *a, Process *p, Process *partner, IPC_Options o, FlexiblePage fp){ Request *r = (Request*)malloc(sizeof(Request)); r->absoluteTick = currentTick + ticks; r->activation = a; r->process = p; r->partner = partner; r->options = o; r->fpage = fp; return r;}void InitializeRequest(Request *r, int ticks, Activation *a, Process *p, Process *partner, IPC_Options o, FlexiblePage fp){ r->absoluteTick = currentTick + ticks; r->activation = a; r->process = p; r->partner = partner; r->options = o; r->fpage = fp;}#ifdef DEBUGvoid PrintRequest(Request *r){ /* print request info */ DebugPrintF("%d", r->absoluteTick);}#endifvoid InsertRequest(RequestQueue *q, Request *r){ if (*q == NULL) { r->next = r; *q = r; } else { Request *prev = *q, *req = prev->next; while (req && (req->absoluteTick - r->absoluteTick <= 0)) { prev = req; req = ((prev == *q) ? NULL : prev->next); } /* now insert r after prev */ r->next = prev->next; prev->next = r; if (req == NULL) /* reached the end of queue */ *q = r; }}Request *FindSendRequest(RequestQueue *q, Process *p, IPC_Options o){ Request *prev = *q, *r = (*q)->next; while (p && (r->process != p) && ((r->options & o) != r->options)) { prev = r; r = ((prev == *q) ? NULL : prev->next); } if (r) { if (prev == r) *q = NULL; else prev->next = r->next; r->next = NULL; } return r;}Request *FindReceiveRequest(RequestQueue *q, Process *p, IPC_Options o){ Request *prev = *q, *r = (*q)->next; while (r->process && (r->process != p) && ((r->options & o) != o)) { prev = r; r = ((prev == *q) ? NULL : prev->next); } if (r) { if (prev == r) *q = NULL; else prev->next = r->next; r->next = NULL; } return r;}Request *TimedOutRequest(RequestQueue *q){ Request *r = NULL; /* skip infinite waiting requests */ while ((*q)->next->options & (IPC_SND_WAIT4EVER | IPC_RCV_WAIT4EVER)) *q = (*q)->next; /* the request queue is actually a chain! :-) */ if ((*q) && ((*q)->next->absoluteTick - currentTick <= 0)) { r = (*q)->next; if (*q == r) *q = NULL; else (*q)->next = r->next; r->next = NULL; } return r;}#ifdef DEBUGvoid PrintRequestQueue(RequestQueue q){ Request *r = q; DebugPrintF("RequestQueue: "); do { r = r->next; PrintRequest(r); if (r != q) DebugPrintF("->"); } while (r != q); DebugPrintF("\n");}#endifvoid ResumeRequest(Request *r, int status){ if (!currentProcess->singleThreaded) { currentProcess->deallocated = 1; currentProcess->pendingUpcallType = Preempted; currentProcess->pendingActivation = currentActivation; } InsertProcess(&readyQueue, currentProcess, TRUE);#ifdef DEBUG DebugPrintF("Resuming request\n");#endif currentActivation = r->activation; currentActivation->eax = status; currentProcess = r->process; KernelResume(&r->resumeActivation);}extern void __wait_return(void);void Wait(int ticks, Process *p, IPC_Options o, FlexiblePage fp){ Request r;#ifdef DEBUG DebugPrintF("Waiting for %d ticks\n", ticks);#endif InitializeRequest(&r, ticks, currentActivation, currentProcess, p, o, fp); r.resumeActivation.eip = (dword)&__wait_return; r.resumeActivation.eflags = 0x02; __asm__("movl %%esp, %0" : "=r" (r.resumeActivation.esp)); InsertRequest(&kernelRequests, &r); if (currentProcess->singleThreaded) Reallocate(); else { /* do upcall */ Activation *oldActivation = currentActivation; currentActivation = NewActivation(); /* upcall with blocked */ setKernelStack(systemTSS, currentActivation->esp0); Upcall(currentProcess, 1, Blocked, oldActivation); } __asm__("__wait_return:" "popl %esp");#ifdef DEBUG DebugPrintF("Wait returned\n");#endif set_CR3(currentProcess->addressSpace); if (!currentProcess->singleThreaded) { /* do upcall */ Activation *oldActivation = currentActivation; currentActivation = NewActivation(); /* upcall with blocked */ setKernelStack(systemTSS, currentActivation->esp0); Upcall(currentProcess, 1, Unblocked, oldActivation); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -