From 65409d2312e702a48d3cf5b32479d25266bda3c3 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 1 Jan 2020 18:22:19 -0800 Subject: 5858 Move script to create a Soso boot image into a sub-directory. I'm trying to streamline newcomer attention to just a couple of use cases. --- tools/iso/kernel.soso/pipe.c | 224 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 tools/iso/kernel.soso/pipe.c (limited to 'tools/iso/kernel.soso/pipe.c') diff --git a/tools/iso/kernel.soso/pipe.c b/tools/iso/kernel.soso/pipe.c new file mode 100644 index 00000000..7141305c --- /dev/null +++ b/tools/iso/kernel.soso/pipe.c @@ -0,0 +1,224 @@ +#include "list.h" +#include "pipe.h" +#include "fs.h" +#include "alloc.h" +#include "fifobuffer.h" + +static List* gPipeList = NULL; + +static FileSystemNode* gPipesRoot = NULL; + +static FileSystemDirent gDirent; + +typedef struct Pipe { + char name[32]; + FifoBuffer* buffer; + FileSystemNode* fsNode; + List* accessingThreads; +} Pipe; + +static BOOL pipes_open(File *file, uint32 flags); +static FileSystemDirent *pipes_readdir(FileSystemNode *node, uint32 index); +static FileSystemNode *pipes_finddir(FileSystemNode *node, char *name); + +void initializePipes() { + gPipeList = List_Create(); + + gPipesRoot = getFileSystemNode("/system/pipes"); + + if (NULL == gPipesRoot) { + WARNING("/system/pipes not found!!"); + } + else { + gPipesRoot->open = pipes_open; + gPipesRoot->finddir = pipes_finddir; + gPipesRoot->readdir = pipes_readdir; + } +} + +static BOOL pipes_open(File *file, uint32 flags) { + return TRUE; +} + +static FileSystemDirent *pipes_readdir(FileSystemNode *node, uint32 index) { + int counter = 0; + + List_Foreach (n, gPipeList) { + Pipe* p = (Pipe*)n->data; + + if (counter == index) { + strcpy(gDirent.name, p->name); + gDirent.fileType = FT_Pipe; + + return &gDirent; + } + ++counter; + } + + return NULL; +} + +static FileSystemNode *pipes_finddir(FileSystemNode *node, char *name) { + List_Foreach (n, gPipeList) { + Pipe* p = (Pipe*)n->data; + + if (strcmp(name, p->name) == 0) { + return p->fsNode; + } + } + + return NULL; +} + +static BOOL pipe_open(File *file, uint32 flags) { + beginCriticalSection(); + + Pipe* pipe = file->node->privateNodeData; + + List_Append(pipe->accessingThreads, file->thread); + + endCriticalSection(); + + return TRUE; +} + +static void pipe_close(File *file) { + beginCriticalSection(); + + Pipe* pipe = file->node->privateNodeData; + + List_RemoveFirstOccurrence(pipe->accessingThreads, file->thread); + + endCriticalSection(); +} + +static void blockAccessingThreads(Pipe* pipe) { + disableInterrupts(); + + List_Foreach (n, pipe->accessingThreads) { + Thread* reader = n->data; + + reader->state = TS_WAITIO; + + reader->state_privateData = pipe; + } + + enableInterrupts(); + + halt(); +} + +static void wakeupAccessingThreads(Pipe* pipe) { + beginCriticalSection(); + + List_Foreach (n, pipe->accessingThreads) { + Thread* reader = n->data; + + if (reader->state == TS_WAITIO) { + if (reader->state_privateData == pipe) { + reader->state = TS_RUN; + } + } + } + + endCriticalSection(); +} + +static int32 pipe_read(File *file, uint32 size, uint8 *buffer) { + if (0 == size || NULL == buffer) { + return -1; + } + + Pipe* pipe = file->node->privateNodeData; + + uint32 used = 0; + while ((used = FifoBuffer_getSize(pipe->buffer)) < size) { + blockAccessingThreads(pipe); + } + + disableInterrupts(); + + int32 readBytes = FifoBuffer_dequeue(pipe->buffer, buffer, size); + + wakeupAccessingThreads(pipe); + + return readBytes; +} + +static int32 pipe_write(File *file, uint32 size, uint8 *buffer) { + if (0 == size || NULL == buffer) { + return -1; + } + + Pipe* pipe = file->node->privateNodeData; + + uint32 free = 0; + while ((free = FifoBuffer_getFree(pipe->buffer)) < size) { + blockAccessingThreads(pipe); + } + + disableInterrupts(); + + int32 bytesWritten = FifoBuffer_enqueue(pipe->buffer, buffer, size); + + wakeupAccessingThreads(pipe); + + return bytesWritten; +} + +BOOL createPipe(const char* name, uint32 bufferSize) { + List_Foreach (n, gPipeList) { + Pipe* p = (Pipe*)n->data; + if (strcmp(name, p->name) == 0) { + return FALSE; + } + } + + Pipe* pipe = (Pipe*)kmalloc(sizeof(Pipe)); + memset((uint8*)pipe, 0, sizeof(Pipe)); + + strcpy(pipe->name, name); + pipe->buffer = FifoBuffer_create(bufferSize); + + pipe->accessingThreads = List_Create(); + + pipe->fsNode = (FileSystemNode*)kmalloc(sizeof(FileSystemNode)); + memset((uint8*)pipe->fsNode, 0, sizeof(FileSystemNode)); + pipe->fsNode->privateNodeData = pipe; + pipe->fsNode->open = pipe_open; + pipe->fsNode->close = pipe_close; + pipe->fsNode->read = pipe_read; + pipe->fsNode->write = pipe_write; + + List_Append(gPipeList, pipe); + + return TRUE; +} + +BOOL destroyPipe(const char* name) { + List_Foreach (n, gPipeList) { + Pipe* p = (Pipe*)n->data; + if (strcmp(name, p->name) == 0) { + List_RemoveFirstOccurrence(gPipeList, p); + FifoBuffer_destroy(p->buffer); + List_Destroy(p->accessingThreads); + kfree(p->fsNode); + kfree(p); + + return TRUE; + } + } + + return FALSE; +} + +BOOL existsPipe(const char* name) { + List_Foreach (n, gPipeList) { + Pipe* p = (Pipe*)n->data; + if (strcmp(name, p->name) == 0) { + return TRUE; + } + } + + return FALSE; +} -- cgit 1.4.1-2-gfad0