/*virtual*/ SysStatus PageAllocatorDefault::deallocAllPages(MemoryMgrPrimitive *memory) { uval start, end, size; SysStatus rc; // Retrieve and make available any memory still available for allocation. memory->allocAll(start, size, PAGE_SIZE); rc = deallocPages(start, size); _IF_FAILURE_RET(rc); // Retrieve and make available any recorded chunks of memory. while (memory->retrieveChunk(start, end)) { rc = deallocPages(start, (end - start)); _IF_FAILURE_RET(rc); } return 0; }
int sysPipe(int fd[2], int flags) { int error = validateUserPointer(fd, sizeof(*fd) * 2); if (error) return error; int readFD; int writeFD; struct Process *proc = getCurrentThread()->process; acquireSpinlock(&proc->fdLock); struct ProcessFile *rf; readFD = allocateFD(proc, &rf); if (readFD < 0) { error = readFD; releaseSpinlock(&proc->fdLock); goto release; } struct ProcessFile *wf; writeFD = allocateFD(proc, &wf); if (writeFD < 0) { error = readFD; releaseSpinlock(&proc->fdLock); goto deallocReadFD; } void *buf = allocKPages(PIPE_BUF, PAGE_FLAG_WRITE); if (!buf) { error = -ENOMEM; releaseSpinlock(&proc->fdLock); goto deallocWriteFD; } struct Pipe *pipe = kmalloc(sizeof(*pipe)); if (!pipe) { error = -ENOMEM; releaseSpinlock(&proc->fdLock); goto deallocBuf; } memset(pipe, 0, sizeof(*pipe)); pipe->buf = buf; pipe->refCount = 2; semInit(&pipe->bytesFree, PIPE_BUF); semInit(&pipe->bytesUsed, 0); if (flags & SYSOPEN_FLAG_CLOEXEC) { rf->flags |= PROCFILE_FLAG_CLOEXEC; } rf->flags |= PROCFILE_FLAG_PIPE; wf->flags = rf->flags | PROCFILE_FLAG_PIPE_WRITE; rf->pipe = pipe; wf->pipe = pipe; fd[0] = readFD; fd[1] = writeFD; goto release; deallocBuf: deallocPages(buf, PIPE_BUF); deallocWriteFD: sysClose(writeFD); deallocReadFD: sysClose(readFD); return error; release: releaseSpinlock(&proc->fdLock); return error; }