2010-12-28 4 views
2

Je travaille sur un devoir qui sera dû au prochain semestre. Cela nous oblige à implémenter notre propre bibliothèque de changement de contexte/thread en utilisant l'API ucontext. Le professeur fournit le code qui le fait, mais avant qu'un thread ne retourne, il fait manuellement un travail et appelle un ISR qui trouve un autre thread à utiliser et swapcontexts ou, s'il n'en reste aucun, se termine.makecontext segfault?

Le point de l'affectation est d'utiliser le champ uc_link du contexte afin que, lorsqu'il renvoie un résultat, il se charge du travail. J'ai créé une fonction (type void/void args) qui fait juste le travail que les fonctions ont fait avant (nettoyer et appelle ensuite ISR). Le professeur a dit qu'il voulait ça.

Il ne reste donc plus qu'à faire un makecontext quelque part sur le contexte dans le champ uc_link pour qu'il exécute mon thread, n'est-ce pas? Eh bien, quand je fais makecontext sur apparemment n'importe quelle combinaison de ucontext_t et de fonction, je reçois un segfault et gdb ne fournit aucune aide .. Je peux passer le makecontext et mon programme existe «normalement» quand il rentre dans les threads que j'ai créés parce que (vraisemblablement) le champ uc_link n'est pas correctement configuré (ce que j'essaie de faire).

Je ne trouve rien sur les raisons pour lesquelles makecontext segfault. Quelqu'un peut-il aider?

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); 

J'ai aussi essayé juste thread_rtn, & thread_rtn et d'autres choses. thread_rtn est déclaré comme void thread_rtn (void).

plus tard, dans chaque thread. run_env est de type ucontext_t: ...

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

Veuillez poster du code, ici ou sur quelque chose comme pastebin. –

+0

Quelle est la taille de votre STACKSIZE? – nos

Répondre

0

Il y a beaucoup de choses ici, mais je vais donner mes meilleures pensées. J'essaie aussi de répondre à la question sans résoudre les devoirs.

Dans quel contexte thread_rtn est-il déclaré et utilise-t-il des variables non statiques?
Le segfault est probablement causé par la mémoire allouée mais n'est plus disponible (hors contexte ou libéré).

Je ne peux pas dire si le main_context est le même que le contexte de fil, les deux devraient être différents.

Il semble que chaque thread ait besoin de sa propre pile, ce qui ne devrait pas être la même que la pile du contexte principal (ou le sam comme n'importe quelle autre pile de threads). Pensez à l'endroit où chaque thread pourrait avoir de la mémoire à utiliser comme une pile. Dans quelles conditions malloc(STACKSIZE) renverra NULL?

Lorsqu'un contexte de thread est ajouté au contexte principal, main_context.uc_link doit être incrémenté. Il semble que main_context.uc_link garde une trace du nombre de threads liés au contexte principal. Pensez à ce qui se passe lorsque le compte diminue (j'essaie de laisser un peu de pertinence au cours plutôt que de dire quoi faire au sujet d'un nombre décroissant). Notez la valeur spéciale de 0, ce qui signifie qu'il n'y a plus de threads associés à ce contexte principal. Y a-t-il une valeur maximale pour main_context.uc_link?

Espérons que cela aide.