2016-08-23 6 views
0

J'écris un gestionnaire de mémoire physique bitmap et je veux implémenter une fonction qui vérifie si n bits sont libres à partir d'un bit spécifique. En ce moment j'utiliser cette fonction qui vérifie si un seul bit est gratuit et je l'appelle n fois pour voir si n bits sont libres, mais je pense qu'il est pas très efficace de le faire de cette façon:Comment vérifier si un ensemble de bits est 0 à partir d'une position déterminée?

inline static bool physical_memory_map_test(uint32_t bit) 
{ 
    return physical_memory.blocks[bit/32] & (1 << bit % 32); 
} 

Alors Je veux implemnt quelque chose comme ceci: (le « » contient un code pseudo):

static bool physical_memory_map_test(uint32_t starting_bit, uint32_t count) 
{ 
    int excess = (starting_bit%32 + count) -32; 
    if(excess < 0) 
     return (physical_memory.blocks[bit/32] & "-excess number of 1s" << bit % 32)) && (physical_memory.blocks[bit/32] & "count + excess number of 1s" << bit % 32)); 

    return physical_memory.blocks[bit/32] & ("count number of ones, if count is 3, this should be 111" << bit % 32); 
} 

ou quelque chose de mieux pour vérifier si tous les bits sont 0 (return true) ou si au moins l'un d'eux est un 1 (return false) Comment pourrais-je faire ça?

+0

Si vous voulez le nombre total de bits définis dans un type entier, vous voulez un 'popcount', qui est disponible en tant qu'instruction machine dans certaines architectures, et en tant que compilateur intégré. Si vous voulez compter les bits set * adjacents *, vous pouvez trouver 'ffs()' ou 'clz/ctz' ou' lzcnt/tzcnt' ou 'bsf/bsr' ou les builtins équivalents intéressants. – EOF

+0

Si vous voulez vérifier que les bits 'n' * consécutifs * sont libres, vous pouvez en examiner 32 à la fois, sauf pour le premier et le dernier. –

Répondre

5

Puisque vous vérifiez une plage de uint32_t mots, vous vous retrouverez avec une boucle. Votre tâche consiste à faire en boucle de 32 bits au lieu de boucler de 1 bit.

Vous devez vérifier les mots de 32 bits partiels aux deux extrémités:

Bit groups

Pour ce faire, vous devez construire un masque avec k bits inférieurs mis à 1 et (32-k) supérieur ensemble à 0. Vous pouvez le faire comme ceci:

uint32_t mask_K = ~(~0U << k); 

Utilisez

if (block & mask_K) 

pour tester les k bits inférieurs; Teste les bits supérieurs.

+0

Le calcul de 'mask_K' semblerait invoquer UB pour' k' = 31. – njuffa

+0

J'utilise habituellement '~ (~ 0U << k)' pour construire un masque de 32 bits avec 'k' 1-bit consécutif (0 <= k <32), peut-être que cela conviendrait à votre objectif? – njuffa

+0

@njuffa C'est encore mieux, merci! – dasblinkenlight