Technology [Programmazione C] Chiamare una funzione da un indirizzo di memoria.

Massi™

Typing Monkey
Ok, ho un piccolo problema.
Per un progetto universitario sto costruendo un sistema operativo per un processore MIPS (o, meglio, una famiglia dei MIPS R2/3000, denominato uMPS -micron MPS-).

Allo stato attuale delle cose, riesco a fargli fare il boot in modo perfetto, alloco la memoria, blabla.. Senza alcun problema. Il problema è invece nello scheduler (sigh) che dev'essere round-robin con timeslice di 5/15ms (a discrezione degli studenti).

Ora. Ogni processo è allocato in memoria in una struttura simile a questa (evito i campi inutili altrimenti vengono 16 pagine di post)

Codice:
typedef struct tcb_t
{
 /* cut */
 state_t pState;
 int priority;
 SEMAPHORE *semAdd;
}

Le altre strutture coinvolte sono:
Codice:
typedef int SEMAPHORE;

typedef struct state_t
{
 /* cut */
 unsigned int pc;
 unsigned int s_reg[];
}

Come si può notare, la struttura tcb_t contiene al suo interno una struttura, che a sua volta contiene tutti i registri del processore.
Quello più interessante è ovviamente pc, che altri non è che l'indirizzo di memoria della funzione del processo che dev'essere eseguita.

Ora, supponendo di avere un codice così (a grandi linee)
Codice:
void
dummyTest()
{
 /* do nothing */
}

int
main()
{
 tcb_t *aProcess;
 aProcess = allocTcb(); /* la funzione si preoccupa da sola di allocarlo nella memoria */
 aProcess->pc = (memaddr) &dummyTest;
 /* blabla */
}

Questo processo viene poi messo in una coda di priorità che viene poi maneggiata dallo scheduler.

Ora.. Come diavolo faccio all'interno dello scheduler, a far eseguire la funzione puntata da pc?
Avevo pensato a qualcosa tipo

Codice:
typedef int (*funcPtr)()

/* poi, dentro lo scheduler */
funcPtr = aProcess->pc;
funcPtr();

Però pare non funzionare..
Ah, chiaramente quello che vedete sopra non è il codice reale, non ho fatto caso ad eventuali puntatori, eccetera.. E' che ho già chiuso l'IDE e non ho voglia di aprirlo.. :asd:

Idee? :sad:
 

Asmoug

Typing Monkey
uhm, puntatori a funzione, grandi rotture di coglioni... non mi ricordo mai la sintassi... comunque c'e' un errore di tipo, cosi' a occhio

mi pare che devi fare una roba tipo

void dummy() { }

int struca_intero(int asd) { return asd+1; }

int main() {
(void)(*funcPtr()) = &dummy;
funcPtr();

(int)(*secondoPtr(int)) = &struca_intero;
secondoPtr(5);

}

comunque e' solo un problema sintattico... google cosa dice? :D
 

Massi™

Typing Monkey
Grande Asmoug.. Il problema era proprio quel typedef, mal consigliato da Google (che sia una convenzione C++?)

Mettendo così
Codice:
/* Scheduler with a round-robin timeslice */
void scheduleTS()
{	
	void (*callFunc)();
	initStatus = getSTATUS();
	resetBuffer();
	printToBuf("Entering main scheduling process");
	while (pCount > 0) {
		resetBuffer();
		causeRegister = getCAUSE();
		if (causeRegister != 0x00000000) {
			/* on which line the interrupt occured? */
			setLines(causeRegister);
			/* if it was the timer interrupt, we reset the timer to 0x0000FFFF
			 * actually, this is not the REAL value, it's just a debug value..
			 * real value will be 0x00000064 (100ms). 
			 */
			if (intLine[2] == 't') {
				printToBuf("Resetting timer");
				*cTimer = 0x0000FFFF;
			}
		}
		
		cProc = removeThreadPQ(&rQueue);
		callFunc = (cProc->procState).pc;
		callFunc();
		sbCount++;
		insertThreadPQ(&rQueue, cProc);
		/* deadlock detection */
		if (pCount > 0 && sbCount == 0)
			PANIC();

		sbCount--;
	}

	return;
}

PARE funzionare. Mi da un warning (su callFunc = blabla.pc) che sistemerò però domani, dato che stavolta l'IDE l'ho chiuso sul serio, ed essendo Eclipse non ho voglia di perdere altri 40 minuti per riaprirlo :asd:

GraFFie ancora :kiss:
 
Alto