2

J'écris un garbage collector semi-précis, et je me demande s'il existe un moyen de détecter avec précision les limites de la pile allouée par le système pour un thread donné. J'ai besoin de ceci pour que je puisse balayer la pile à la recherche de racines (pointeurs), et mon approche actuelle consiste à enregistrer le pointeur de pile lors de l'entrée d'un nouveau thread et lors de l'entrée main(), puis de le sauvegarder pour chaque thread lors du démarrage d'une collecte de place, à l'aide d'un verrou global.Détecter les limites de la pile du thread en cours

(je sais que cette approche n'est pas idéale à long terme, car il provoque le verrouillage inutile, mais pour l'instant il est acceptable que les bases sont en place)

Mais je voudrais vraiment avoir un plus " sécurisée "façon de détecter les limites, car il est assez facile pour les racines d'échapper à ce mécanisme (en fonction de l'implémentation du thread - pthreads est facile à gérer, mais pas avec OpenMP ou Grand Central Dispatch).

Ce serait encore plus génial s'il y avait une façon portable de le faire, mais je ne m'attends pas à ce que ce soit le cas. Je travaille actuellement sur Mac OS X 10.6, mais les réponses pour toutes les plateformes sont les bienvenues.

Répondre

1

Vous pouvez utiliser le mécanisme VM pour protéger en écriture la fin de la pile et développer une interruption d'écriture de machine virtuelle. Ensuite, vous connaissez la limite de la pile dans une page de pile. Mais je ne suis pas sûr de comprendre l'objection à simplement inspecter la valeur actuelle du SP pour le thread existant, * si vous faites l'hypothèse de "grosse pile" * généralement supposé par le petit nombre de -threads communauté de parallélisme. Voir this SO article pour une discussion sur un modèle mondial où vous n'avez pas de "grandes piles". Ensuite, vous ne pouvez pas créer un GC qui balaye simplement "la pile", car il est affecté à la demande (par exemple, l'entrée de la fonction). Vous devez maintenant scanner tous les segments de pile qui peuvent être en ligne.

+0

Merci pour cette entrée. Votre suggestion d'utiliser des pièges d'écriture de mémoire virtuelle est intelligente, mais vous avez probablement raison de dire que c'est inutile. De plus, cela ne fonctionnerait qu'avec la croissance de la pile, et non lorsque l'espace de pile requis est réduit, ce qui le rend inutilisable pour les besoins du GC (puisqu'il y aura beaucoup de racines non utilisées). Ce qui m'inquiète le plus, ce sont les implémentations de threads qui font des hypothèses différentes sur la mise en page et la taille de la pile, mais il se peut que mes soucis ne soient pas fondés. –

+0

Les implémentations de threads n'ont pas beaucoup de choix, compte tenu des espaces d'adresses linéaires. Chaque thread doit être démarré, avec une quantité linéaire maximale de pile. Linux et MS le font tous les deux, avec une (pré) allocation de 1Mb (définie par défaut dans le fichier objet), mais n'importe quel fork peut spécifier le montant. Le cas que je trouve intéressant est quand la préallocation est petite, et les appels de fonction allouent de nouveaux segments de trame de pile linéaires de manière non-concordante par rapport à la pile de l'appelant. Ensuite, un simple balayage linéaire de "la" pile ne peut pas fonctionner, car il y a beaucoup de morceaux. –

Questions connexes