Ist das so wie du das gemeint hast?
Jep, genau sowas. Einen Bug sehe ich da allerdings noch. Der macht sich zwar nur in einem der Grenzfälle bemerkbar, aber ein Auge für sowas zu entwickeln, ist nie schlecht. Was passiert wenn, du
long[] testarr = {0,0,0,0,0,0,0,0,0}; /* die anzahl nullen ist egal */
verwendest? Und wie korrigiert man das? Auf Grund der Uhrzeit
1) entschließe ich mich mal, das als Rätsel zu formulieren. Falls du nicht auf die Lösung kommst, geht die Schnitzeljagd hier los:
http://pastebin.com/JdPGFGn1 Die Entdeckung solcher Probleme meinte ich übrigens mit "gründlich Testen". Andere Testfälle, wären beispielsweise noch ein leeres Array, oder ein Array mit 0xfffffffff belegt. Einfach mal gucken, ob die Funktion, da dann auch das tut, was sie soll, auch wenn es ggf. nur eine Fehlermeldung (oder Rückgabewert -1) ist.
Bei dem 2. bin ich mir allerdings nicht sicher wie ich das hinkriege dass ich das niedrigste gesetzte Bit in einem Integer finde.
Das ist schwer zu erklären ohne gleich den Code zu servieren, deswegen hier mal eine einfache Implementierung:
private static int bitscanforward(int x) {
int i;
for (i = 0; i < 32; i++) {
if ((x & (1 << i)) != 0)
return i;
}
/* ups gar kein bit war gesetzt */
return -1;
}
Ein (32-Bit-)Integer hat 32 Bits. Deswegen habe ich da eine Schleife, die von 0 bis 31 läuft. Der Wert von
1 << i ist mathematisch gesehen
2^i und ist in Binärdarstellung eine Zahl, die genau ein Bit auf 1 gesetzt hat (nämlich das i-te) und alle anderen sind 0. Das heißt wenn wir
x & (1 << i) auswerten, hat dieses ein Ergebnis ungleich 0, wenn sowohl
x als auch
1 << i an der selben Bitposition ungleich 0 sind. Also genau dann, wenn
x an der i-ten Bitposition ungleich 0 ist. Weil wir die Schleife aufsteigend von 0 an durchlaufen, finden wir mit dieser Methode das niedrigste Bit ungleich 0. (Das ist etwas, das man sich im Zweifelsfall mal aufmalen sollte.)
Deine (hoffentlich korrigierte) Funktion und meine Funktion kannst du nun kombinieren, um deine pmm_alloc zu implementieren. Deine Funktion sollte einen Eintrag in der Bitmap ungleich 0 finden, und meine Funktion sollte darin den Index bestimmen. Der Algorithmus ist dann
2)index = indexArrayValNotNull(bitmap);
bit = bitscanforward(bitmap[index]);
page_nummer = index * 32 + bit; // 32 pages pro eintrag in "bitmap"
adresse = page_nummer * 4096; // jede page ist 4096 bytes groß
Und zu der Frage, ob nun char* oder void* oder unsigned int: Eigentlich absolut nicht egal, aber solange mir keiner widerspricht: unsigned int.
Zur Fehlerbehandlung: Wenn deine Funktion (gerechtfertigt) -1 zurück gibt, dann ist der Speicher übrigens komplett belegt, und dein OS sollte anhalten. Meine Funktion sollte nie -1 zurückgeben, wenn du sie mit Bitmap-Einträgen fütterst, die ungleich 0 sind.
1) 2) Individualisierung angebracht und erwünscht