-BUILD_NUM = 224
+BUILD_NUM = 225
Uint i;
for(base = KERNEL_STACKS; base < KERNEL_STACKS_END; base += KERNEL_STACK_SIZE)
{
+ // Check if space is free
if(MM_GetPhysAddr(base) != 0) continue;
- for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000) {
- MM_Allocate(base+i);
+ // Allocate
+ //for(i = KERNEL_STACK_SIZE; i -= 0x1000 ; )
+ for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000 )
+ {
+ if( MM_Allocate(base+i) == 0 )
+ {
+ // On error, print a warning and return error
+ Warning("MM_NewKStack - Out of memory");
+ // - Clean up
+ //for( i += 0x1000 ; i < KERNEL_STACK_SIZE; i += 0x1000 )
+ // MM_Deallocate(base+i);
+ return 0;
+ }
}
+ // Success
Log("MM_NewKStack - Allocated %p", base + KERNEL_STACK_SIZE);
return base+KERNEL_STACK_SIZE;
}
- Warning("MM_NewKStack - No address space left\n");
+ // No stacks left
+ Warning("MM_NewKStack - No address space left");
return 0;
}
// Initialise Memory Space (New Addr space or kernel stack)
if(Flags & CLONE_VM) {
newThread->MemState.CR3 = MM_Clone();
+ // Check for errors
+ if(newThread->MemState.CR3 == 0) {
+ Threads_Kill(newThread, -2);
+ return -1;
+ }
newThread->KernelStack = cur->KernelStack;
} else {
Uint tmpEbp, oldEsp = esp;
newThread->KernelStack = MM_NewKStack();
// Check for errors
if(newThread->KernelStack == 0) {
- free(newThread);
+ Threads_Kill(newThread, -2);
return -1;
}
{
Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
LEAVE('-');
- Threads_Exit(0, 0);
+ Threads_Exit(0, -10);
for(;;);
}
extern tThread *Threads_GetThread(Uint TID);
extern void Threads_SetPriority(tThread *Thread, int Pri);
extern int Threads_Wake(tThread *Thread);
+extern void Threads_Kill(tThread *Thread, int Status);
extern void Threads_AddActive(tThread *Thread);
extern tThread *Threads_GetNextToRun(int CPU, tThread *Last);
SHORTLOCK( &glThreadListLock );
new->GlobalPrev = NULL; // Protect against bugs
new->GlobalNext = gAllThreads;
+ gAllThreads->GlobalPrev = new;
gAllThreads = new;
SHORTREL( &glThreadListLock );
tMsg *msg;
// TODO: Kill all children
- #if 0
+ #if 1
{
tThread *child;
// TODO: I should keep a .Parent pointer, and a .Children list
- for(child = gActiveThreads;
+ for(child = gAllThreads;
child;
- child = child->Next)
+ child = child->GlobalNext)
{
- if(child->PTID == Thread->TID)
+ if(child->Parent == Thread)
Threads_Kill(child, -1);
}
}
// Lock thread list
SHORTLOCK( &glThreadListLock );
- // Delete from active list
- #if SCHEDULER_TYPE == SCHED_RR_PRI
- if( !Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread ) )
- #else
- if( !Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
- #endif
+ switch(Thread->Status)
{
- Warning("Proc_Exit - Current thread is not on the active queue");
- SHORTREL( &glThreadListLock );
- SHORTREL( &Thread->IsLocked );
- return;
- }
+ case THREAD_STAT_PREINIT: // Only on main list
+ break;
- // Ensure that we are not rescheduled
- Thread->Remaining = 0; // Clear Remaining Quantum
- Thread->Quantum = 0; // Clear Quantum to indicate dead thread
-
- // Update bookkeeping
- giNumActiveThreads --;
- #if SCHEDULER_TYPE == SCHED_LOTTERY
- if( Thread != Proc_GetCurThread() )
- giFreeTickets -= caiTICKET_COUNTS[ Thread->Priority ];
- #endif
+ // Currently active thread
+ case THREAD_STAT_ACTIVE:
+ #if SCHEDULER_TYPE == SCHED_RR_PRI
+ if( Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread ) )
+ #else
+ if( Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
+ #endif
+ {
+ // Ensure that we are not rescheduled
+ Thread->Remaining = 0; // Clear Remaining Quantum
+ Thread->Quantum = 0; // Clear Quantum to indicate dead thread
+
+ // Update bookkeeping
+ giNumActiveThreads --;
+ #if SCHEDULER_TYPE == SCHED_LOTTERY
+ if( Thread != Proc_GetCurThread() )
+ giFreeTickets -= caiTICKET_COUNTS[ Thread->Priority ];
+ #endif
+ }
+ else
+ {
+ Log_Warning("Threads",
+ "Threads_Kill - Thread %p(%i,%s) marked as active, but not on list",
+ Thread, Thread->TID, Thread->ThreadName
+ );
+ }
+ break;
+ case THREAD_STAT_SLEEPING:
+ if( !Threads_int_DelFromQueue( &gSleepingThreads, Thread ) )
+ {
+ Log_Warning("Threads",
+ "Threads_Kill - Thread %p(%i,%s) marked as sleeping, but not on list",
+ Thread, Thread->TID, Thread->ThreadName
+ );
+ }
+ break;
+ default:
+ Log_Warning("Threads", "Threads_Kill - BUG Un-checked status (%i)",
+ Thread->Status);
+ break;
+ }
// Save exit status
Thread->RetStatus = Status;
Threads_Wake( Thread->Parent );
}
- Log("Thread %i went *hurk* (%i)", Thread->TID, Thread->Status);
+ Log("Thread %i went *hurk* (%i)", Thread->TID, Status);
// Release spinlocks
SHORTREL( &glThreadListLock );
while(gDeleteThreads)
{
thread = gDeleteThreads->Next;
- if( IS_LOCKED(&gDeleteThreads->IsLocked) ) { // Only free if structure is unused
+ // Only free if structure is unused
+ if( !IS_LOCKED(&gDeleteThreads->IsLocked) )
+ {
// Set to dead
gDeleteThreads->Status = THREAD_STAT_BURIED;
// Free name
* AcessOS 1\r
* Video BIOS Extensions (Vesa) Driver\r
*/\r
-#define DEBUG 1\r
+#define DEBUG 0\r
#define VERSION 0x100\r
\r
#include <acess.h>\r
break;\r
}\r
\r
- tmp = gVesa_Modes[i].width * gVesa_Modes[i].height * gVesa_Modes[i].bpp;\r
- tmp -= data->width * data->height * data->bpp;\r
+ tmp = gVesa_Modes[i].width * gVesa_Modes[i].height;\r
+ tmp -= data->width * data->height;\r
tmp = tmp < 0 ? -tmp : tmp;\r
- factor = tmp * 100 / (data->width * data->height * data->bpp);\r
+ factor = tmp * 100 / (data->width * data->height);\r
+ \r
+ if( (data->bpp == 32 || data->bpp == 24)\r
+ && (gVesa_Modes[i].bpp == 32 || gVesa_Modes[i].bpp == 24) )\r
+ {\r
+ \r
+ }\r
+ else {\r
+ factor *= 10;\r
+ }\r
\r
LOG("factor = %i", factor);\r
\r
for(;;) clone(CLONE_VM, 0);
}
else {
- for(;;) clone(0, malloc(512-16)+512-16);
+ for(;;)
+ {
+ const int stackSize = 512-16;
+ const int stackOffset = 65;
+ char *stack = calloc(1, stackSize);
+ int tid;
+ if( !stack ) {
+ printf("Outta heap space!\n");
+ return 0;
+ }
+ tid = clone(0, stack+stackSize-stackOffset);
+ if( tid == 0 )
+ {
+ // Sleep forever (TODO: Fix up the stack so it can nuke)
+ for(;;) sleep();
+ }
+ if( tid < 0 ) {
+ printf("Clone failed\n");
+ return 0;
+ }
+ printf("stack = %p, tid = %i\n", stack, tid);
+ }
}
+ printf("RETURN!?\n");
return 0;
}
start:
call main
push eax
- call _exit
+ call _exit
jmp $ ; This should never be reached
dd 0
[section .text]
-; --- Process Controll ---
+; DEST
+; SRC
+_memcpy:
+ push ebp
+ mov ebp, esp
+ push edi
+ push esi ; DI and SI must be maintained, CX doesn't
+
+ mov ecx, [ebp+16]
+ mov esi, [ebp+12]
+ mov edi, [ebp+8]
+ rep movsb
+
+ pop esi
+ pop edi
+ pop ebp
+ ret
+
+; --- Process Control ---
SYSCALL1 _exit, SYS_EXIT
+
+%if 0
SYSCALL2 clone, SYS_CLONE
+%else
+[global clone:func]
+clone:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+ mov ebx, [ebp+12] ; Get new stack pointer
+
+ ; Check if the new stack is being used
+ test ebx, ebx
+ jz .doCall
+ ; Modify it to include the calling function (and this)
+ %if 0
+ mov eax, [ebp] ; Get old stack frame
+ sub eax, ebp ; Get size
+ sub ebx, eax ; Alter new stack pointer
+ push eax ; < Size
+ push DWORD [ebp] ; < Source
+ push ebx ; < Dest
+ call _memcpy
+ add esp, 4*3 ; Restore stack
+ ; EBX should still be the new stack pointer
+ mov eax, [ebp] ; Save old stack frame pointer in new stack
+ mov [ebx-4], eax
+ mov eax, [ebp-4] ; Save EBX there too
+ mov [ebx-8], eax
+ sub ebx, 8 ; Update stack pointer for system
+ %else
+ ; Quick hack, just this stack frame
+ mov eax, [ebp+4]
+ mov [ebx-4], eax ; Return
+ mov [ebx-8], ebx ; EBP
+ mov DWORD [ebx-12], 0 ; EBX
+ sub ebx, 12
+ %endif
+.doCall:
+ mov eax, SYS_CLONE
+ mov ecx, ebx ; Stack
+ mov ebx, [ebp+8] ; Flags
+ SYSCALL_OP
+ mov [_errno], ebx
+ pop ebx
+ pop ebp
+ ret
+%endif
+
SYSCALL2 kill, SYS_KILL
SYSCALL0 yield, SYS_YIELD
SYSCALL0 sleep, SYS_SLEEP
EXP(_SysOpenChild),
EXP(_SysGetPhys),
- EXP(_SysAllocate)
+ EXP(_SysAllocate),
+ EXP(_SysDebug)
};
EXPORT void *realloc(void *mem, Uint bytes);\r
EXPORT void *sbrk(int increment);\r
LOCAL void *extendHeap(int bytes);\r
+static void *FindHeapBase();\r
LOCAL uint brk(Uint newpos);\r
\r
//Code\r
\r
while((Uint)curBlock < (Uint)_heap_end)\r
{\r
- //SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);\r
+ //_SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);\r
if(curBlock->magic == MAGIC_FREE)\r
{\r
if(curBlock->size == bestSize)\r
else if(curBlock->magic != MAGIC)\r
{\r
//Corrupt Heap\r
- //SysDebug("malloc: Corrupt Heap\n");\r
+ _SysDebug("malloc: Corrupt Heap\n");\r
return NULL;\r
}\r
curBlock = (heap_head*)((Uint)curBlock + curBlock->size);\r
}\r
\r
if((Uint)curBlock < (Uint)_heap_start) {\r
- //SysDebug("malloc: Heap underrun for some reason\n");\r
+ _SysDebug("malloc: Heap underrun for some reason\n");\r
return NULL;\r
}\r
\r
if(!closestMatch) {\r
curBlock = extendHeap(bestSize); //Allocate more\r
if(curBlock == NULL) {\r
- //SysDebug("malloc: Out of Heap Space\n");\r
+ _SysDebug("malloc: Out of Heap Space\n");\r
return NULL;\r
}\r
curBlock->magic = MAGIC;\r
if(foot == (void*)-1)\r
return NULL;\r
\r
- \r
//Create New Block\r
// Header\r
head->magic = MAGIC_FREE; //Unallocated\r
*/\r
EXPORT void *sbrk(int increment)\r
{\r
- size_t newEnd;\r
static size_t oldEnd = 0;\r
static size_t curEnd = 0;\r
\r
- //_SysDebug("sbrk: (increment=%i)\n", increment);\r
+ //_SysDebug("sbrk: (increment=%i)", increment);\r
\r
- if (oldEnd == 0) curEnd = oldEnd = brk(0);\r
+ if (curEnd == 0) {\r
+ oldEnd = curEnd = (size_t)FindHeapBase();\r
+ //_SysAllocate(curEnd); // Allocate the first page\r
+ }\r
\r
- //SysDebug(" sbrk: oldEnd = 0x%x\n", oldEnd);\r
+ //_SysDebug(" sbrk: oldEnd = 0x%x", oldEnd);\r
if (increment == 0) return (void *) curEnd;\r
\r
- newEnd = curEnd + increment;\r
-\r
- if (brk(newEnd) == curEnd) return (void *) -1;\r
oldEnd = curEnd;\r
- curEnd = newEnd;\r
- //SysDebug(" sbrk: newEnd = 0x%x\n", newEnd);\r
\r
+ // Single Page\r
+ if( (curEnd & 0xFFF) && (curEnd & 0xFFF) + increment < 0x1000 )\r
+ {\r
+ //if( curEnd & 0xFFF == 0 )\r
+ //{\r
+ // if( !_SysAllocate(curEnd) )\r
+ // {\r
+ // _SysDebug("sbrk - Error allocating memory");\r
+ // return (void*)-1;\r
+ // }\r
+ //}\r
+ curEnd += increment;\r
+ //_SysDebug("sbrk: RETURN %p (single page, no alloc)", (void *) oldEnd);\r
+ return (void *)oldEnd;\r
+ }\r
+\r
+ increment -= curEnd & 0xFFF;\r
+ curEnd += 0xFFF; curEnd &= ~0xFFF;\r
+ while( increment > 0 )\r
+ {\r
+ if( !_SysAllocate(curEnd) )\r
+ {\r
+ // Error?\r
+ _SysDebug("sbrk - Error allocating memory");\r
+ return (void*)-1;\r
+ }\r
+ increment -= 0x1000;\r
+ curEnd += 0x1000;\r
+ }\r
+\r
+ //_SysDebug("sbrk: RETURN %p", (void *) oldEnd);\r
return (void *) oldEnd;\r
}\r
\r
uint ret = curpos;\r
int delta;\r
\r
- //_SysDebug("brk: (newpos=0x%x)", newpos);\r
+ _SysDebug("brk: (newpos=0x%x)", newpos);\r
\r
// Find initial position\r
if(curpos == 0) curpos = (uint)FindHeapBase();\r
if(newpos < curpos) return newpos;\r
\r
delta = newpos - curpos;\r
- //_SysDebug(" brk: delta = 0x%x", delta);\r
+ _SysDebug(" brk: delta = 0x%x", delta);\r
\r
// Do we need to add pages\r
if(curpos & 0xFFF && (curpos & 0xFFF) + delta < 0x1000)\r
#include <stdio.h>
#include <string.h>
+// Make the scope character ('.') be a symbol, otherwise it's just
+// a ident character
#define USE_SCOPE_CHAR 0
#define DEBUG 0
// Return from a method
case TOK_RWD_RETURN:
- //printf("return\n");
GetToken(Parser);
ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser));
break;
}
/**
- * \brief Get an identifier (constand or function call)
+ * \brief Get an identifier (constant or function call)
*/
tAST_Node *Parse_GetIdent(tParser *Parser)
{
- tAST_Node *ret;
+ tAST_Node *ret = NULL;
char *name;
SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
name = strndup( Parser->TokenStr, Parser->TokenLen );
#if 0
while( GetToken(Parser) == TOK_SCOPE )
{
- ret = AST_New
+ ret = AST_NewScopeDereference( Parser, ret, name );
+ SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
+ name = strndup( Parser->TokenStr, Parser->TokenLen );
}
PutBack(Parser);
#endif
}
}
else {
- // Runtime Constant
+ // Runtime Constant / Variable (When implemented)
#if DEBUG >= 2
printf("Parse_GetIdent: Referencing '%s'\n", name);
#endif