int WritePos;
int BufSize;
char *Buffer;
- tSemaphore Semaphore;
} tPipe;
// === PROTOTYPES ===
void FIFO_Close(tVFS_Node *Node);
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
+};
tDevFS_Driver gFIFO_DriverInfo = {
NULL, "fifo",
{
.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 = {
while(remaining)
{
// Wait for buffer to fill
- if(pipe->Flags & PF_BLOCKING) {
+ if(pipe->Flags & PF_BLOCKING)
+ {
+ #if 0
len = Semaphore_Wait( &pipe->Semaphore, remaining );
+ #else
+ VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "FIFO_Read");
+ // Read buffer
+ // TODO: Rethink this, it might not work on buffer overflow
+ if(pipe->WritePos - pipe->ReadPos < remaining)
+ len = pipe->WritePos - pipe->ReadPos;
+ else
+ len = remaining;
+ #endif
}
else
{
{
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
{
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;
}
return Length;
* \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;
{
// Wait for buffer to empty
if(pipe->Flags & PF_BLOCKING) {
+ #if 0
len = Semaphore_Signal( &pipe->Semaphore, remaining );
+ #else
+ VFS_SelectNode(Node, VFS_SELECT_WRITE, NULL, "FIFO_Write");
+ if(pipe->ReadPos - pipe->WritePos < remaining)
+ len = pipe->ReadPos - pipe->WritePos;
+ else
+ len = remaining;
+ #endif
}
else
{
{
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
{
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;
}
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 namelen = strlen(Name) + 1;
ret->Name = ret->Buffer + Size;
strcpy(ret->Name, Name);
// - Start empty, max of `Size`
- Semaphore_Init( &ret->Semaphore, 0, Size, "FIFO", ret->Name );
+ //Semaphore_Init( &ret->Semaphore, 0, Size, "FIFO", ret->Name );
// Set Node
ret->Node.Size = 0;
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;
}