X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Ffifo.c;h=0779a60b9ee014480a51ffb14ac5f3b782886948;hb=a2495c6ea4f4cab16b5d339ae511428e92e89e73;hp=67b9a6d702aaa133f911bcc1611c717bdac704c7;hpb=156885e938b60fee9d061d989ae7711c9aeea493;p=tpg%2Facess2.git diff --git a/Kernel/drv/fifo.c b/Kernel/drv/fifo.c index 67b9a6d7..0779a60b 100644 --- a/Kernel/drv/fifo.c +++ b/Kernel/drv/fifo.c @@ -1,9 +1,11 @@ /* AcessOS * FIFO Pipe Driver */ +#define DEBUG 0 #include #include #include +#include // === CONSTANTS === #define DEFAULT_RING_SIZE 2048 @@ -25,27 +27,40 @@ typedef struct sPipe { int FIFO_Install(char **Arguments); int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data); char *FIFO_ReadDir(tVFS_Node *Node, int Id); -tVFS_Node *FIFO_FindDir(tVFS_Node *Node, char *Filename); - int FIFO_MkNod(tVFS_Node *Node, char *Name, Uint Flags); +tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename); + int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags); +void FIFO_Reference(tVFS_Node *Node); void FIFO_Close(tVFS_Node *Node); - int FIFO_Relink(tVFS_Node *Node, char *OldName, char *NewName); + int FIFO_Relink(tVFS_Node *Node, const char *OldName, const char *NewName); Uint64 FIFO_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); -Uint64 FIFO_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); -tPipe *FIFO_Int_NewPipe(int Size, char *Name); +Uint64 FIFO_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer); +tPipe *FIFO_Int_NewPipe(int Size, const char *Name); // === GLOBALS === MODULE_DEFINE(0, 0x0032, FIFO, FIFO_Install, NULL, NULL); +tVFS_NodeType gFIFO_DirNodeType = { + .TypeName = "FIFO Dir Node", + .ReadDir = FIFO_ReadDir, + .FindDir = FIFO_FindDir, + .MkNod = FIFO_MkNod, + .Relink = FIFO_Relink, + .IOCtl = FIFO_IOCtl +}; +tVFS_NodeType gFIFO_PipeNodeType = { + .TypeName = "FIFO Pipe Node", + .Read = FIFO_Read, + .Write = FIFO_Write, + .Close = FIFO_Close, + .Reference = FIFO_Reference +}; tDevFS_Driver gFIFO_DriverInfo = { NULL, "fifo", { + .Size = 1, .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRW, .Flags = VFS_FFLAG_DIRECTORY, - .ReadDir = FIFO_ReadDir, - .FindDir = FIFO_FindDir, - .MkNod = FIFO_MkNod, - .Relink = FIFO_Relink, - .IOCtl = FIFO_IOCtl + .Type = &gFIFO_DirNodeType } }; tVFS_Node gFIFO_AnonNode = { @@ -80,6 +95,7 @@ int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data) char *FIFO_ReadDir(tVFS_Node *Node, int Id) { tPipe *tmp = gFIFO_NamedPipes; + // Entry 0 is Anon Pipes if(Id == 0) return strdup("anon"); @@ -92,11 +108,11 @@ char *FIFO_ReadDir(tVFS_Node *Node, int Id) } /** - * \fn tVFS_Node *FIFO_FindDir(tVFS_Node *Node, char *Filename) + * \fn tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename) * \brief Find a file in the FIFO root * \note Creates an anon pipe if anon is requested */ -tVFS_Node *FIFO_FindDir(tVFS_Node *Node, char *Filename) +tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename) { tPipe *tmp; if(!Filename) return NULL; @@ -124,13 +140,20 @@ tVFS_Node *FIFO_FindDir(tVFS_Node *Node, char *Filename) } /** - * \fn int FIFO_MkNod(tVFS_Node *Node, char *Name, Uint Flags) + * \fn int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) */ -int FIFO_MkNod(tVFS_Node *Node, char *Name, Uint Flags) +int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) { return 0; } +void FIFO_Reference(tVFS_Node *Node) +{ + if(!Node->ImplPtr) return ; + + Node->ReferenceCount ++; +} + /** * \fn void FIFO_Close(tVFS_Node *Node) * \brief Close a FIFO end @@ -146,6 +169,7 @@ void FIFO_Close(tVFS_Node *Node) pipe = Node->ImplPtr; if(strcmp(pipe->Name, "anon") == 0) { + Log_Debug("FIFO", "Pipe %p closed", Node->ImplPtr); free(Node->ImplPtr); return ; } @@ -154,10 +178,10 @@ void FIFO_Close(tVFS_Node *Node) } /** - * \fn int FIFO_Relink(tVFS_Node *Node, char *OldName, char *NewName) + * \fn int FIFO_Relink(tVFS_Node *Node, const char *OldName, const char *NewName) * \brief Relink a file (Deletes named pipes) */ -int FIFO_Relink(tVFS_Node *Node, char *OldName, char *NewName) +int FIFO_Relink(tVFS_Node *Node, const char *OldName, const char *NewName) { tPipe *pipe, *tmp; @@ -210,31 +234,50 @@ Uint64 FIFO_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) tPipe *pipe = Node->ImplPtr; Uint len; Uint remaining = Length; - + if(!pipe) return 0; + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + while(remaining) { // Wait for buffer to fill if(pipe->Flags & PF_BLOCKING) - while(pipe->ReadPos == pipe->WritePos) - Threads_Yield(); + { + if( pipe->ReadPos == pipe->WritePos ) + VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "FIFO_Read"); + + } else + { if(pipe->ReadPos == pipe->WritePos) + { + VFS_MarkAvaliable(Node, 0); + LEAVE('i', 0); return 0; - - // Read buffer - if(pipe->WritePos - pipe->ReadPos < remaining) - len = pipe->WritePos - pipe->ReadPos; + } + } + + len = remaining; + if( pipe->ReadPos < pipe->WritePos ) + { + int avail_bytes = pipe->WritePos - pipe->ReadPos; + if( avail_bytes < remaining ) len = avail_bytes; + } else - len = remaining; - + { + int avail_bytes = pipe->WritePos + pipe->BufSize - pipe->ReadPos; + if( avail_bytes < remaining ) len = avail_bytes; + } + + LOG("len = %i, remaining = %i", len, remaining); + // Check if read overflows buffer if(len > pipe->BufSize - pipe->ReadPos) { int ofs = pipe->BufSize - pipe->ReadPos; memcpy(Buffer, &pipe->Buffer[pipe->ReadPos], ofs); - memcpy(Buffer + ofs, &pipe->Buffer, len-ofs); + memcpy((Uint8*)Buffer + ofs, &pipe->Buffer, len-ofs); } else { @@ -245,12 +288,23 @@ Uint64 FIFO_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) pipe->ReadPos += len; pipe->ReadPos %= pipe->BufSize; + // Mark some flags + if( pipe->ReadPos == pipe->WritePos ) { + VFS_MarkAvaliable(Node, 0); + } + VFS_MarkFull(Node, 0); // Buffer can't still be full + // Decrement Remaining Bytes remaining -= len; // Increment Buffer address - Buffer += len; + Buffer = (Uint8*)Buffer + len; + + // TODO: Option to read differently + LEAVE('i', len); + return len; } + LEAVE('i', Length); return Length; } @@ -259,36 +313,55 @@ Uint64 FIFO_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) * \fn Uint64 FIFO_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) * \brief Write to a fifo pipe */ -Uint64 FIFO_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +Uint64 FIFO_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer) { tPipe *pipe = Node->ImplPtr; Uint len; Uint remaining = Length; if(!pipe) return 0; + + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); while(remaining) { // Wait for buffer to empty - if(pipe->Flags & PF_BLOCKING) - while(pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize) - Threads_Yield(); + if(pipe->Flags & PF_BLOCKING) { + if( pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize ) + VFS_SelectNode(Node, VFS_SELECT_WRITE, NULL, "FIFO_Write"); + + len = remaining; + if( pipe->ReadPos > pipe->WritePos ) + { + int rem_space = pipe->ReadPos - pipe->WritePos; + if(rem_space < remaining) len = rem_space; + } + else + { + int rem_space = pipe->ReadPos + pipe->BufSize - pipe->WritePos; + if(rem_space < remaining) len = rem_space; + } + } else + { if(pipe->ReadPos == (pipe->WritePos+1)%pipe->BufSize) + { + LEAVE('i', 0); return 0; - - // Write buffer - if(pipe->ReadPos - pipe->WritePos < remaining) - len = pipe->ReadPos - pipe->WritePos; - else - len = remaining; + } + // Write buffer + if(pipe->ReadPos - pipe->WritePos < remaining) + len = pipe->ReadPos - pipe->WritePos; + else + len = remaining; + } // Check if write overflows buffer if(len > pipe->BufSize - pipe->WritePos) { int ofs = pipe->BufSize - pipe->WritePos; memcpy(&pipe->Buffer[pipe->WritePos], Buffer, ofs); - memcpy(&pipe->Buffer, Buffer + ofs, len-ofs); + memcpy(&pipe->Buffer, (Uint8*)Buffer + ofs, len-ofs); } else { @@ -299,42 +372,51 @@ Uint64 FIFO_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) pipe->WritePos += len; pipe->WritePos %= pipe->BufSize; + // Mark some flags + if( pipe->ReadPos == pipe->WritePos ) { + VFS_MarkFull(Node, 1); // Buffer full + } + VFS_MarkAvaliable(Node, 1); + // Decrement Remaining Bytes remaining -= len; // Increment Buffer address - Buffer += len; + Buffer = (Uint8*)Buffer + len; } + LEAVE('i', Length); return Length; } // --- HELPERS --- /** - * \fn tPipe *FIFO_Int_NewPipe(int Size, char *Name) + * \fn tPipe *FIFO_Int_NewPipe(int Size, const char *Name) * \brief Create a new pipe */ -tPipe *FIFO_Int_NewPipe(int Size, char *Name) +tPipe *FIFO_Int_NewPipe(int Size, const char *Name) { tPipe *ret; - int allocsize = sizeof(tPipe) + sizeof(tVFS_ACL) + Size; + int namelen = strlen(Name) + 1; + int allocsize = sizeof(tPipe) + sizeof(tVFS_ACL) + Size + namelen; - ret = malloc(allocsize); + ret = calloc(1, allocsize); if(!ret) return NULL; // Clear Return - memset(ret, 0, allocsize); - - ret->Name = Name; + ret->Flags = PF_BLOCKING; // Allocate Buffer ret->BufSize = Size; ret->Buffer = (void*)( (Uint)ret + sizeof(tPipe) + sizeof(tVFS_ACL) ); - if(!ret->Buffer) { - free(ret); - return NULL; - } + + // Set name (and FIFO name) + ret->Name = ret->Buffer + Size; + strcpy(ret->Name, Name); + // - Start empty, max of `Size` + //Semaphore_Init( &ret->Semaphore, 0, Size, "FIFO", ret->Name ); // Set Node + ret->Node.ReferenceCount = 1; ret->Node.Size = 0; ret->Node.ImplPtr = ret; ret->Node.UID = Threads_GetUID(); @@ -348,9 +430,7 @@ tPipe *FIFO_Int_NewPipe(int Size, char *Name) ret->Node.CTime = ret->Node.MTime = ret->Node.ATime = now(); - ret->Node.Read = FIFO_Read; - ret->Node.Write = FIFO_Write; - ret->Node.Close = FIFO_Close; + ret->Node.Type = &gFIFO_PipeNodeType; return ret; }