Ejemplo n.º 1
0
void sleep(int ticks)
{
	if (getCurrentThread() == NULL)
	{
		// not ready to wait!
		uint64_t then = getUptime() + (uint64_t)ticks;
		while (getUptime() < then);
	}
	else
	{
		uint64_t then = getUptime() + (uint64_t)ticks;
		uint64_t nanoThen = then * (uint64_t)1000000;

		cli();
		lockSched();
		TimedEvent ev;
		timedPost(&ev, nanoThen);
		
		while (getNanotime() <= nanoThen)
		{
			waitThread(getCurrentThread());
			unlockSched();
			kyield();
			
			cli();
			lockSched();
		};
		
		timedCancel(&ev);
		unlockSched();
		sti();
	};
};
Ejemplo n.º 2
0
int
OSGLContext::getMaxOpenGLHeight()
{
    static int maxCPUHeight = 0;
    static int maxGPUHeight = 0;
    if (_imp->useGPUContext) {
        if (maxGPUHeight == 0) {
            boost::shared_ptr<OSGLContextAttacher> attacher;
            if (getCurrentThread() != QThread::currentThread()) {
                attacher = OSGLContextAttacher::create(shared_from_this());
                attacher->attach();
            }
            GL_GPU::GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxGPUHeight);
        }
        return maxGPUHeight;
    } else {
#ifdef HAVE_OSMESA
        if (maxCPUHeight == 0) {
            boost::shared_ptr<OSGLContextAttacher> attacher;
            if (getCurrentThread() != QThread::currentThread()) {
                attacher = OSGLContextAttacher::create(shared_from_this());
                attacher->attach();
            }
            GL_CPU::GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxCPUHeight);
            int osmesaMaxHeight = OSGLContext_osmesa::getMaxHeight();
            maxCPUHeight = std::min(maxCPUHeight, osmesaMaxHeight);
        }
#endif
        return maxCPUHeight;
    }
}
Ejemplo n.º 3
0
SysThread::SysThread(Thread *userThread, size_t stackSize, int priority, bool privileged)
{
	LOG(SYS, INFO, "Thread %p created\n", this);
	assert(priority <= Thread::maxPriority);
	this->userThread = userThread;
	group = NULL;
	if (getCurrentThread() != NULL)
		group = getCurrentThread()->group;
	nextInGroup = NULL;
	prevInGroupRef = NULL;
	prev = NULL;
	next = NULL;
	operation = NULL;
	firstLocked = NULL;
	this->stackSize = stackSize;
	if (stackSize == 0) 
		this->stack = NULL;
	else
		this->stack = gcnew(char[stackSize]);
	this->flags = (privileged ? FLAG_PRIVILEGED : 0) | FLAG_SUSPENDED | priority;
	lastGCStackItem = NULL;
	lastGCConstrItem = NULL;
	tmpStackObjRef = NULL;
	memset(&context, 0, sizeof(context));
}
Ejemplo n.º 4
0
static ssize_t pipe_read(File *fp, void *buffer, size_t size)
{
	if (size == 0) return 0;

	Pipe *pipe = (Pipe*) fp->fsdata;
	semWait(&pipe->sem);

	if (pipe->size == 0)
	{
		if (pipe->writecount == 0)
		{
			semSignal(&pipe->sem);
			return 0;
		}
		else if (fp->oflag & O_NONBLOCK)
		{
			semSignal(&pipe->sem);
			getCurrentThread()->therrno = EAGAIN;
			return -1;
		}
		else
		{
			semSignal(&pipe->sem);
			while (1)
			{
				if (getCurrentThread()->sigcnt > 0)
				{
					getCurrentThread()->therrno = EINTR;
					return -1;
				};

				semWait(&pipe->sem);
				if (pipe->size > 0) break;
				semSignal(&pipe->sem);
			};
		};
	};

	if (size > pipe->size) size = pipe->size;

	ssize_t outSize = 0;
	uint8_t *out = (uint8_t*) buffer;
	while (size--)
	{
		*out++ = pipe->buffer[pipe->offRead];
		pipe->offRead = (pipe->offRead + 1) % 1024;
		outSize++;
		pipe->size--;
	};

	semSignal(&pipe->sem);
	return outSize;
};
Ejemplo n.º 5
0
static ssize_t pipe_write(File *fp, const void *buffer, size_t size)
{
	if (size == 0) return 0;

	Pipe *pipe = (Pipe*) fp->fsdata;
	semWait(&pipe->sem);

	if (pipe->readcount == 0)
	{
		semSignal(&pipe->sem);
		return 0;
	};

	if ((pipe->size+size) > 1024)
	{
		if (fp->oflag & O_NONBLOCK)
		{
			semSignal(&pipe->sem);
			getCurrentThread()->therrno = EAGAIN;
			return -1;
		}
		else
		{
			semSignal(&pipe->sem);
			while (1)
			{
				if (getCurrentThread()->sigcnt > 0)
				{
					getCurrentThread()->therrno = EINTR;
					return -1;
				};
				semWait(&pipe->sem);
				if ((pipe->size+size) <= 1024) break;
				semSignal(&pipe->sem);
			};
		};
	};

	ssize_t inSize = 0;
	const uint8_t *in = (const uint8_t*) buffer;
	while (size--)
	{
		pipe->buffer[pipe->offWrite] = *in++;;
		pipe->offWrite = (pipe->offWrite + 1) % 1024;
		inSize++;
		pipe->size++;
	};

	semSignal(&pipe->sem);
	return inSize;
};
Ejemplo n.º 6
0
void kyield()
{
	while (getCurrentThread()->flags & THREAD_WAITING)
	{
		ASM("sti; hlt");
	};

#if 0
	cli();
	uint64_t counter = switchTaskCounter;
	apic->timerInitCount = 0;
	sti();
	
	// at this point, we have 2 possiblities:
	// 1) the APIC timer fired before we turned it off above. in this case, "switchTaskCounter" changed,
	//    and we have already rescheduled, so just return.
	// 2) we turned the APIC timer off before it fired, so "switchTaskCounter" did not change. in this case
	//    we must reprogram it to 1, and we can be sure that we reschedule before this function returns.
	
	if (switchTaskCounter == counter)
	{
		apic->timerInitCount = 2;
		nop();				// make sure it fires before we return by using at least 1 CPU cycle
	};
#endif
};
Ejemplo n.º 7
0
void Thread::setPriority(Priority pr)
{
    if(pr.validate()==false) errorHandler(INVALID_PARAMETERS);
    PauseKernelLock lock;

    Thread *current=getCurrentThread();
    //If thread is locking at least one mutex
    if(current->mutexLocked!=0)
    {   
        //savedPriority always changes, since when all mutexes are unlocked
        //setPriority() must become effective
        if(current->savedPriority==pr) return;
        current->savedPriority=pr;
        //Calculate new priority of thread, which is
        //max(savedPriority, inheritedPriority)
        Mutex *walk=current->mutexLocked;
        while(walk!=0)
        {
            if(walk->waiting.empty()==false)
                pr=std::max(pr,walk->waiting.front()->getPriority());
            walk=walk->next;
        }
    }
    
    //If old priority == desired priority, nothing to do.
    if(pr==current->getPriority()) return;
    Scheduler::PKsetPriority(current,pr);
    #ifdef SCHED_TYPE_EDF
    if(isKernelRunning()) yield(); //Another thread might have a closer deadline
    #endif //SCHED_TYPE_EDF
}
Ejemplo n.º 8
0
int sys_pipe(int *pipefd)
{
	int rfd=-1, wfd=-1;

	FileTable *ftab = getCurrentThread()->ftab;
	spinlockAcquire(&ftab->spinlock);

	int i;
	for (i=0; i<MAX_OPEN_FILES; i++)
	{
		if (ftab->entries[i] == NULL)
		{
			if (rfd == -1)
			{
				rfd = i;
			}
			else if (wfd == -1)
			{
				wfd = i;
				break;
			};
		};
	};

	if ((rfd == -1) || (wfd == -1))
	{
		getCurrentThread()->therrno = EMFILE;
		return -1;
	};

	Pipe *pipe = (Pipe*) kmalloc(sizeof(Pipe));
	semInit(&pipe->sem);
	pipe->readcount = 0;
	pipe->writecount = 0;
	pipe->offRead = 0;
	pipe->offWrite = 0;
	pipe->size = 0;

	ftab->entries[rfd] = openPipe(pipe, O_RDONLY);
	ftab->entries[wfd] = openPipe(pipe, O_WRONLY);

	pipefd[0] = rfd;
	pipefd[1] = wfd;

	spinlockRelease(&ftab->spinlock);
	return 0;
};
Ejemplo n.º 9
0
static ssize_t termWrite(Inode *inode, File *file, const void *buffer, size_t size, off_t pos)
{
	if (getCurrentThread()->creds->pgid != termGroup)
	{
		cli();
		lockSched();
		siginfo_t si;
		si.si_signo = SIGTTOU;
		sendSignal(getCurrentThread(), &si);
		unlockSched();
		sti();
		ERRNO = ENOTTY;
		return -1;
	};

	kputbuf((const char*) buffer, size);
	return size;
};
Ejemplo n.º 10
0
// calculates \sum_K v_i'*A*v_i
double dosum(Matrix A, Matrix v)
{
  double alpha=0.0;
  Matrix temp;
  int i, t;

  t = getMaxThreads();

  temp = createMatrix(A->rows, t);
#pragma omp parallel for schedule(static) reduction(+:alpha)
  for(i=0;i<v->cols;++i) {
    MxV(temp->col[getCurrentThread()],A,v->col[i], 1.0, 0.0, 'N');
    alpha += dotproduct(temp->col[getCurrentThread()],v->col[i]);
  }
  freeMatrix(temp);

  return alpha;
}
Ejemplo n.º 11
0
void ghsInitExceptions()
{
   if (p__cpp_exception_init_ptr->getAddress()) {
      auto thread = getCurrentThread();

      // Invoke the exception initializer
      (*p__cpp_exception_init_ptr)(&thread->_ghs__eh_globals);
   }
}
Ejemplo n.º 12
0
void timedPost(TimedEvent *ev, uint64_t nanotime)
{
	ev->nanotime = nanotime;
	ev->thread = getCurrentThread();

	if (nanotime == 0)
	{
		ev->prev = ev->next = NULL;
		return;
	};
	
	if (timedEvents == NULL)
	{
		ev->prev = ev->next = NULL;
		timedEvents = ev;
	}
	else
	{
		if (nanotime <= timedEvents->nanotime)
		{
			//ev->prev = timedEvents;
			//ev->next = timedEvents->next;
			//timedEvents = ev;
			timedEvents->prev = ev;
			ev->prev = NULL;
			ev->next = timedEvents;
			timedEvents = ev;
			return;
		};
		
		TimedEvent *scan = timedEvents;
		while (1)
		{
			if (scan->next == NULL)
			{
				ev->prev = scan;
				ev->next = NULL;
				scan->next = ev;
				return;
			}
			else
			{
				if ((scan->nanotime <= nanotime) && (scan->next->nanotime >= nanotime))
				{
					ev->next = scan->next;
					ev->prev = scan;
					scan->next->prev = ev;
					scan->next = ev;
					return;
				};
				
				scan = scan->next;
			};
		};
	};
};
Ejemplo n.º 13
0
int MprThreadService::getCurrentThreadId()
{
	MprThread	*tp;

	tp = getCurrentThread();
	if (tp) {
		return tp->getId();
	}
	return -1;
}
Ejemplo n.º 14
0
/**
 * 実行中スレッドの処理待ち
 * @param target int:時間待ち(ms), string:トリガ待ち, obj:オブジェクト待ち
 * @param timeout タイムアウト(省略時は無限に待つ)
 * @return 待ちがキャンセルされたら true
 */
SQRESULT
Thread::global_wait(HSQUIRRELVM v)
{
	Thread *th = getCurrentThread(v);
	if (!th) {
		return ERROR_NOTHREAD(v);
	}
	th->_wait(v);
	return sq_suspendvm(v);
}
Ejemplo n.º 15
0
pid_t sysWaitPid(pid_t filter, void *waitStatus, int options) {
	//check if any of the current children that match the filter are status=PROCSTATE_FINISHED 
	//if so return
	pid_t ret = 0;
	bool exist = false;
	thread_t curThread = getCurrentThread();
	struct Process *proc = curThread->process;

	acquireSpinlock(&curThread->lock); //lock curThread early to prevent child exit during execution of this function
	acquireSpinlock(&proc->lock);
	struct Process *child = proc->children;
	while (child) {
		acquireSpinlock(&child->lock);
		if (checkFilter(filter, child)) {
			exist = true;
			if (child->state == PROCSTATE_FINISHED) {
				releaseSpinlock(&child->lock);
				ret = child->pid;
				break;
			}
		}
		struct Process *next = child->nextChild;
		releaseSpinlock(&child->lock);
		child = next;
	}
	releaseSpinlock(&proc->lock);
	if (ret > 0) {
		if (waitStatus) {
			//*waitStatus = child->exitValue; //TODO expand this when signals get added
			memcpy(waitStatus, &proc->exitInfo, sizeof(proc->exitInfo));
		}
		removeProcess(child);
		releaseSpinlock(&curThread->lock);
		return ret;
	}
	if (!exist) {
		releaseSpinlock(&curThread->lock);
		return -ECHILD; //child does not exist
	}
	
	//save filter
	//Wait for children to exit
	
	curThread->state = THREADSTATE_PIDWAIT;
	curThread->waitPid = filter;
	kthreadStop();

	if (waitStatus) {
		//*waitStatus = curThread->waitProc->exitValue;
		memcpy(waitStatus, &proc->exitInfo, sizeof(proc->exitInfo));
	}
	removeProcess(curThread->waitProc);

	return curThread->waitPid;
}
Ejemplo n.º 16
0
void ghsCleanupExceptions()
{
   if (p__cpp_exception_cleanup_ptr->getAddress()) {
      auto thread = getCurrentThread();

      if (thread->_ghs__eh_globals.getAddress()) {
         (*p__cpp_exception_cleanup_ptr)(&thread->_ghs__eh_globals);
         thread->_ghs__eh_globals = nullptr;
      }
   }
}
Ejemplo n.º 17
0
static ssize_t termRead(Inode *inode, File *fp, void *buffer, size_t size, off_t pos)
{
	if (getCurrentThread()->creds->pgid != termGroup)
	{
		cli();
		lockSched();
		siginfo_t si;
		si.si_signo = SIGTTIN;
		sendSignal(getCurrentThread(), &si);
		unlockSched();
		sti();
		ERRNO = ENOTTY;
		return -1;
	};
	
	int count = semWaitGen(&semCount, (int) size, SEM_W_INTR, 0);
	if (count < 0)
	{
		ERRNO = -count;
		return -1;
	};

	semWait(&semInput);

	if (size > (size_t) count) size = (size_t) count;
	ssize_t out = 0;
	while (size > 0)
	{
		if (inputRead == INPUT_BUFFER_SIZE) inputRead = 0;
		size_t max = INPUT_BUFFER_SIZE - inputRead;
		if (max > size) max = size;
		memcpy(buffer, &inputBuffer[inputRead], max);
		size -= max;
		out += max;
		inputRead += max;
		buffer = (void*)((uint64_t)buffer + max);
	};
	semSignal(&semInput);
	return out;
};
Ejemplo n.º 18
0
/**
 * スクリプトを切り替える
 * @param func スレッドで実行するファンクション
 */
SQRESULT
Thread::global_exec(HSQUIRRELVM v)
{
	Thread *th = getCurrentThread(v);
	if (!th) {
		return ERROR_NOTHREAD(v);
	}
	if (sq_gettop(v) <= 1) {
		return ERROR_INVALIDPARAM(v);
	}
	th->_exec(v);
	return sq_suspendvm(v);
}
Ejemplo n.º 19
0
/* suspend the thread */
bool Thread::suspendCallerUntil(const TTime reactivationTime, void* signaler) {

    Thread* caller =  getCurrentThread();
    PRIORITY_CEILING {
        caller->waitingFor = signaler;
        caller->suspendedUntil = reactivationTime;
    }
    yield();

    caller->waitingFor = 0;
    /** after yield: It was resumed (suspendedUntil set to 0) or time was reached ?*/
    if(caller->suspendedUntil == 0) return true; // it was resumed!
    return false; // time was reached
}
Ejemplo n.º 20
0
/**
 * コマンド実行
 * @param func スレッドで実行するファンクション
 * @return 終了コード
 */
SQRESULT
Thread::global_system(HSQUIRRELVM v)
{
	Thread *th = getCurrentThread(v);
	if (!th) {
		return ERROR_NOTHREAD(v);
	}
	if (!_fork(v)) {
		return ERROR_FORK(v);
	}
	th->_system(v);
	sq_pop(v,1);
	return sq_suspendvm(v);
}
Ejemplo n.º 21
0
static void spawnProc(void *stack)
{
	kprintf("%$\x02" "Done%#\n");

	initInterp();

	kprintf("Allocating memory for bootstrap... ");
	FrameList *fl = palloc(2);
	AddSegment(getCurrentThread()->pm, 1, fl, PROT_READ | PROT_WRITE | PROT_EXEC);
	pdownref(fl);
	SetProcessMemory(getCurrentThread()->pm);
	kprintf("%$\x02" "Done%#\n");

	kprintf("Setting up the terminal... ");
	setupTerminal(getCurrentThread()->ftab);
	kprintf("%$\x02" "Done%#\n");

	kprintf("Loading /initrd/usbs... ");
	int err;
	File *file = vfsOpen("/initrd/usbs", VFS_CHECK_ACCESS, &err);
	if (file == NULL)
	{
		kprintf("%$\x04" "Failed%#\n");
		panic("failed to open /initrd/usbs");
	};
	ssize_t count = vfsRead(file, (void*) 0x1000, 0x1000);
	if (count < 1)
	{
		kprintf("%$\x04" "Failed%#\n");
		panic("read() /initrd/usbs: %d\n", count);
	};
	vfsClose(file);
	kprintf("%$\x02" "%d bytes%#\n", count);

	kprintf("Control will be transferred to usbs now.\n");
	_jmp_usbs(stack);
};
Ejemplo n.º 22
0
//exit info already set in process
void signalExit(void) {
	thread_t curThread = getCurrentThread();
	if (curThread->process->pid == 1) {
		panic("\n[PANIC] Attempted to kill init!");
	}
	//kill all other threads
	//set current thread as mainThread
	
	threadQueueRemove(curThread);
	exitProcess(curThread->process);

	//exit thread
	curThread->detached = true;
	kthreadExit(NULL);
}
Ejemplo n.º 23
0
/** pause execution of this thread and call scheduler */
void Thread::yield() {
    if(!isSchedulingEnabled) return; // I really do not like This! but required

    /** Optimisation: Avoid unnecesary context swtichs: see Scheduler::schedule()  ***/
    long long timeNow = NOW(); 
    Thread* preselection = findNextToRun(timeNow); 
    if(preselection == getCurrentThread()) return;

    // schedule is required, The scheduler shall not repeate my computations: 
    Scheduler::preSelectedNextToRun = preselection; 
    Scheduler::preSelectedTime = timeNow;

    /* reschedule next timer interrupt to avoid interruptions of while switching */
    Timer::stop();
    __asmSaveContextAndCallScheduler();
}
Ejemplo n.º 24
0
static jvmtiError
GetLocal_checkArgs(jvmtiEnv* env,
                        jthread *thread,
                        jint depth,
                        jint UNREF slot,
                        void* value_ptr)
{
    jint state;
    jvmtiError err;

    // TODO: check error condition: JVMTI_ERROR_MUST_POSSESS_CAPABILITY

    if (*thread == 0) {
        *thread = getCurrentThread();
    }

    // check error condition: JVMTI_ERROR_INVALID_THREAD
    err = jvmtiGetThreadState(env, *thread, &state);

    if (err != JVMTI_ERROR_NONE) {
        return err;
    }

    // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE
    if ((state & JVMTI_THREAD_STATE_ALIVE) == 0) {
        return JVMTI_ERROR_THREAD_NOT_ALIVE;
    }

    // check error condition: JVMTI_ERROR_ILLEGAL_ARGUMENT
    if (depth < 0) {
        return JVMTI_ERROR_ILLEGAL_ARGUMENT;
    }

    // check error condition: JVMTI_ERROR_NULL_POINTER
    if (value_ptr == 0) {
        return JVMTI_ERROR_NULL_POINTER;
    }

    return JVMTI_ERROR_NONE;
}
Ejemplo n.º 25
0
static UINT32 onPowerButton(void *ignore)
{
	(void)ignore;
	Thread *thread = getCurrentThread();
	while (thread->pid != 1)
	{
		thread = thread->next;
	};
	
	siginfo_t info;
	info.si_signo = SIGHUP;
	info.si_code = 0;
	info.si_errno = 0;
	info.si_pid = 0;
	info.si_uid = 0;
	info.si_addr = NULL;
	info.si_status = 0;
	info.si_band = 0;
	info.si_value.sival_int = 0;
	sendSignal(thread, &info);
	return 0;
};
Ejemplo n.º 26
0
int sysArchPrctl(int which, void *addr) {
	int error = 0;
	uintptr_t uaddr = (uintptr_t)addr;

	if (uaddr & (0xFFFF8000UL << 32)) {
		return -EINVAL;
	}
	thread_t thread = getCurrentThread();
	switch (which) {
		case PRCTL_FS:
			thread->fsBase = addr;
			wrmsr(0xC0000100, uaddr);
			break;
		case PRCTL_GS:
			thread->gsBase = addr;
			wrmsr(0xC0000102, uaddr);
			break;
		default:
			error = -EINVAL;
			break;
	}

	return error;
}
Ejemplo n.º 27
0
int elfExec(Regs *regs, const char *path, const char *pars, size_t parsz)
{
	//getCurrentThread()->therrno = ENOEXEC;

	vfsLockCreation();
	struct stat st;
	int error = vfsStat(path, &st);
	if (error != 0)
	{
		vfsUnlockCreation();
		return sysOpenErrno(error);
	};

	if (!vfsCanCurrentThread(&st, 1))
	{
		vfsUnlockCreation();
		getCurrentThread()->therrno = EPERM;
		return -1;
	};

	File *fp = vfsOpen(path, VFS_CHECK_ACCESS, &error);
	if (fp == NULL)
	{
		vfsUnlockCreation();
		return sysOpenErrno(error);
	};
	vfsUnlockCreation();

	if (fp->seek == NULL)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = EIO;
		return -1;
	};

	if (fp->dup == NULL)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = EIO;
		return -1;
	};

	Elf64_Ehdr elfHeader;
	if (vfsRead(fp, &elfHeader, sizeof(Elf64_Ehdr)) < sizeof(Elf64_Ehdr))
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	if (memcmp(elfHeader.e_ident, "\x7f" "ELF", 4) != 0)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	if (elfHeader.e_ident[EI_CLASS] != ELFCLASS64)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	if (elfHeader.e_ident[EI_DATA] != ELFDATA2LSB)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	if (elfHeader.e_ident[EI_VERSION] != 1)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	if (elfHeader.e_type != ET_EXEC)
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	if (elfHeader.e_phentsize < sizeof(Elf64_Phdr))
	{
		vfsClose(fp);
		getCurrentThread()->therrno = ENOEXEC;
		return -1;
	};

	ProgramSegment *segments = (ProgramSegment*) kmalloc(sizeof(ProgramSegment)*(elfHeader.e_phnum));
	memset(segments, 0, sizeof(ProgramSegment) * elfHeader.e_phnum);

	int interpNeeded = 0;
	Elf64_Dyn *dynamic;

	unsigned int i;
	for (i=0; i<elfHeader.e_phnum; i++)
	{
		fp->seek(fp, elfHeader.e_phoff + i * elfHeader.e_phentsize, SEEK_SET);
		Elf64_Phdr proghead;
		if (vfsRead(fp, &proghead, sizeof(Elf64_Phdr)) < sizeof(Elf64_Phdr))
		{
			kfree(segments);
			getCurrentThread()->therrno = ENOEXEC;
			return -1;
		};

		if (proghead.p_type == PT_PHDR)
		{
			continue;
		}
		else if (proghead.p_type == PT_NULL)
		{
			continue;
		}
		else if (proghead.p_type == PT_LOAD)
		{
			if (proghead.p_vaddr < 0x1000)
			{
				vfsClose(fp);
				kfree(segments);
				getCurrentThread()->therrno = ENOEXEC;
				return -1;
			};

			if ((proghead.p_vaddr+proghead.p_memsz) > 0x8000000000)
			{
				vfsClose(fp);
				kfree(segments);
				return -1;
			};

			uint64_t start = proghead.p_vaddr;
			segments[i].index = (start)/0x1000;

			uint64_t end = proghead.p_vaddr + proghead.p_memsz;
			uint64_t size = end - start;
			uint64_t numPages = ((start + size) / 0x1000) - segments[i].index + 1; 
			//if (size % 0x1000) numPages++;

			segments[i].count = (int) numPages;
			segments[i].fileOffset = proghead.p_offset;
			segments[i].memorySize = proghead.p_memsz;
			segments[i].fileSize = proghead.p_filesz;
			segments[i].loadAddr = proghead.p_vaddr;
			segments[i].flags = 0;

			if (proghead.p_flags & PF_R)
			{
				segments[i].flags |= PROT_READ;
			};

			if (proghead.p_flags & PF_W)
			{
				segments[i].flags |= PROT_WRITE;
			};

			if (proghead.p_flags & PF_X)
			{
				segments[i].flags |= PROT_EXEC;
			};
		}
		else if (proghead.p_type == PT_INTERP)
		{
			interpNeeded = 1;
		}
		else if (proghead.p_type == PT_DYNAMIC)
		{
			dynamic = (Elf64_Dyn*) proghead.p_vaddr;
		}
		else
		{
			kfree(segments);
			getCurrentThread()->therrno = ENOEXEC;
			return -1;
		};
	};

	// set the signal handler to default.
	getCurrentThread()->rootSigHandler = 0;

	// thread name
	strcpy(getCurrentThread()->name, path);

	// set the execPars
	Thread *thread = getCurrentThread();
	if (thread->execPars != NULL) kfree(thread->execPars);
	thread->execPars = (char*) kmalloc(parsz);
	thread->szExecPars = parsz;
	memcpy(thread->execPars, pars, parsz);

	// create a new address space
	ProcMem *pm = CreateProcessMemory();

	// switch the address space, so that AddSegment() can optimize mapping
	lockSched();
	ProcMem *oldPM = thread->pm;
	thread->pm = pm;
	unlockSched();
	SetProcessMemory(pm);
	DownrefProcessMemory(oldPM);

	// pass 1: allocate the frames and map them
	for (i=0; i<(elfHeader.e_phnum); i++)
	{
		if (segments[i].count > 0)
		{
			FrameList *fl = palloc_later(segments[i].count, segments[i].fileOffset, segments[i].fileSize);
			if (AddSegment(pm, segments[i].index, fl, segments[i].flags) != 0)
			{
				getCurrentThread()->therrno = ENOEXEC;
				pdownref(fl);
				DownrefProcessMemory(pm);
				break;
			};
			pdownref(fl);
		};
	};

	// change the fpexec
	if (thread->fpexec != NULL)
	{
		if (thread->fpexec->close != NULL) thread->fpexec->close(thread->fpexec);
		kfree(thread->fpexec);
	};
	thread->fpexec = fp;

	// make sure we jump to the entry upon return
	regs->rip = elfHeader.e_entry;

	// the errnoptr is now invalid
	thread->errnoptr = NULL;

	// close all files marked with O_CLOEXEC (on glidx a.k.a. FD_CLOEXEC)
	spinlockAcquire(&getCurrentThread()->ftab->spinlock);
	for (i=0; i<MAX_OPEN_FILES; i++)
	{
		File *fp = getCurrentThread()->ftab->entries[i];
		if (fp != NULL)
		{
			if (fp->oflag & O_CLOEXEC)
			{
				getCurrentThread()->ftab->entries[i] = NULL;
				vfsClose(fp);
			};
		};
	};
	spinlockRelease(&getCurrentThread()->ftab->spinlock);
	
	// suid/sgid stuff
	if (st.st_mode & VFS_MODE_SETUID)
	{
		thread->euid = st.st_uid;
		//thread->ruid = st.st_uid;
		//thread->suid = st.st_uid;
		thread->flags |= THREAD_REBEL;
	};

	if (st.st_mode & VFS_MODE_SETGID)
	{
		thread->egid = st.st_gid;
		//thread->rgid = st.st_gid;
		//thread->sgid = st.st_gid;
		thread->flags |= THREAD_REBEL;
	};

	if (interpNeeded)
	{
		linkInterp(regs, dynamic, pm);
	};

	return 0;
};
Ejemplo n.º 28
0
int pollThread(Regs *regs, int pid, int *stat_loc, int flags)
{
	if (kernelStatus != KERNEL_RUNNING)
	{
		currentThread->therrno = EPERM;
		return -1;
	};

	int sigcnt = getCurrentThread()->sigcnt;

	lockSched();
	ASM("cli");
	Thread *threadToKill = NULL;
	Thread *thread = currentThread->next;
	while (thread != currentThread)
	{
		if (thread->pidParent == currentThread->pid)
		{
			if ((thread->pid == pid) || (pid == -1))
			{
				if (thread->flags & THREAD_TERMINATED)
				{
					threadToKill = thread;
					*stat_loc = thread->status;

					// unlink from the runqueue
					thread->prev->next = thread->next;
					thread->next->prev = thread->prev;

					break;
				};
			};
		};
		thread = thread->next;
	};

	// when WNOHANG is clear
	while ((threadToKill == NULL) && ((flags & WNOHANG) == 0))
	{
		//currentThread->flags |= THREAD_WAITING;
		//currentThread->therrno = ECHILD;
		//*((int*)&regs->rax) = -1;
		//switchTask(regs);
		getCurrentThread()->flags |= THREAD_WAITING;
		unlockSched();
		kyield();
		if (getCurrentThread()->sigcnt > sigcnt)
		{
			ERRNO = EINTR;
			return -1;
		};
		lockSched();
	};

	unlockSched();
	ASM("sti");

	// when WNOHANG is set
	if (threadToKill == NULL)
	{
		currentThread->therrno = ECHILD;
		return -1;
	};

	// there is a process ready to be deleted, it's already removed from the runqueue.
	kfree(thread->stack);
	DownrefProcessMemory(thread->pm);
	ftabDownref(thread->ftab);

	if (thread->fpexec != NULL)
	{
		if (thread->fpexec->close != NULL) thread->fpexec->close(thread->fpexec);
		kfree(thread->fpexec);
	};

	if (thread->execPars != NULL) kfree(thread->execPars);
	int ret = thread->pid;
	kfree(thread);

	return ret;
};
Ejemplo n.º 29
0
void joinThreadGroup(SysThreadGroup *group)
{
	getCurrentThread()->joinGroup(group);
}
Ejemplo n.º 30
0
int termIoctl(Inode *inode, File *fp, uint64_t cmd, void *argp)
{
	Thread *target = NULL;
	Thread *scan;
	int pgid;
	struct termios *tc = (struct termios*) argp;
	TermWinSize *winsz = (TermWinSize*) argp;
	
	switch (cmd)
	{
	case IOCTL_TTY_GETATTR:
		memcpy(tc, &termState, sizeof(struct termios));
		return 0;
	case IOCTL_TTY_SETATTR:
		termState.c_iflag = tc->c_iflag;
		termState.c_oflag = tc->c_oflag;
		termState.c_cflag = tc->c_cflag;
		termState.c_lflag = tc->c_lflag;
		return 0;
	case IOCTL_TTY_GETPGID:
		*((int*)argp) = termGroup;
		return 0;
	case IOCTL_TTY_SETPGID:
		if (getCurrentThread()->creds->sid != 1)
		{
			ERRNO = ENOTTY;
			return -1;
		};
		pgid = *((int*)argp);
		cli();
		lockSched();
		scan = getCurrentThread();
		do
		{
			if (scan->creds != NULL)
			{
				if (scan->creds->pgid == pgid)
				{
					target = scan;
					break;
				};
			};
			
			scan = scan->next;
		} while (scan != getCurrentThread());
		if (target == NULL)
		{
			unlockSched();
			sti();
			ERRNO = EPERM;
			return -1;
		};
		if (target->creds->sid != 1)
		{
			unlockSched();
			sti();
			ERRNO = EPERM;
			return -1;
		};
		unlockSched();
		sti();
		termGroup = pgid;
		return 0;
	case IOCTL_TTY_ISATTY:
		return 0;
	case IOCTL_TTY_GETSIZE:
		getConsoleSize(&winsz->ws_col, &winsz->ws_row);
		winsz->ws_xpixel = 0;
		winsz->ws_ypixel = 0;
		return 0;
	default:
		ERRNO = ENODEV;
		return -1;
	};
};