6 | | Rappelons qu'un cluster possède deux index: |
7 | | * CID est un index codé sur 32 bits. Il permet d'indexer de façon continue, de 0 à N-1, l'ensemble des clusters contenant au moins un processeur, c'est à dire l'ensemble des instances du noyau. Cet index est - pour l'instant - défini dans le fichier arch_info. |
| 8 | Le code et les différentes structures de données utilisés pour les RPC sont définis dans les fichiers rpc.c et rpc.h. |
| 9 | Ce code utilise une bibliothèque de fonctions d'accès à une FIFO logicielle définie dans les fichiers remote_fifo.c et remote_fifo.h. |
| 10 | Les macros permettant la manipulation des pointeurs étendus sont définies dans le fichier type.h. |
| 11 | |
| 12 | Rappelons que l'architecture cible est décrite dans le fichier arch_info. Cette architecture est généralement clusterisée, et un cluster possède deux index: |
| 13 | * CID est un index codé sur 32 bits. Il permet d'indexer de façon continue, de 0 à N-1, l'ensemble des clusters de l'architecture cible, définis dans le fichier arch_info. Chaque peut contenir un nombre quelconque de CPUs (y compris 0), un nombre quelconque de périphériques, et un banc mémoire physique de longueur quelconque (y compris 0). Il n'existe une instance du noyau que dans les clusters contenant au moins un CPU, un contrôleur d'interruptions, et un banc mémoire physique, ce qui n'est pas le cas de tous les clusters. |
11 | | cluster server, identifié par son index CXY. |
| 21 | cluster serveur. Le serveur est identifié par son index CXY. |
| 22 | Il existe donc dans chaque cluster une RPC_FIFO logicielle possédant à priori N écrivains et M lecteurs. N est le nombre de thread clients, M est le nombre de thread serveurs. |
| 23 | * Pour synchroniser les accès concurrents entre écrivains, la RPC_FIFO imlémente un mécanisme de ticket garantissant que les clients pourront stocker leurs requêtes dans l'ordre d'attribution des tickets. |
| 24 | * pour synchroniser les accès concurrents entre lecteurs, ALMOS-MK implémente un ''light-lock'', qui est un verrou non bloquant enregistrant l'identité du premier lecteur qui obtient le verrou. |
| 31 | == 3) Format d'une RPC == |
| 32 | |
| 33 | Il existe différents types de RPC : |
| 34 | * Une RPC ''simple bloquante'' est envoyée à un seul serveur, et attend une seule réponse. |
| 35 | * Une RPC ''broadcast bloquante'' est envoyée à N serveurs, et attend N réponses. |
| 36 | * Une RPC ''simple non bloquante'' est envoyée à un seul serveur et n'attend pas de réponse. |
| 37 | * Une RPC ''broadcast non bloquante'' est envoyée à N serveurs et n'attend pas de réponse. |
| 38 | |
| 39 | Chaque case d'une RPC_FIFO contient un pointeur étendu (xptr_t) sur un descripteur de RPC (rpc_desc_t), qui est toujours stocké dans la mémoire du cluster client. |
| 40 | Un descripteur de RPC possède un format fixe comportant les informations suivantes: |
| 41 | * Le champs '''index''' définit le type de service demandé (de façon similaire à un index d'appel système). |
| 42 | * Le champs '''response''' est un entier qui défini le nombre de réponses attendues. |
| 43 | * Le champs '''args''' est un tableau de 32 uint32_t contenant les arguments d'entrée et de sortie. |
| 44 | L'utilisation et l'interprétation du tableau '''args''' dépend de chaque type de RPC. |
| 45 | |
| 46 | == 4) Introduction d'une nouvelle RPC == |
| 47 | |
| 48 | L'introduction d'un nouveau service nécessite de modifier le code de ALMOS-MK de la façon suivante opérations suivantes. |
| 49 | * Il doit exister une fonction système ''my_kernel_service()'' possédant un nombre quelconque (inférieur à 32) de paramètres d'entrée ou de sortie. |
| 50 | * La nouvelle doit être enregistrée dans l'enum ''rpc_index_t'' (fichier rpc.h) et dans le tableau ''rpc_exec[]'' (fichier rpc.c). |
| 51 | * Il faut écrire explicitement la fonction de marshaling ''rpc_my_kernel_service_client()'' qui est exécutée du côté client pour (1) enregistrer les arguments d'entrée dans le descripteur de RPC, (2) poster la RPC dans la RPC_FIFO, (3) récupérer les arguments de sortie dans le descripteur de RPC. |
| 52 | * Il faut écrire explicitement a fonction de marshaling ''rpc_my_kernel_service_server()'' qui est exécutée du côté serveur pour (1) récupérer les arguments d'entrée dans le descripteur de RPC, (2) appeler la fonction ''my_kernel_service()'', (3) écrire les arguments de sortie dans le descripteur de RPC. |
| 53 | |