+/**
+ * \fn int Proc_SpawnWorker()
+ * \brief Spawns a new worker thread
+ */
+int Proc_SpawnWorker()
+{
+ tThread *new, *cur;
+ Uint eip, esp, ebp;
+
+ cur = Proc_GetCurThread();
+
+ // Create new thread
+ new = malloc( sizeof(tThread) );
+ if(!new) {
+ Warning("Proc_SpawnWorker - Out of heap space!\n");
+ return -1;
+ }
+ memcpy(new, &gThreadZero, sizeof(tThread));
+ // Set Thread ID
+ new->TID = giNextTID++;
+ // Set kernel stack
+ new->KernelStack = MM_NewWorkerStack();
+
+ // Get ESP and EBP based in the new stack
+ __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
+ __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
+ esp = cur->KernelStack - (new->KernelStack - esp);
+ ebp = new->KernelStack - (cur->KernelStack - ebp);
+
+ // Save core machine state
+ new->SavedState.ESP = esp;
+ new->SavedState.EBP = ebp;
+ eip = GetEIP();
+ if(eip == SWITCH_MAGIC) {
+ outb(0x20, 0x20); // ACK Timer and return as child
+ return 0;
+ }
+
+ // Set EIP as parent
+ new->SavedState.EIP = eip;
+
+ return new->TID;
+}
+