2010-12-28 16 views
2

Ich arbeite an einer Hausaufgabe, die im nächsten Semester fällig wird. Es erfordert, dass wir unsere eigene Kontextwechsel-/Thread-Bibliothek mit der ucontext-API implementieren. Der Professor stellt Code zur Verfügung, der es tut, aber bevor ein Thread zurückkehrt, führt er manuell eine Arbeit aus und ruft einen ISR auf, der einen anderen Thread findet, um ihn zu verwenden und Swap-Contexte zu ihm oder, wenn nichts übrig ist, zu beenden.makekontext segfault?

Der Punkt der Zuweisung ist, das Feld uc_link des Kontextes zu verwenden, so dass es bei der Rückkehr die Arbeit erledigt. Ich habe eine Funktion erstellt (geben Sie void/void args ein), die nur die Arbeit erledigt, die die Funktionen vorher getan haben (bereinigen und dann ISR aufrufen). Der Professor sagte, er wolle das.

Alles, was übrig bleibt, ist, einen Makekontext irgendwo auf dem Weg zum Kontext im Feld uc_link zu machen, damit er meinen Thread ausführt, richtig? Nun, wenn ich eine scheinbar beliebige Kombination aus ucontext_t und Funktion mache, bekomme ich einen segfault und gdb bietet keine Hilfe. Ich kann den makekontext überspringen und mein Programm existiert 'normal', wenn es eine Rückkehr in den Threads gibt, die ich erstellt habe (vermutlich) das uc_link-Feld ist nicht richtig eingerichtet (was ich versuche).

Ich kann auch nichts darüber finden, warum Makecontext segfault würde. Kann jemand helfen?

stack2.ss_sp = (void *)(malloc(STACKSIZE)); 
if(stack2.ss_sp == NULL){ 
printf("thread failed to get stack space\n"); 
exit(8); 
} 
stack2.ss_size = STACKSIZE; 
stack2.ss_flags = 0; 

if(getcontext(&main_context) == -1){ 
perror("getcontext in t_init, rtn_env"); 
exit(5); 
} 

//main_context.uc_stack = t_state[i].mystk;                             
main_context.uc_stack = stack2; 
main_context.uc_link = 0; 
makecontext(&main_context, (void (*)(void))thread_rtn, 0); 

ich auch nur thread_rtn versucht haben, & thread_rtn und andere Dinge. thread_rtn wird als void thread_rtn (void) deklariert.

später in jedem Thread. run_env ist vom Typ ucontext_t: ...

t_state[i].run_env.uc_link = &main_context; 
+1

Bitte poste etwas Code, hier oder auf etwas wie pastebin. –

+0

Wie groß ist Ihr STAPELSIZE? – nos

Antwort

0

Es gibt viel los hier, aber ich werde meinen Besten Gedanken geben. Ich versuche auch, die Frage zu beantworten, ohne die Hausaufgaben zu lösen.

In welchem ​​Kontext ist thread_rtn deklariert, und verwendet es nicht statische Variablen?
Der segfault wird wahrscheinlich durch Speicher verursacht, der zugewiesen wurde, aber nicht mehr verfügbar ist (nicht im Kontext oder freigegeben).

Ich kann nicht sagen, ob die main_context ist das gleiche wie der Thread-Kontext, die beiden sollten unterschiedlich sein.

Es sieht so aus, als ob jeder Thread einen eigenen Stack benötigt, der nicht mit dem Stack des Hauptkontexts (oder dem Sam wie jeder Stack eines anderen Threads) übereinstimmen sollte. Überlegen Sie, wo jeder Thread Speicher als Stack verwenden könnte. Unter welchen Bedingungen würde malloc(STACKSIZE)NULL zurückgeben?

Wenn ein Threadkontext zum Hauptkontext hinzugefügt wird, sollte main_context.uc_link inkrementiert werden. Es sieht so aus, als ob main_context.uc_link verfolgt, wie viele Threads mit dem Hauptkontext verknüpft sind. Denken Sie darüber nach, was passiert, wenn die Anzahl abnimmt (ich versuche, etwas Arbeit für den Kurs relevant zu belassen, anstatt zu sagen, was mit einer abnehmenden Zählung zu tun ist). Beachten Sie den speziellen Wert von 0, das bedeutet, dass diesem Hauptkontext keine Threads mehr zugeordnet sind. Gibt es einen Maximalwert für main_context.uc_link?

Hoffe, das hilft.