Fixup keyboard handler, add string manipulation to lainlib
This commit is contained in:
parent
49f3afbecb
commit
31fdb462ab
|
@ -22,6 +22,7 @@
|
||||||
#include <kernel/system/pci.h>
|
#include <kernel/system/pci.h>
|
||||||
#include <kernel/system/stack.h>
|
#include <kernel/system/stack.h>
|
||||||
|
|
||||||
|
#include <lainlib/lainlib.h>
|
||||||
#include <lainlib/ethernet/e1000/e1000.h>
|
#include <lainlib/ethernet/e1000/e1000.h>
|
||||||
|
|
||||||
//Removed cause "wacky copyrighted stuff"
|
//Removed cause "wacky copyrighted stuff"
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char Char;
|
char Char;
|
||||||
int Scancode;
|
char Scancode;
|
||||||
bool Pressed;
|
bool Pressed;
|
||||||
} KeyboardData;
|
} KeyboardData;
|
||||||
|
|
||||||
typedef void (*KeyboardCallback)(KeyboardData* Frame);
|
typedef void (*KeyboardCallback)(KeyboardData Frame);
|
||||||
|
|
||||||
extern KeyboardCallback KeyboardCallbacks[16];
|
extern KeyboardCallback KeyboardCallbacks[16];
|
||||||
|
|
||||||
int SetupKBCallback(void (*Handler)(KeyboardData* Frame));
|
int SetupKBCallback(void (*Handler)(KeyboardData Frame));
|
||||||
|
|
||||||
void UninstallKBCallback(int Index);
|
void UninstallKBCallback(int Index);
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
|
@ -13,8 +12,6 @@
|
||||||
* If need be, they can also be moved into a trimmed-down "kernel libc" or "libk".
|
* If need be, they can also be moved into a trimmed-down "kernel libc" or "libk".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <lainlib/vector/vector.h>
|
#include <lainlib/vector/vector.h>
|
||||||
|
|
||||||
#include <lainlib/list/list.h>
|
#include <lainlib/list/list.h>
|
||||||
|
@ -22,4 +19,6 @@
|
||||||
#include <lainlib/mutex/spinlock.h>
|
#include <lainlib/mutex/spinlock.h>
|
||||||
#include <lainlib/mutex/ticketlock.h>
|
#include <lainlib/mutex/ticketlock.h>
|
||||||
|
|
||||||
|
#include <lainlib/string/str.h>
|
||||||
|
|
||||||
#include <lainlib/compression/lzg.h>
|
#include <lainlib/compression/lzg.h>
|
||||||
|
|
10
inc/lainlib/string/str.h
Normal file
10
inc/lainlib/string/str.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/************************
|
||||||
|
*** Team Kitty, 2021 ***
|
||||||
|
*** Chroma ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
size_t strlen(const char* String);
|
||||||
|
|
||||||
|
bool strcmp(char* a, const char* b);
|
59
src/kernel.c
59
src/kernel.c
|
@ -20,7 +20,13 @@ size_t KernelEnd = (size_t) &end;
|
||||||
|
|
||||||
address_space_t KernelAddressSpace;
|
address_space_t KernelAddressSpace;
|
||||||
|
|
||||||
void PrintPressedChar(KeyboardData* data);
|
void PrintPressedChar(KeyboardData data);
|
||||||
|
int CharPrinterCallbackID;
|
||||||
|
void TrackInternalBuffer(KeyboardData data);
|
||||||
|
int InternalBufferID;
|
||||||
|
|
||||||
|
size_t BufferLength = 0;
|
||||||
|
char* InternalBuffer;
|
||||||
|
|
||||||
int Main(void) {
|
int Main(void) {
|
||||||
KernelAddressSpace = (address_space_t) {0};
|
KernelAddressSpace = (address_space_t) {0};
|
||||||
|
@ -48,13 +54,14 @@ int Main(void) {
|
||||||
|
|
||||||
InitMemoryManager();
|
InitMemoryManager();
|
||||||
|
|
||||||
InitPrint();
|
|
||||||
|
|
||||||
InitPaging();
|
InitPaging();
|
||||||
|
|
||||||
Printf("Paging complete. System initialized.\n\r");
|
Printf("Paging complete. System initialized.\n\r");
|
||||||
KernelLoaded = true;
|
KernelLoaded = true;
|
||||||
|
|
||||||
|
InternalBuffer = (char*) kmalloc(4098);
|
||||||
|
SerialPrintf("[ Mem] Allocated a text buffer at 0x%p\r\n", (size_t) InternalBuffer);
|
||||||
|
|
||||||
SetForegroundColor(0x00FF0000);
|
SetForegroundColor(0x00FF0000);
|
||||||
WriteChar('C');
|
WriteChar('C');
|
||||||
SetForegroundColor(0x0000FF00);
|
SetForegroundColor(0x0000FF00);
|
||||||
|
@ -82,22 +89,54 @@ int Main(void) {
|
||||||
|
|
||||||
SetForegroundColor(0x00FFFFFF);
|
SetForegroundColor(0x00FFFFFF);
|
||||||
|
|
||||||
int CharPrinterCallbackID = SetupKBCallback(&PrintPressedChar);
|
CharPrinterCallbackID = SetupKBCallback(&PrintPressedChar);
|
||||||
UNUSED(CharPrinterCallbackID);
|
|
||||||
|
InternalBufferID = SetupKBCallback(&TrackInternalBuffer);
|
||||||
|
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintPressedChar(KeyboardData* data) {
|
void PrintPressedChar(KeyboardData data) {
|
||||||
if(!KernelLoaded) return;
|
if(!KernelLoaded) return;
|
||||||
|
|
||||||
if(data->Pressed) {
|
if(data.Pressed) {
|
||||||
SerialPrintf("Key released: [\\%c]\r\n", data->Char);
|
SerialPrintf("Key pressed: [\\%c (%x)]\r\n", data.Char, data.Scancode);
|
||||||
|
Printf("%c", data.Char);
|
||||||
} else {
|
} else {
|
||||||
SerialPrintf("Key pressed: [\\%c (%x)]\r\n", data->Char, data->Scancode);
|
SerialPrintf("Key released: [\\%c]\r\n", data.Char);
|
||||||
Printf("%c", data->Char);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackInternalBuffer(KeyboardData data) {
|
||||||
|
if(!data.Pressed) return;
|
||||||
|
|
||||||
|
bool tentative = false;
|
||||||
|
if(BufferLength > 4097) tentative = true;
|
||||||
|
|
||||||
|
if(data.Char == '\b') {
|
||||||
|
BufferLength--;
|
||||||
|
tentative = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.Scancode == 0x1C) {
|
||||||
|
InternalBuffer[BufferLength] = '\0'; // Null-terminate to make checking easier
|
||||||
|
SerialPrintf("[ Kbd] Enter pressed.\r\n");
|
||||||
|
if(strcmp(InternalBuffer, "editor")) {
|
||||||
|
UninstallKBCallback(InternalBufferID);
|
||||||
|
StartEditor(CharPrinterCallbackID);
|
||||||
|
} else {
|
||||||
|
SerialPrintf("[ Kbd] No match for %s\r\n", InternalBuffer);
|
||||||
|
memset(InternalBuffer, 0, 4098);
|
||||||
|
BufferLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!tentative && data.Scancode < 0x27 && data.Scancode != 0x1C) {
|
||||||
|
SerialPrintf("[ Kbd] Adding %c to the buffer.\r\n", data.Char);
|
||||||
|
InternalBuffer[BufferLength] = data.Char;
|
||||||
|
BufferLength++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
src/lainlib/string/str.c
Normal file
25
src/lainlib/string/str.c
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/************************
|
||||||
|
*** Team Kitty, 2021 ***
|
||||||
|
*** Chroma ***
|
||||||
|
***********************/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
size_t strlen(const char* String) {
|
||||||
|
size_t Len = 0;
|
||||||
|
while(String[Len] != '\0') {
|
||||||
|
Len++;
|
||||||
|
}
|
||||||
|
return Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strcmp(char* a, const char* b) {
|
||||||
|
size_t aI = 0, bI = 0;
|
||||||
|
while(true) {
|
||||||
|
if(a[aI] != b[bI]) return false;
|
||||||
|
if(a[aI] == '\0') return true;
|
||||||
|
aI++;
|
||||||
|
bI++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,7 @@ KeyboardCallback KeyboardCallbacks[16] = {
|
||||||
|
|
||||||
static int CurrentCallback = 0;
|
static int CurrentCallback = 0;
|
||||||
|
|
||||||
int SetupKBCallback(void (*Handler)(KeyboardData* Frame)) {
|
int SetupKBCallback(void (*Handler)(KeyboardData Frame)) {
|
||||||
KeyboardCallbacks[CurrentCallback++] = Handler;
|
KeyboardCallbacks[CurrentCallback++] = Handler;
|
||||||
return CurrentCallback;
|
return CurrentCallback;
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,6 @@ void KbdEcho() {
|
||||||
|
|
||||||
void UpdateKeyboard(uint8_t msg) {
|
void UpdateKeyboard(uint8_t msg) {
|
||||||
|
|
||||||
InputBuffer[0] = msg;
|
|
||||||
|
|
||||||
switch(msg) {
|
switch(msg) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
KbdFlags.Error = 1;
|
KbdFlags.Error = 1;
|
||||||
|
@ -119,16 +117,16 @@ void UpdateKeyboard(uint8_t msg) {
|
||||||
|
|
||||||
KeyboardData data = (KeyboardData) {
|
KeyboardData data = (KeyboardData) {
|
||||||
.Scancode = msg,
|
.Scancode = msg,
|
||||||
.Pressed = msg > 0x80 && msg < 0xD8 ? true : false,
|
.Pressed = msg > 0x80 && msg < 0xD8 ? false : true,
|
||||||
.Char = msg > 0x80 && msg < 0xD8 ? keys[msg - 0x80] : keys[msg]
|
.Char = msg > 0x80 && msg < 0xD8 ? keys[msg - 0x80] : keys[msg]
|
||||||
};
|
};
|
||||||
|
|
||||||
void (*Handler)(KeyboardData* data);
|
void (*Handler)(KeyboardData data);
|
||||||
|
|
||||||
for(size_t handlerNum = 0; handlerNum < 16; handlerNum++) {
|
for(size_t handlerNum = 0; handlerNum < 16; handlerNum++) {
|
||||||
Handler = KeyboardCallbacks[handlerNum];
|
Handler = KeyboardCallbacks[handlerNum];
|
||||||
if(Handler) {
|
if(Handler) {
|
||||||
Handler(&data);
|
Handler(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ static int liballoc_free(void* ptr, size_t count) {
|
||||||
} \
|
} \
|
||||||
*((ALIGN_TYPE*)((uintptr_t)ptr - ALIGN_INFO)) = \
|
*((ALIGN_TYPE*)((uintptr_t)ptr - ALIGN_INFO)) = \
|
||||||
diff + ALIGN_INFO; \
|
diff + ALIGN_INFO; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define UNALIGN( ptr ) \
|
#define UNALIGN( ptr ) \
|
||||||
|
@ -89,7 +89,7 @@ static int liballoc_free(void* ptr, size_t count) {
|
||||||
ptr = (void*)((uintptr_t)ptr - diff); \
|
ptr = (void*)((uintptr_t)ptr - diff); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define LIBALLOC_MAGIC 0xc001c0de
|
#define LIBALLOC_MAGIC 0xc001c0de
|
||||||
|
@ -103,7 +103,7 @@ static int liballoc_free(void* ptr, size_t count) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** A structure found at the top of all system allocated
|
/** A structure found at the top of all system allocated
|
||||||
* memory blocks. It details the usage of the memory block.
|
* memory blocks. It details the usage of the memory block.
|
||||||
*/
|
*/
|
||||||
struct liballoc_major
|
struct liballoc_major
|
||||||
|
@ -113,7 +113,7 @@ struct liballoc_major
|
||||||
unsigned int pages; ///< The number of pages in the block.
|
unsigned int pages; ///< The number of pages in the block.
|
||||||
unsigned int size; ///< The number of pages in the block.
|
unsigned int size; ///< The number of pages in the block.
|
||||||
unsigned int usage; ///< The number of bytes used in the block.
|
unsigned int usage; ///< The number of bytes used in the block.
|
||||||
struct liballoc_minor *first; ///< A pointer to the first allocated memory in the block.
|
struct liballoc_minor *first; ///< A pointer to the first allocated memory in the block.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ static void *liballoc_memset(void* s, int c, size_t n)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for ( i = 0; i < n ; i++)
|
for ( i = 0; i < n ; i++)
|
||||||
((char*)s)[i] = c;
|
((char*)s)[i] = c;
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
|
static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
|
||||||
|
@ -174,16 +174,16 @@ static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
|
||||||
|
|
||||||
cdest = (char*)ldest;
|
cdest = (char*)ldest;
|
||||||
csrc = (char*)lsrc;
|
csrc = (char*)lsrc;
|
||||||
|
|
||||||
while ( n > 0 )
|
while ( n > 0 )
|
||||||
{
|
{
|
||||||
*cdest++ = *csrc++;
|
*cdest++ = *csrc++;
|
||||||
n -= 1;
|
n -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined DEBUG || defined INFO
|
#if defined DEBUG || defined INFO
|
||||||
static void liballoc_dump()
|
static void liballoc_dump()
|
||||||
|
@ -204,7 +204,7 @@ static void liballoc_dump()
|
||||||
while ( maj != NULL )
|
while ( maj != NULL )
|
||||||
{
|
{
|
||||||
printf( "liballoc: %x: total = %i, used = %i\n",
|
printf( "liballoc: %x: total = %i, used = %i\n",
|
||||||
maj,
|
maj,
|
||||||
maj->size,
|
maj->size,
|
||||||
maj->usage );
|
maj->usage );
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ static void liballoc_dump()
|
||||||
while ( min != NULL )
|
while ( min != NULL )
|
||||||
{
|
{
|
||||||
printf( "liballoc: %x: %i bytes\n",
|
printf( "liballoc: %x: %i bytes\n",
|
||||||
min,
|
min,
|
||||||
min->size );
|
min->size );
|
||||||
min = min->next;
|
min = min->next;
|
||||||
}
|
}
|
||||||
|
@ -243,15 +243,15 @@ static struct liballoc_major *allocate_new_page( unsigned int size )
|
||||||
st = st / (l_pageSize);
|
st = st / (l_pageSize);
|
||||||
else
|
else
|
||||||
st = st / (l_pageSize) + 1;
|
st = st / (l_pageSize) + 1;
|
||||||
// No, add the buffer.
|
// No, add the buffer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Make sure it's >= the minimum size.
|
// Make sure it's >= the minimum size.
|
||||||
if ( st < l_pageCount ) st = l_pageCount;
|
if ( st < l_pageCount ) st = l_pageCount;
|
||||||
|
|
||||||
maj = (struct liballoc_major*)liballoc_alloc( st );
|
maj = (struct liballoc_major*)liballoc_alloc( st );
|
||||||
|
|
||||||
if ( maj == NULL )
|
if ( maj == NULL )
|
||||||
{
|
{
|
||||||
l_warningCount += 1;
|
l_warningCount += 1;
|
||||||
#if defined DEBUG || defined INFO
|
#if defined DEBUG || defined INFO
|
||||||
|
@ -260,7 +260,7 @@ static struct liballoc_major *allocate_new_page( unsigned int size )
|
||||||
#endif
|
#endif
|
||||||
return NULL; // uh oh, we ran out of memory.
|
return NULL; // uh oh, we ran out of memory.
|
||||||
}
|
}
|
||||||
|
|
||||||
maj->prev = NULL;
|
maj->prev = NULL;
|
||||||
maj->next = NULL;
|
maj->next = NULL;
|
||||||
maj->pages = st;
|
maj->pages = st;
|
||||||
|
@ -276,15 +276,12 @@ static struct liballoc_major *allocate_new_page( unsigned int size )
|
||||||
printf( "liballoc: Total memory usage = %i KB\n", (int)((l_allocated / (1024))) );
|
printf( "liballoc: Total memory usage = %i KB\n", (int)((l_allocated / (1024))) );
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return maj;
|
return maj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void *PREFIX(malloc)(size_t req_size)
|
void *PREFIX(malloc)(size_t req_size)
|
||||||
{
|
{
|
||||||
int startedBet = 0;
|
int startedBet = 0;
|
||||||
|
@ -303,7 +300,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
}
|
}
|
||||||
// So, ideally, we really want an alignment of 0 or 1 in order
|
// So, ideally, we really want an alignment of 0 or 1 in order
|
||||||
// to save space.
|
// to save space.
|
||||||
|
|
||||||
liballoc_lock();
|
liballoc_lock();
|
||||||
|
|
||||||
if ( size == 0 )
|
if ( size == 0 )
|
||||||
|
@ -317,7 +314,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
liballoc_unlock();
|
liballoc_unlock();
|
||||||
return PREFIX(malloc)(1);
|
return PREFIX(malloc)(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( l_memRoot == NULL )
|
if ( l_memRoot == NULL )
|
||||||
{
|
{
|
||||||
|
@ -328,14 +325,14 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
atexit( liballoc_dump );
|
atexit( liballoc_dump );
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This is the first time we are being used.
|
// This is the first time we are being used.
|
||||||
l_memRoot = allocate_new_page( size );
|
l_memRoot = allocate_new_page( size );
|
||||||
if ( l_memRoot == NULL )
|
if ( l_memRoot == NULL )
|
||||||
{
|
{
|
||||||
liballoc_unlock();
|
liballoc_unlock();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "liballoc: initial l_memRoot initialization failed\n", p);
|
printf( "liballoc: initial l_memRoot initialization failed\n", p);
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -349,7 +346,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "liballoc: %x PREFIX(malloc)( %i ): ",
|
printf( "liballoc: %x PREFIX(malloc)( %i ): ",
|
||||||
__builtin_return_address(0),
|
__builtin_return_address(0),
|
||||||
size );
|
size );
|
||||||
FLUSH();
|
FLUSH();
|
||||||
|
@ -359,7 +356,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
|
|
||||||
maj = l_memRoot;
|
maj = l_memRoot;
|
||||||
startedBet = 0;
|
startedBet = 0;
|
||||||
|
|
||||||
// Start at the best bet....
|
// Start at the best bet....
|
||||||
if ( l_bestBet != NULL )
|
if ( l_bestBet != NULL )
|
||||||
{
|
{
|
||||||
|
@ -371,10 +368,10 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
startedBet = 1;
|
startedBet = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( maj != NULL )
|
while ( maj != NULL )
|
||||||
{
|
{
|
||||||
diff = maj->size - maj->usage;
|
diff = maj->size - maj->usage;
|
||||||
// free memory in the block
|
// free memory in the block
|
||||||
|
|
||||||
if ( bestSize < diff )
|
if ( bestSize < diff )
|
||||||
|
@ -383,10 +380,10 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
l_bestBet = maj;
|
l_bestBet = maj;
|
||||||
bestSize = diff;
|
bestSize = diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_CASE1
|
#ifdef USE_CASE1
|
||||||
|
|
||||||
// CASE 1: There is not enough space in this major block.
|
// CASE 1: There is not enough space in this major block.
|
||||||
if ( diff < (size + sizeof( struct liballoc_minor )) )
|
if ( diff < (size + sizeof( struct liballoc_minor )) )
|
||||||
{
|
{
|
||||||
|
@ -394,9 +391,9 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
printf( "CASE 1: Insufficient space in block %x\n", maj);
|
printf( "CASE 1: Insufficient space in block %x\n", maj);
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Another major block next to this one?
|
// Another major block next to this one?
|
||||||
if ( maj->next != NULL )
|
if ( maj->next != NULL )
|
||||||
{
|
{
|
||||||
maj = maj->next; // Hop to that one.
|
maj = maj->next; // Hop to that one.
|
||||||
continue;
|
continue;
|
||||||
|
@ -421,13 +418,13 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CASE2
|
#ifdef USE_CASE2
|
||||||
|
|
||||||
// CASE 2: It's a brand new block.
|
// CASE 2: It's a brand new block.
|
||||||
if ( maj->first == NULL )
|
if ( maj->first == NULL )
|
||||||
{
|
{
|
||||||
maj->first = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major) );
|
maj->first = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major) );
|
||||||
|
|
||||||
|
|
||||||
maj->first->magic = LIBALLOC_MAGIC;
|
maj->first->magic = LIBALLOC_MAGIC;
|
||||||
maj->first->prev = NULL;
|
maj->first->prev = NULL;
|
||||||
maj->first->next = NULL;
|
maj->first->next = NULL;
|
||||||
|
@ -438,14 +435,14 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
|
|
||||||
|
|
||||||
l_inuse += size;
|
l_inuse += size;
|
||||||
|
|
||||||
|
|
||||||
p = (void*)((uintptr_t)(maj->first) + sizeof( struct liballoc_minor ));
|
p = (void*)((uintptr_t)(maj->first) + sizeof( struct liballoc_minor ));
|
||||||
|
|
||||||
ALIGN( p );
|
ALIGN( p );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "CASE 2: returning %x\n", p);
|
printf( "CASE 2: returning %x\n", p);
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
|
@ -453,7 +450,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CASE3
|
#ifdef USE_CASE3
|
||||||
|
|
||||||
// CASE 3: Block in use and enough space at the start of the block.
|
// CASE 3: Block in use and enough space at the start of the block.
|
||||||
|
@ -467,7 +464,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
maj->first->prev = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major) );
|
maj->first->prev = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major) );
|
||||||
maj->first->prev->next = maj->first;
|
maj->first->prev->next = maj->first;
|
||||||
maj->first = maj->first->prev;
|
maj->first = maj->first->prev;
|
||||||
|
|
||||||
maj->first->magic = LIBALLOC_MAGIC;
|
maj->first->magic = LIBALLOC_MAGIC;
|
||||||
maj->first->prev = NULL;
|
maj->first->prev = NULL;
|
||||||
maj->first->block = maj;
|
maj->first->block = maj;
|
||||||
|
@ -481,13 +478,13 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
ALIGN( p );
|
ALIGN( p );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "CASE 3: returning %x\n", p);
|
printf( "CASE 3: returning %x\n", p);
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -495,7 +492,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
|
|
||||||
// CASE 4: There is enough space in this block. But is it contiguous?
|
// CASE 4: There is enough space in this block. But is it contiguous?
|
||||||
min = maj->first;
|
min = maj->first;
|
||||||
|
|
||||||
// Looping within the block now...
|
// Looping within the block now...
|
||||||
while ( min != NULL )
|
while ( min != NULL )
|
||||||
{
|
{
|
||||||
|
@ -506,7 +503,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
diff = (uintptr_t)(maj) + maj->size;
|
diff = (uintptr_t)(maj) + maj->size;
|
||||||
diff -= (uintptr_t)min;
|
diff -= (uintptr_t)min;
|
||||||
diff -= sizeof( struct liballoc_minor );
|
diff -= sizeof( struct liballoc_minor );
|
||||||
diff -= min->size;
|
diff -= min->size;
|
||||||
// minus already existing usage..
|
// minus already existing usage..
|
||||||
|
|
||||||
if ( diff >= (size + sizeof( struct liballoc_minor )) )
|
if ( diff >= (size + sizeof( struct liballoc_minor )) )
|
||||||
|
@ -523,12 +520,12 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
maj->usage += size + sizeof( struct liballoc_minor );
|
maj->usage += size + sizeof( struct liballoc_minor );
|
||||||
|
|
||||||
l_inuse += size;
|
l_inuse += size;
|
||||||
|
|
||||||
p = (void*)((uintptr_t)min + sizeof( struct liballoc_minor ));
|
p = (void*)((uintptr_t)min + sizeof( struct liballoc_minor ));
|
||||||
ALIGN( p );
|
ALIGN( p );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "CASE 4.1: returning %x\n", p);
|
printf( "CASE 4.1: returning %x\n", p);
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
|
@ -562,18 +559,18 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
min->next->prev = new_min;
|
min->next->prev = new_min;
|
||||||
min->next = new_min;
|
min->next = new_min;
|
||||||
maj->usage += size + sizeof( struct liballoc_minor );
|
maj->usage += size + sizeof( struct liballoc_minor );
|
||||||
|
|
||||||
l_inuse += size;
|
l_inuse += size;
|
||||||
|
|
||||||
p = (void*)((uintptr_t)new_min + sizeof( struct liballoc_minor ));
|
p = (void*)((uintptr_t)new_min + sizeof( struct liballoc_minor ));
|
||||||
ALIGN( p );
|
ALIGN( p );
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "CASE 4.2: returning %x\n", p);
|
printf( "CASE 4.2: returning %x\n", p);
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -588,7 +585,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
#ifdef USE_CASE5
|
#ifdef USE_CASE5
|
||||||
|
|
||||||
// CASE 5: Block full! Ensure next block and loop.
|
// CASE 5: Block full! Ensure next block and loop.
|
||||||
if ( maj->next == NULL )
|
if ( maj->next == NULL )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "CASE 5: block full\n");
|
printf( "CASE 5: block full\n");
|
||||||
|
@ -601,7 +598,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
startedBet = 0;
|
startedBet = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we've run out. we need more...
|
// we've run out. we need more...
|
||||||
maj->next = allocate_new_page( size ); // next one guaranteed to be okay
|
maj->next = allocate_new_page( size ); // next one guaranteed to be okay
|
||||||
if ( maj->next == NULL ) break; // uh oh, no more memory.....
|
if ( maj->next == NULL ) break; // uh oh, no more memory.....
|
||||||
|
@ -615,7 +612,7 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
} // while (maj != NULL)
|
} // while (maj != NULL)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -630,20 +627,12 @@ void *PREFIX(malloc)(size_t req_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PREFIX(free)(void *ptr)
|
void PREFIX(free)(void *ptr)
|
||||||
{
|
{
|
||||||
struct liballoc_minor *min;
|
struct liballoc_minor *min;
|
||||||
struct liballoc_major *maj;
|
struct liballoc_major *maj;
|
||||||
|
|
||||||
if ( ptr == NULL )
|
if ( ptr == NULL )
|
||||||
{
|
{
|
||||||
l_warningCount += 1;
|
l_warningCount += 1;
|
||||||
#if defined DEBUG || defined INFO
|
#if defined DEBUG || defined INFO
|
||||||
|
@ -661,16 +650,16 @@ void PREFIX(free)(void *ptr)
|
||||||
|
|
||||||
min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof( struct liballoc_minor ));
|
min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof( struct liballoc_minor ));
|
||||||
|
|
||||||
|
|
||||||
if ( min->magic != LIBALLOC_MAGIC )
|
if ( min->magic != LIBALLOC_MAGIC )
|
||||||
{
|
{
|
||||||
l_errorCount += 1;
|
l_errorCount += 1;
|
||||||
|
|
||||||
// Check for overrun errors. For all bytes of LIBALLOC_MAGIC
|
// Check for overrun errors. For all bytes of LIBALLOC_MAGIC
|
||||||
if (
|
if (
|
||||||
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
|
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
|
||||||
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
|
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
|
||||||
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))
|
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
l_possibleOverruns += 1;
|
l_possibleOverruns += 1;
|
||||||
|
@ -681,8 +670,7 @@ void PREFIX(free)(void *ptr)
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( min->magic == LIBALLOC_DEAD )
|
if ( min->magic == LIBALLOC_DEAD )
|
||||||
{
|
{
|
||||||
#if defined DEBUG || defined INFO
|
#if defined DEBUG || defined INFO
|
||||||
|
@ -701,19 +689,19 @@ void PREFIX(free)(void *ptr)
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// being lied to...
|
// being lied to...
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "liballoc: %x PREFIX(free)( %x ): ",
|
printf( "liballoc: %x PREFIX(free)( %x ): ",
|
||||||
__builtin_return_address( 0 ),
|
__builtin_return_address( 0 ),
|
||||||
ptr );
|
ptr );
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
maj = min->block;
|
maj = min->block;
|
||||||
|
|
||||||
|
@ -725,7 +713,7 @@ void PREFIX(free)(void *ptr)
|
||||||
if ( min->next != NULL ) min->next->prev = min->prev;
|
if ( min->next != NULL ) min->next->prev = min->prev;
|
||||||
if ( min->prev != NULL ) min->prev->next = min->next;
|
if ( min->prev != NULL ) min->prev->next = min->next;
|
||||||
|
|
||||||
if ( min->prev == NULL ) maj->first = min->next;
|
if ( min->prev == NULL ) maj->first = min->next;
|
||||||
// Might empty the block. This was the first
|
// Might empty the block. This was the first
|
||||||
// minor.
|
// minor.
|
||||||
|
|
||||||
|
@ -753,27 +741,23 @@ void PREFIX(free)(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "OK\n");
|
printf( "OK\n");
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void* PREFIX(calloc)(size_t nobj, size_t size)
|
void* PREFIX(calloc)(size_t nobj, size_t size)
|
||||||
{
|
{
|
||||||
int real_size;
|
int real_size;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
real_size = nobj * size;
|
real_size = nobj * size;
|
||||||
|
|
||||||
p = PREFIX(malloc)( real_size );
|
p = PREFIX(malloc)( real_size );
|
||||||
|
|
||||||
liballoc_memset( p, 0, real_size );
|
liballoc_memset( p, 0, real_size );
|
||||||
|
@ -788,7 +772,7 @@ void* PREFIX(realloc)(void *p, size_t size)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
struct liballoc_minor *min;
|
struct liballoc_minor *min;
|
||||||
unsigned int real_size;
|
unsigned int real_size;
|
||||||
|
|
||||||
// Honour the case of size == 0 => free old and return NULL
|
// Honour the case of size == 0 => free old and return NULL
|
||||||
if ( size == 0 )
|
if ( size == 0 )
|
||||||
{
|
{
|
||||||
|
@ -808,15 +792,15 @@ void* PREFIX(realloc)(void *p, size_t size)
|
||||||
min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof( struct liballoc_minor ));
|
min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof( struct liballoc_minor ));
|
||||||
|
|
||||||
// Ensure it is a valid structure.
|
// Ensure it is a valid structure.
|
||||||
if ( min->magic != LIBALLOC_MAGIC )
|
if ( min->magic != LIBALLOC_MAGIC )
|
||||||
{
|
{
|
||||||
l_errorCount += 1;
|
l_errorCount += 1;
|
||||||
|
|
||||||
// Check for overrun errors. For all bytes of LIBALLOC_MAGIC
|
// Check for overrun errors. For all bytes of LIBALLOC_MAGIC
|
||||||
if (
|
if (
|
||||||
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
|
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
|
||||||
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
|
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
|
||||||
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))
|
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
l_possibleOverruns += 1;
|
l_possibleOverruns += 1;
|
||||||
|
@ -827,8 +811,8 @@ void* PREFIX(realloc)(void *p, size_t size)
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( min->magic == LIBALLOC_DEAD )
|
if ( min->magic == LIBALLOC_DEAD )
|
||||||
{
|
{
|
||||||
#if defined DEBUG || defined INFO
|
#if defined DEBUG || defined INFO
|
||||||
|
@ -847,17 +831,17 @@ void* PREFIX(realloc)(void *p, size_t size)
|
||||||
FLUSH();
|
FLUSH();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// being lied to...
|
// being lied to...
|
||||||
liballoc_unlock(); // release the lock
|
liballoc_unlock(); // release the lock
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definitely a memory block.
|
// Definitely a memory block.
|
||||||
|
|
||||||
real_size = min->req_size;
|
real_size = min->req_size;
|
||||||
|
|
||||||
if ( real_size >= size )
|
if ( real_size >= size )
|
||||||
{
|
{
|
||||||
min->req_size = size;
|
min->req_size = size;
|
||||||
liballoc_unlock();
|
liballoc_unlock();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user