-.PHONY: all clean nativelib DiskTool NetTest
+.PHONY: all clean
+.PHONY: nativelib DiskTool NetTest
+#.PHONY: nativelib-clean DiskTool-clean NetTest-clean
-all: DiskTool NetTest
+all clean: DiskTool NetTest
img2sif: img2sif.c
$(CC) -o $@ $< `sdl-config --libs --cflags` -lSDL_image -Wall
nativelib:
- $(MAKE) -C $@
+ $(MAKE) -C $@ $(MAKECMDGOALS)
DiskTool NetTest: nativelib
- $(MAKE) -C $@
+ $(MAKE) -C $@ $(MAKECMDGOALS)
NOBJ := logging.o misc.o threads_int.o
-LOBJ := threads.o time.o mutex.o rwlock.o semaphore.o
+LOBJ := threads.o time.o
+# mutex.o rwlock.o semaphore.o
KOBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o
KOBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o # vfs/select.o
KOBJ += vfs/fs/root.o vfs/fs/devfs.o
KOBJ += drv/proc.o
+KOBJ += mutex.o rwlock.o semaphore.o
NOBJ := $(NOBJ:%.o=obj/%.o)
LOBJ := $(LOBJ:%.o=obj/%.o)
$(RM) $(BIN) $(OBJ)
$(BIN): $(OBJ)
- ar cru $(BIN) $(OBJ)
+ ar cr $(BIN) $(OBJ)
-$(NOBJ): obj/%.o: %.c
+$(NOBJ): obj/%.o: %.c Makefile
@echo [CC Native] $@
@mkdir -p $(dir $@)
- @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
-$(LOBJ): obj/%.o: %.c
+$(LOBJ): obj/%.o: %.c Makefile
@echo [CC Local] $@
@mkdir -p $(dir $@)
- @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+ @$(CC) -o $@ -c $<
-MMD -MF [email protected] -MT $@ -MP $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
-$(KOBJ): obj/_Kernel/%.o: $(KERNEL_DIR)/%.c
+$(KOBJ): obj/_Kernel/%.o: $(KERNEL_DIR)/%.c Makefile
@echo [CC Kernel] $@
@mkdir -p $(dir $@)
- @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+ @$(CC) -o $@ -c $< -MMD -MF
[email protected] -MT $@ -MP $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+
+-include $(OBJ:%=%.dep)
#ifndef _THREADS_INT_H_
#define _THREADS_INT_H_
+#include <shortlock.h>
+
+typedef struct sThread tThread;
+
#define THREAD_EVENT_RWLOCK (1 << 8)
typedef struct sThreadIntMutex tThreadIntMutex; // actually pthreads
void *ThreadHandle;
int TID;
- tThreadIntMutex *Protector;
+ int Status;
+
+ tShortSpinlock IsLocked;
uint32_t PendingEvents;
uint32_t WaitingEvents;
tThreadIntSem *WaitSemaphore; // pthreads
- char *Name;
+ char *ThreadName;
+
+ int bInstrTrace; // Used for semaphore tracing
+
+ int RetStatus;
+ void *WaitPointer;
// Init Only
void (*SpawnFcn)(void*);
void *SpawnData;
};
+enum eThreadStatus {
+ THREAD_STAT_NULL, // Invalid process
+ THREAD_STAT_ACTIVE, // Running and schedulable process
+ THREAD_STAT_SLEEPING, // Message Sleep
+ THREAD_STAT_MUTEXSLEEP, // Mutex Sleep
+ THREAD_STAT_RWLOCKSLEEP, // Read-Writer lock Sleep
+ THREAD_STAT_SEMAPHORESLEEP, // Semaphore Sleep
+ THREAD_STAT_QUEUESLEEP, // Queue
+ THREAD_STAT_EVENTSLEEP, // Event sleep
+ THREAD_STAT_WAITING, // ??? (Waiting for a thread)
+ THREAD_STAT_PREINIT, // Being created
+ THREAD_STAT_ZOMBIE, // Died/Killed, but parent not informed
+ THREAD_STAT_DEAD, // Awaiting burial (free)
+ THREAD_STAT_BURIED // If it's still on the list here, something's wrong
+};
+static const char * const casTHREAD_STAT[] = {
+ "THREAD_STAT_NULL",
+ "THREAD_STAT_ACTIVE",
+ "THREAD_STAT_SLEEPING",
+ "THREAD_STAT_MUTEXSLEEP",
+ "THREAD_STAT_RWLOCKSLEEP",
+ "THREAD_STAT_SEMAPHORESLEEP",
+ "THREAD_STAT_QUEUESLEEP",
+ "THREAD_STAT_EVENTSLEEP",
+ "THREAD_STAT_WAITING",
+ "THREAD_STAT_PREINIT",
+ "THREAD_STAT_ZOMBIE",
+ "THREAD_STAT_DEAD",
+ "THREAD_STAT_BURIED"
+};
+
extern struct sThread __thread *lpThreads_This;
+extern tShortSpinlock glThreadListLock;
extern int Threads_int_CreateThread(struct sThread *Thread);
extern int Threads_int_ThreadingEnabled(void);
+extern tThread *Proc_GetCurThread(void);
+extern tThread *Threads_RemActive(void);
+extern void Threads_AddActive(tThread *Thread);
+extern void Threads_int_WaitForStatusEnd(enum eThreadStatus Status);
+
extern tThreadIntMutex *Threads_int_MutexCreate(void);
extern void Threads_int_MutexDestroy(tThreadIntMutex *Mutex);
extern void Threads_int_MutexLock(tThreadIntMutex *Mutex);
tThread *gThreads_List;
tThread __thread *lpThreads_This;
int giThreads_NextTID = 1;
+tShortSpinlock glThreadListLock;
// === CODE ===
void Threads_int_Init(void)
// nope.avi
return ;
}
- Threads_int_MutexLock(Thread->Protector);
+ SHORTLOCK( &Thread->IsLocked );
Thread->PendingEvents |= Events;
if( Thread->WaitingEvents & Events )
Threads_int_SemSignal(Thread->WaitSemaphore);
- Threads_int_MutexRelease(Thread->Protector);
+ SHORTREL( &Thread->IsLocked );
}
Uint32 Threads_WaitEvents(Uint32 Events)
Log_Notice("Threads", "_ClearEvent: Threading disabled");
return ;
}
- Threads_int_MutexLock(lpThreads_This->Protector);
+ SHORTLOCK(&lpThreads_This->IsLocked);
lpThreads_This->PendingEvents &= ~Mask;
- Threads_int_MutexRelease(lpThreads_This->Protector);
+ SHORTREL(&lpThreads_This->IsLocked);
}
tUID Threads_GetUID(void) { return 0; }
Log_Warning("Threads", "Threads_Sleep shouldn't be used");
}
+void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
+{
+ while( lpThreads_This->Status != Status )
+ Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
+}
+
int Threads_SetName(const char *Name)
{
if( !lpThreads_This )
return 0;
- if( lpThreads_This->Name )
- free(lpThreads_This->Name);
- lpThreads_This->Name = strdup(Name);
+ if( lpThreads_This->ThreadName )
+ free(lpThreads_This->ThreadName);
+ lpThreads_This->ThreadName = strdup(Name);
return 0;
}
return &a_errno;
}
+tThread *Threads_RemActive(void)
+{
+ return lpThreads_This;
+}
+
+void Threads_AddActive(tThread *Thread)
+{
+ Thread->Status = THREAD_STAT_ACTIVE;
+ // Increment state-change semaphore
+ Threads_int_SemSignal(Thread->WaitSemaphore);
+}
+
struct sProcess *Threads_int_CreateProcess(void)
{
struct sProcess *ret = calloc(sizeof(struct sProcess), 1);
tThread *ret = calloc( sizeof(tThread), 1 );
ret->TID = giThreads_NextTID ++;
ret->WaitSemaphore = Threads_int_SemCreate();
- ret->Protector = Threads_int_MutexCreate();
+ //ret->Protector = Threads_int_MutexCreate();
if( !Parent )
{