if( argc-i != 3 ) {
Log_Error("NetTest", "'netcat' <addr> <port>");
PrintUsage(argv[0]);
+ return -1;
}
NetTest_Suite_Netcat(argv[i+1], strtol(argv[i+2], NULL, 0));
// === CODE ===
int VFS_SelectNode(tVFS_Node *Node, int Type, tTime *Timeout, const char *Name)
{
+ tThread *us = Proc_GetCurThread();
+
+ int ret = 0;
+
+ Threads_ClearEvent(THREAD_EVENT_VFS);
+
+ if( Type & VFS_SELECT_READ ) {
+ Node->ReadThreads = (void*)us;
+ if(Node->DataAvaliable) ret |= VFS_SELECT_READ;
+ }
+ if( Type & VFS_SELECT_WRITE ) {
+ Node->WriteThreads = (void*)us;
+ if(!Node->BufferFull) ret |= VFS_SELECT_WRITE;
+ }
+ if( Type & VFS_SELECT_ERROR ) {
+ Node->ErrorThreads = (void*)us;
+ if(Node->ErrorOccurred) ret |= VFS_SELECT_ERROR;
+ }
- return 0;
+ if( !ret )
+ {
+ // TODO: Timeout
+ Threads_WaitEvents(THREAD_EVENT_VFS);
+ }
+
+ if( Type & VFS_SELECT_READ ) {
+ Node->ReadThreads = NULL;
+ if(Node->DataAvaliable) ret |= VFS_SELECT_READ;
+ }
+ if( Type & VFS_SELECT_WRITE ) {
+ Node->WriteThreads = NULL;
+ if(!Node->BufferFull) ret |= VFS_SELECT_WRITE;
+ }
+ if( Type & VFS_SELECT_ERROR ) {
+ Node->ErrorThreads = NULL;
+ if(Node->ErrorOccurred) ret |= VFS_SELECT_ERROR;
+ }
+ return ret;
}
int VFS_MarkAvaliable(tVFS_Node *Node, BOOL bAvail)
return 0;
}
+int VFS_MarkFull(tVFS_Node *Node, BOOL bError)
+{
+ Node->BufferFull = bError;
+ if( !Node->BufferFull && Node->WriteThreads )
+ Threads_PostEvent( (void*)Node->WriteThreads, THREAD_EVENT_VFS );
+ return 0;
+}
+
+
#if 0
int VFS_Open(const char *Path, Uint Flags)
{
typedef uint32_t tGID;
typedef uint32_t tTID;
-// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
-typedef char tShortSpinlock;
-
typedef int64_t tTime;
extern tTime now(void);
extern int64_t timestamp(int sec, int min, int hr, int day, int month, int year);
static inline int MIN(int a, int b) { return a < b ? a : b; }
static inline int MAX(int a, int b) { return a > b ? a : b; }
-#if USE_MULTITHREADING
-#error "TODO: Impliment multithreaded SHORTLOCK"
-#else
-static inline void SHORTLOCK(tShortSpinlock *Lock) {
- if(*Lock) Log_KernelPanic("---", "Double short lock");
- *Lock = 1;
-}
-static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
-static inline int CPU_HAS_LOCK(tShortSpinlock *m) { return *m; }
-#endif
+#include <shortlock.h>
static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
static inline int MM_IsUser(const void *Ptr) { return 1; }
--- /dev/null
+/*
+ * Acess2 native library
+ * - By John Hodge (thePowersGang)
+ *
+ * shortlock.h
+ * - Short locks :)
+ */
+#ifndef _SHORTLOCK_H_
+#define _SHORTLOCK_H_
+
+typedef void *tShortSpinlock;
+
+extern void SHORTLOCK(tShortSpinlock *Lock);
+extern void SHORTREL(tShortSpinlock *m);
+extern int CPU_HAS_LOCK(tShortSpinlock *m);
+
+#endif
/*
- *
+ * Acess2 libnative (Kernel Simulation Library)
+ * - By John Hodge (thePowersGang)
+ *
+ * logging.c
+ * - Logging functions
*/
#include <stdio.h>
#include <stdarg.h>
#include <acess_logging.h>
#include <ctype.h>
#include <inttypes.h>
+#include <shortlock.h>
-#define LOGHDR(col,type) fprintf(stderr, "\e["col"m[%-8.8s]"type" ", Ident)
+extern int Threads_GetTID();
+
+#define LOGHDR(col,type) fprintf(stderr, "\e["col"m[%-8.8s]"type"%2i ", Ident, Threads_GetTID())
#define LOGTAIL() fprintf(stderr, "\e[0m\n")
#define PUTERR(col,type) {\
+ if(!gbThreadInLog) SHORTLOCK(&glDebugLock); \
+ gbThreadInLog ++; \
LOGHDR(col,type);\
va_list args; va_start(args, Message);\
vfprintf(stderr, Message, args);\
va_end(args);\
LOGTAIL();\
+ gbThreadInLog --; \
+ if(!gbThreadInLog) SHORTREL(&glDebugLock); \
}
+// === GLOBALS ===
+int __thread gbThreadInLog;
+tShortSpinlock glDebugLock;
+
// === CODE ===
void Log_KernelPanic(const char *Ident, const char *Message, ...) {
PUTERR("35", "k")
- abort();
+ exit(-1);
}
void Log_Panic(const char *Ident, const char *Message, ...)
PUTERR("34", "p")
#include <acess.h>
#include <semaphore.h>
+#if 0
+TODO:: Rework kernel-land semaphore code to use events
+- Allows it to be used here and be tested easier
+#endif
+
// === CODE ===
void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name)
{
// === GLOBALS ===
tThread *gThreads_List;
tThread __thread *lpThreads_This;
+ int giThreads_NextTID = 1;
// === CODE ===
void Threads_int_Init(void)
Uint32 Threads_WaitEvents(Uint32 Events)
{
- if( Threads_int_ThreadingEnabled() ) {
+ if( !Threads_int_ThreadingEnabled() ) {
Log_Notice("Threads", "_WaitEvents: Threading disabled");
return 0;
}
void Threads_ClearEvent(Uint32 Mask)
{
- if( Threads_int_ThreadingEnabled() ) {
+ if( !Threads_int_ThreadingEnabled() ) {
Log_Notice("Threads", "_ClearEvent: Threading disabled");
return ;
}
tUID Threads_GetUID(void) { return 0; }
tGID Threads_GetGID(void) { return 0; }
-tTID Threads_GetTID(void) { return 0; }
+tTID Threads_GetTID(void) { return lpThreads_This->TID; }
int *Threads_GetMaxFD(void) { return &lpThreads_This->Process->MaxFDs; }
char **Threads_GetCWD(void) { return &lpThreads_This->Process->CWD; }
tThread *Threads_int_CreateTCB(tThread *Parent)
{
tThread *ret = calloc( sizeof(tThread), 1 );
+ ret->TID = giThreads_NextTID ++;
ret->WaitSemaphore = Threads_int_SemCreate();
ret->Protector = Threads_int_MutexCreate();
#include <acess_logging.h>
#include <threads_int.h>
#include <pthread_weak.h>
+#include <shortlock.h>
// === TYPES ===
typedef struct sThread tThread;
// === CODE ===
int Threads_int_ThreadingEnabled(void)
{
- Log_Debug("Threads", "pthread_create = %p", pthread_create);
return !!pthread_create;
}
}
}
+void SHORTLOCK(tShortSpinlock *Lock)
+{
+ if( !pthread_mutex_init )
+ {
+ if(*Lock) Log_KernelPanic("---", "Double short lock");
+ *Lock = (void*)1;
+ }
+ else
+ {
+ if( !*Lock ) {
+ *Lock = malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(*Lock, NULL);
+ }
+ pthread_mutex_lock(*Lock);
+ }
+}
+
+void SHORTREL(tShortSpinlock *Lock)
+{
+ if( !pthread_mutex_init )
+ {
+ if(!*Lock) Log_Notice("---", "Short release when not held");
+ *Lock = NULL;
+ }
+ else
+ {
+ pthread_mutex_unlock(*Lock);
+ }
+}
+
+int CPU_HAS_LOCK(tShortSpinlock *Lock)
+{
+ return 0;
+}
+