Programmation multi-cœurs
Nous allons implémenter un buffer circulaire qui permet à un lecteur et un écrivain d'échanger des données ordonnées sans utiliser de verrou ni de mémoire allouée dynamiquement.
Ce buffer circulaire offre les possibilités suivantes :
- L'initialisation se fait à partir d'un tableau de données non initialisées ou à partir d'un pointeur brut et d'une longueur qui représentent l'espace de stockage utilisé par le buffer circulaire.
- Le buffer est utilisable par un lecteur et un écrivain à la fois, aucun ne pouvant bloquer l'autre. On n'aura jamais des lecteurs multiples ou des écrivains multiples.
- Lorsqu'on veut ajouter des éléments, ils sont soit tous rajoutés soit aucun en cas de manque de place. Des éléments multiples peuvent être ajoutés avec
push_all()
à partir de n'importe quel itérateur qui implémenteExactSizeIterator
afin de pouvoir procéder à la vérification. - Les éléments sont soit récupérés un par un avec
pop()
. - Deux méthodes
execute()
etexecute_max()
permettent d'appliquer une fonction à une vue partielle du buffer circulaire. Les éléments sont présentés sous la forme d'une référence sur une slice et sont considérés pouvoir être libérés une fois que la fonction retourne. - Les références sur le buffer implémentent
Iterator
et renvoient les éléments disponibles.
Récupération du modèle de projet
Étant donné la taille du code, vous disposez d'un modèle de crate disponible ici. Décompressez le et ajoutez le à votre dépôt git.
Ce projet est à compléter partout où se trouvent des todo!()
. Des tests permettent de vérifier le bon comportement du buffer circulaire une fois les fonctions manquantes implémentées.