github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/kernel/pipe.go (about) 1 package kernel 2 3 import ( 4 "syscall" 5 "unsafe" 6 7 "github.com/icexin/eggos/kernel/isyscall" 8 ) 9 10 // Timer depends on epoll and pipe. 11 // When timer is frequently used, it will be more efficient 12 // to implement it in the kernel 13 14 const ( 15 pipeReadFd = epollFd + 1 16 pipeWriteFd = epollFd + 2 17 ) 18 19 var ( 20 // FIXME: 21 // avoid dup create pipe 22 epollPipeCreated bool 23 // the bytes number in pipe 24 pipeBufferBytes int 25 ) 26 27 //go:nosplit 28 func sysPipe2(req *isyscall.Request) { 29 if epollPipeCreated { 30 req.SetErrorNO(syscall.EINVAL) 31 return 32 } 33 epollPipeCreated = true 34 fds := (*[2]int32)(unsafe.Pointer(req.Arg(0))) 35 fds[0] = pipeReadFd 36 fds[1] = pipeWriteFd 37 req.SetRet(0) 38 } 39 40 //go:nosplit 41 func sysPipeRead(req *isyscall.Request) { 42 fd := req.Arg(0) 43 buffer := req.Arg(1) 44 len := req.Arg(2) 45 _ = fd 46 _ = buffer 47 48 var n int 49 if int(len) < pipeBufferBytes { 50 n = int(len) 51 } else { 52 n = pipeBufferBytes 53 } 54 55 pipeBufferBytes -= n 56 epollNotify(pipeWriteFd, syscall.EPOLLOUT) 57 req.SetRet(uintptr(n)) 58 } 59 60 //go:nosplit 61 func sysPipeWrite(req *isyscall.Request) { 62 fd := req.Arg(0) 63 buffer := req.Arg(1) 64 len := req.Arg(2) 65 _ = fd 66 _ = buffer 67 68 pipeBufferBytes += int(len) 69 epollNotify(pipeReadFd, syscall.EPOLLIN) 70 req.SetRet(len) 71 }