連絡帳/200309-200401


2003/09/01〜2004/01/31までの連絡帳

Vesa Consoleの件 Gakuさん

メモリマネジャ(0x200000割当て)の件 To:Gaku様

フォント表示の件 To:Gakuさん

a.elfの件 To:Gakuさん

01:05 [Gaku] これなんですが、a.elf と打って、リターンすると盛大に PageFault するんですが。何のエラーでしょう?
01:05 [Gaku] A.ELF のバイナリがまずいのか。。。

kernel.cpp の testFD について by Gaku

To:Gakuさん from Higepon

HList<T>::removeAt おかしくないですか? by Gaku

kernel panic しますね

コメントはありません。 コメント/連絡帳/200309-200401?

お名前:

幾つか連絡(or 相談、でなけりゃ質問) by Gaku

”非常に簡単に”ファイル読んだり、BMP表示したり、キー入力を取得したり。
ていう関数とか、ライブラリというか作ったら使う人いますかね?

というのは、Monaに自分で少しプログラムを付け足して遊んで見たいけれど、ちょっと難しいなぁ。
と思う人が居るなら、なるべく”非常に簡単に”なるように便利に使える道具を作ってみようかと。
そういう話なんですが。

追記:
こういう記事って、ここに書くのが適当なのでしょうか?
トップページから辿れるページでそれっぽいのはここかなぁと思ったのですが、
いまいち、どこに書き込んで良いか判然としませんでした。

Gakuさんの提案に対するコメント

コメントはありません。 コメント/連絡帳/200309-200401?

お名前:

mallocのバグ

struct memoryEntry* freeBlock = (struct memoryEntry*)((dword)current + (dword)realSize);
#include <stdlib.h>
#include <stdio.h>
 
typedef unsigned int dword;
typedef unsigned char byte;
 
typedef struct memoryentry {
    struct memoryentry* next;
    dword size;
    char startAddress[0];
} MemoryEntry;
 
class MemoryManager {
 
  public:
    MemoryManager(dword start, dword end);
    ~MemoryManager();
 
  public:
    dword allocate(dword size);
    void free(dword address);
    dword getFreeMemorySize() const;
    dword getUsedMemorySize() const;
    void debugPrint() const;
 
  private:
    bool hasNoEntry(MemoryEntry* list) const;
    void addToList(MemoryEntry** list, MemoryEntry* entry);
    void deleteFromList(MemoryEntry** list, MemoryEntry* entry);
    void addToNext(MemoryEntry* current, MemoryEntry* next);
    void concatFreeList();
    bool tryConcat(MemoryEntry* entry);
    dword getRealSize(dword size);
 
  private:
    MemoryEntry* freeList_;
    MemoryEntry* usedList_;
 
};
 
#define MANAGE_SIZE    (10 * 1024 * 1024)
#define SIZE_OF_HEADER sizeof(MemoryEntry)
 
void test(MemoryManager* mm);
 
/*
    main()
*/
int main(int argc, char* argv) {
 
    byte* memory = (byte*)malloc(MANAGE_SIZE);
 
    if (memory == NULL) {
 
        printf("memory allocate error\n");
        exit(-1);
    }
 
    static MemoryManager mm((dword)memory, (dword)memory + MANAGE_SIZE);
 
    test(&mm);
 
    free(memory);
    return 0;
}
 
void test(MemoryManager* mm) {
 
    /* this test code expects 10mb of memory is availble */
    dword testNumber = 1;
 
    /* test normal */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p = mm->allocate(8* 1024);
        mm->free(p);
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test normal */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p = mm->allocate(513);
        mm->free(p);
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test normal */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p = mm->allocate(5);
        mm->free(p);
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test 2 times allocate */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p1 = mm->allocate(5);
        dword p2 = mm->allocate(512);
        mm->free(p2);
        mm->free(p1);
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test 2 times allocate */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p1 = mm->allocate(2 * 1024 * 1024);
        dword p2 = mm->allocate(512);
        mm->free(p2);
        mm->free(p1);
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test 2 times allocate */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p1 = mm->allocate(2 * 1024 * 1024);
        dword p2 = mm->allocate(512);
        mm->free(p1);
        mm->free(p2);
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test 30 times allocate */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p[30];
 
        for (int i = 0; i < 30; i++) {
 
            p[i] = mm->allocate(100 * 1024);
            if (p[i] == (dword)NULL) {
                printf("test%d failed allocate error\n", testNumber);
                exit(-1);
            }
        }
 
        for (int i = 0; i < 30; i++) {
 
            mm->free(p[i]);
        }
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test 30 times allocate reverse */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p[30];
 
        for (int i = 0; i < 30; i++) {
 
            p[i] = mm->allocate(100 * 1024);
            if (p[i] == (dword)NULL) {
                printf("test%d failed allocate error\n", testNumber);
                exit(-1);
            }
        }
 
        for (int i = 29; i >= 0 ; i--) {
 
            mm->free(p[i]);
        }
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
 
    /* test 100 times allocate reverse */
    {
        dword freeMememorySize = mm->getFreeMemorySize();
        dword usedMememorySize = mm->getUsedMemorySize();
 
        dword p[100];
 
        for (int i = 0; i < 100; i++) {
 
            p[i] = mm->allocate(i + 1);
            if (p[i] == (dword)NULL) {
                printf("test%d failed allocate error\n", testNumber);
                exit(-1);
            }
        }
 
        for (int i = 99; i >= 0 ; i--) {
 
            mm->free(p[i]);
        }
 
        if (freeMememorySize != mm->getFreeMemorySize() || usedMememorySize != mm->getUsedMemorySize()) {
 
            printf("test%d failed\n", testNumber);
            exit(-1);
        }
        printf("test%d OK\n", testNumber);
        testNumber++;
    }
}
 
MemoryManager::MemoryManager(dword start, dword end) {
 
    /* create large free block */
    freeList_       = (MemoryEntry*)start;
    freeList_->next = (MemoryEntry*)NULL;
    freeList_->size = end - start - SIZE_OF_HEADER;
 
    /* memory not used yet */
    usedList_ = (MemoryEntry*)NULL;
}
 
MemoryManager::~MemoryManager() {
 
 
}
 
bool MemoryManager::hasNoEntry(MemoryEntry* list) const {
 
    return (list == (MemoryEntry*)NULL);
}
 
void MemoryManager::addToNext(MemoryEntry* current, MemoryEntry* next) {
 
    MemoryEntry* nextnext = current->next;
    current->next         = next;
    next->next            = nextnext;
}
 
void MemoryManager::addToList(MemoryEntry** list, MemoryEntry* entry) {
 
    MemoryEntry* target = *list;
 
    if (hasNoEntry(target)) {
 
        *list        = entry;
        entry->next  = (MemoryEntry*)NULL;
        return;
    }
 
    if (entry < target) {
 
        entry->next = target;
        *list = entry;
        return;
    }
 
    for (; ; target = target->next) {
 
        bool isBetween   = target < entry && entry < target->next;
        bool isEndOfList = target->next == (MemoryEntry*)NULL;
 
        if (isBetween || isEndOfList) {
 
            addToNext(target, entry);
            break;
        }
    }
 
    return;
}
 
void MemoryManager::concatFreeList() {
 
    for (MemoryEntry* current = freeList_; current != (MemoryEntry*)NULL; current = current->next) {
 
        while (true) {
            if (!tryConcat(current)) break;
        }
    }
}
 
bool MemoryManager::tryConcat(MemoryEntry* entry) {
 
    /* has no next entry */
    if (entry->next == (MemoryEntry*)NULL) return false;
 
    MemoryEntry* expectedNext = (MemoryEntry*)((dword)entry + getRealSize(entry->size));
 
    /* can not concat */
    if (expectedNext != entry->next) return false;
 
    /* concat */
    dword nextSize = getRealSize(entry->next->size);
    entry->next = entry->next->next;
    entry->size += nextSize;
 
    return true;
}
 
dword MemoryManager::getRealSize(dword size) {
 
    return (size + SIZE_OF_HEADER);
}
 
dword MemoryManager::allocate(dword size) {
 
    if (size == 0) return (dword)NULL;
 
    MemoryEntry* current;
    MemoryEntry* usedBlock;
    dword realSize = getRealSize(size);
 
    for (current = freeList_; ; current = current->next) {
 
        if (current->size >= realSize) break;
        if (current->next == (MemoryEntry*)NULL) return (dword)NULL;
    }
 
    if (current->size == realSize) {
 
        deleteFromList(&freeList_, current);
        addToList(&usedList_, current);
        return (dword)(current->startAddress);
 
    } else if (current->size - realSize >= SIZE_OF_HEADER) {
 
        MemoryEntry* freeBlock = (MemoryEntry*)((dword)current + realSize);
        freeBlock->size  = getRealSize(current->size) - realSize - SIZE_OF_HEADER;
        current->size = size;
 
        deleteFromList(&freeList_, current);
        addToList(&usedList_, current);
        addToList(&freeList_, freeBlock);
 
        return (dword)(current->startAddress);
 
    } else {
 
        return (dword)NULL;
    }
 
 
}
 
void MemoryManager::free(dword address) {
 
    if (address < 1) return;
 
    MemoryEntry* entry = (MemoryEntry*)(address - SIZE_OF_HEADER);
 
    deleteFromList(&usedList_, entry);
    addToList(&freeList_, entry);
    concatFreeList();
}
 
void MemoryManager::deleteFromList(MemoryEntry** list, MemoryEntry* entry) {
 
    /* delete block is top of the list */
    if (*list == entry && (*list)->next == (MemoryEntry*)NULL) {
 
        *list = (MemoryEntry*)NULL;
        return;
    } else if (*list == entry && (*list)->next != (MemoryEntry*)NULL) {
 
        MemoryEntry* next = (*list)->next;
        *list = next;
        return;
    }
 
    /* iterate list and find block to delete */
    for (MemoryEntry* current = *list; current != (MemoryEntry*)NULL; current = current->next) {
 
        /* block to delete found */
        if (current->next == entry) {
            current->next = current->next->next;
            break;
        }
    }
 
    return;
}
 
dword MemoryManager::getFreeMemorySize() const {
 
    dword result = 0;
 
    for (MemoryEntry* current = freeList_; current != (MemoryEntry*)NULL; current = current->next) {
 
        result += (current->size);
    }
    return result;
}
 
dword MemoryManager::getUsedMemorySize() const {
 
    dword result = 0;
 
    for (MemoryEntry* current = usedList_; current != (MemoryEntry*)NULL; current = current->next) {
 
        result += (current->size);
    }
    return result;
}
 
void MemoryManager::debugPrint() const {
 
    printf("FreeMemorySize=%d\n", getFreeMemorySize());
 
    for (MemoryEntry* current = freeList_; current != (MemoryEntry*)NULL; current = current->next) {
 
        printf("F[%d][%d]\n", current, current->size);
    }
 
    printf("UsedMemorySize=%d\n", getUsedMemorySize());
 
    for (MemoryEntry* current = usedList_; current != (MemoryEntry*)NULL; current = current->next) {
 
        printf("U[%d][%d]\n", current, current->size);
    }
 
 
}

MENU

now: 3

リンク


最新の20件
2018-10-07 2018-09-20 2018-09-03 2018-05-09 2017-09-29 2017-01-10 2016-12-11 2016-10-04 2016-08-14 2016-05-29 2015-12-28 2013-02-25 2013-02-21 2013-02-20 2013-02-12 2013-02-11 2013-02-10
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 2691, today: 1, yesterday: 0

リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Last-modified: 2008-03-28 (金) 15:48:03 (3857d);  Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.074 sec.