示例#1
0
CVector* divideFam(CVector *wordVec, int wordLength, char ch, int *max_index)
{
    int n = 1;
    for (int i = 0; i < wordLength; i++) {
        n += n;
    }
    CVector **fam = malloc(n * sizeof(CVector*));
    for (int i = 0; i < n; i++) {
        fam[i] = NULL;
    }
    int *arr = calloc(n, sizeof(int));
    int index = 0;
    for (void *cur = cvec_first(wordVec); cur != NULL; cur = cvec_next(wordVec, cur)) {
        char *word = (char*)cur;
        int check = 0;
        for (int i = wordLength -1; i >= 0; i--) {
            if (word[i] == ch) {
                if(check != 0) {
                    // means the character appears more than once.
                    // remove it from the current family
                    cvec_remove(fam[check], cvec_count(fam[check]) - 1);
                    arr[check]--;
                    check = check | (1 << (wordLength -i - 1));
                }
                check = check | (1 << (wordLength -i - 1));
                appendElem(fam, check, wordLength, arr, word);
            }
        }
        
        if (check == 0) {
            appendElem(fam, check, wordLength, arr, word);
        }
    }
    *max_index = getMaxIndex(arr, n);
    free(arr);
    return fam[*max_index];
}
示例#2
0
int doSchedule(int *spsr, volatile unsigned int *sp[], q_elem **next, int timedSchedule)
{
	#if DEBUG_SCHEDULE
	kprintf("do Schedule timed=%d forcere=%d forceup=%d\r\n", timedSchedule, force_reschedule, force_updateRegs);
	#endif
	int returnValue = 0;

	if(!timedSchedule && !force_reschedule)
	{
		(*next) = thread.current;
		return returnValue;
	}

	if(current_wants_to_be_destroyed)
	{
		q_elem *tmp = thread.current;

		thread.thread_count--;
		thread.threads_ready--;
		threadsPerPidCount[tmp->tcb.pid]--;

		// free stack
		unsigned int stackMap = getMapping(tmp->tcb.pid, 0xB+tmp->id)-0xA;
		free_0_63&=(~(1<<stackMap));
		minvalidate(tmp->tcb.pid, 0xB+tmp->id);

		// free data if all threads of a process died
		if(threadsPerPidCount[tmp->tcb.pid]<=0)
		{
			unsigned int dataMap = getMapping(tmp->tcb.pid, 0xA)-0xA;
			free_0_63&=(~(1<<dataMap));
			minvalidate(tmp->tcb.pid, 0xA);
		}

		thread.current = nextThread();

		queueOut(tmp, &thread.head);
		appendElem(tmp, &thread.free_elems);

		force_updateRegs = 1;
		current_wants_to_be_destroyed = 0;
	}
	
	if(!force_updateRegs)
	{
		saveCurrentThread(*sp, *spsr);
		(*next) = nextThread();
	}
	else
	{
		(*next) = thread.current;
	}

	#if DEBUG
	kprintf("waiting: ");
	printListPrev(thread.waiting);
	kprintf("\r\n");
	kprintf("queue: ");
	printListPrev(thread.head);
	kprintf("\r\n");
	kprintf("next %d\r\n", (*next)->id);
	#endif

	if(force_reschedule)
		force_reschedule=0;

	updateTimer(next, timedSchedule);

	#if DEBUG
	kprintf("TIMER NEXT\r\n");
	kprintf("waiting: ");
	printListPrev(thread.waiting);
	kprintf("\r\n");
	kprintf("queue: ");
	printListPrev(thread.head);
	kprintf("\r\n");
	kprintf("next %d\r\n", (*next)->id);
	#endif

	#if DEBUG_THREAD_REGS
	kprintf("next PC %x before THREAD REGS\r\n",(*next)->tcb.regs[15]);
	#endif

	switch(updateThreadRegs((*next),sp))
	{
		// didn't do the context switch, so update LR
		case 1:
			returnValue = 1;
		break;
		case -1:
			kprintf("ERROR no next Thread, something went wrong\r\n");
			while(1);
		break;

	}
	

	return returnValue;
}
示例#3
0
// init new thread and append at the beginning of the queue
int createThread(void (*startFun)(void* args, int len), void *args, int len, int prio, int newProcess)
{
	if(thread.free_elems)
	{
		q_elem *newfree = thread.free_elems;
		thread.free_elems = thread.free_elems->next;
		thread.free_elems->prev = 0;
		newfree->next = thread.head;

		// if we're not adding the idle thread and prio is 
		// less than zero throw error
		if(thread.thread_count>0 && prio<=0)
		{
			return -2;
		}
		else
		{
			newfree->priority = prio;
		}

		appendElem(newfree, &thread.head);

		// we're going to copy args to begining of thread stack
		int argbuffer[32]; // if it is a new thread we need to copy data into kernel 
				   // space so we can copy it to the new thread
		if(newProcess)
		{
			len = len>32?32:len; // no buffer overflow ;)
			int i;
			for(i=0;i<len;i++)
			{
				argbuffer[i] = ((int *) args)[i];
			}
			args=argbuffer;
			unsigned int newpid;
			for(newpid=0;threadsPerPidCount[newpid] && newpid<MAX_PIDS;newpid++);
			if(newpid==MAX_PIDS)
				return -1;
			int newMemAdr = nextFreeBlock();
			if(newMemAdr==-1)
				return -1;
			newMemAdr+=0xA;
			mmap(newpid, 0xA, newMemAdr, mmu_readwrite); // data segment - just one per process
			newfree->tcb.pid = newpid;
			set_ttbr0(get_mmu(newpid)); // load new table
			tlbiall(); // flush tlb
		}
		else
		{
			newfree->tcb.pid = thread.current->tcb.pid;
		}

		threadsPerPidCount[newfree->tcb.pid]++;

		int newMemAdr = nextFreeBlock();
		if(newMemAdr==-1)
			return -1;
		newMemAdr+=0xA;
		mmap(newfree->tcb.pid, 0xB+newfree->id, newMemAdr, mmu_readwrite); // stack one for each thread
		newfree->tcb.regs[0] = 0xBffffc + (newfree->id<<20) - (len<<2);

		newfree->tcb.regs[1] = len;
		// SP = USR BASE + Thread Count Offset 64k - args (copied to stack)
		newfree->tcb.regs[13] = newfree->tcb.regs[0]; // sp
		newfree->tcb.regs[14] = (int) &exitThread; // lr 
		//printf("set LR to: %x\r\n", thread.head->tcb.regs[14]);
		newfree->tcb.regs[15] = (int) startFun; // pc
		// init cpsr, user mode enable IRQs, no thumb no FIQ
		newfree->tcb.cpsr = 0b1010000;
		// copy args to stack
		int i;
		int curAddr = newfree->tcb.regs[13];
		for(i=0;i<len;i++)
		{
			int arg = ((int *) args)[i];
			write_u32(curAddr,arg);
			curAddr+=4;
		}
		thread.thread_count++;
		thread.threads_ready++;

		if(newProcess && thread.current)
		{
			set_ttbr0(get_mmu(thread.current->tcb.pid)); // load current table
			tlbiall(); // flush tlb
		}

		// if there was currently just the idle Thread read 
		// and we got a new one -> force reschedule!
		if(thread.threads_ready==2)
		{
		//	setTimer(0);
		        #if DEBUG
		        kprintf("create force \r\n");
		        #endif
			force_reschedule=1;
		}
		return 1;
	}
	else
		return -1;
}
示例#4
0
void threadIntoWait(int spsr, volatile unsigned int sp[], enum thread_status status)
{
	#if DEBUG
	kprintf("thread into wait\r\n");
	#endif
	// if we're able to put a char into the output Buffer
	// the thread doesn't need to wait
	if(status==thread_waiting_putChr)
	{
		#if DEBUG
		kprintf("try to put char %c\r\n", (char) sp[2]);
		#endif
		if(putChar(sp[2]))
		{
			#if DEBUG
			kprintf("putted char\r\n");
			#endif
			return;
		}
	}
	if(status==thread_waiting_getChr)
	{
		#if DEBUG
		kprintf("try to put char %c\r\n", (char) sp[2]);
		#endif
		char chr = getChar();
		if(chr)
		{
			sp[2] = getChar();
			#if DEBUG
			kprintf("putted char\r\n");
			#endif
			return;
		}
	}


	saveCurrentThread(sp, spsr);
	thread.current->tcb.status = status;

	if(status==thread_waiting_time)
	{
		thread.current->tcb.waitTime = thread.current->tcb.regs[0];
		#if DEBUG
		kprintf("put thread %d into waiting for %dns\r\n",thread.current->id ,thread.current->tcb.waitTime);
		#endif
	}


	q_elem *tmp = thread.current;
	thread.threads_ready--;
	thread.current = nextThread();

	#if DEBUG
	kprintf(" new current %d \r\n", thread.current->id);
	#endif

	queueOut(tmp, &thread.head);
	appendElem(tmp, &thread.waiting);

	force_reschedule = 1;
	force_updateRegs = 1;
}