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.
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. –
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. –