Proc control block

Primitive code for the allocation library
This commit is contained in:
secXsQuared 2016-05-16 00:34:41 -07:00
parent 1ba3afd68a
commit 9e96b66a08
6 changed files with 265 additions and 3 deletions

26
Test/bit_operation.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef _BIT_OPERATION_H_
#define _BIT_OPERATION_H_
#include <stdint.h>
static inline uint64_t bit_mask_64(uint32_t bit)
{
return (uint64_t)1 << bit;
}
static inline uint32_t bit_mask_32(uint32_t bit)
{
return (uint32_t)1 << bit;
}
static inline uint64_t bit_field_mask_64(uint32_t low, uint32_t high)
{
return ~(~(uint64_t)0 << high << 1) << low;
}
static inline uint32_t bit_field_mask_32(uint32_t low, uint32_t high)
{
return ~(~(uint32_t)0 << high << 1) << low;
}
#endif

203
Test/main.c Normal file
View File

@ -0,0 +1,203 @@
#include <stdint.h>
#include <stdio.h>
#include "bit_operation.h"
typedef union {
uint32_t size;
uint32_t flags;
} alloc_header;
#define ALLOC_FLAG_NUM 2
#define ALLOC_HEADER_FLAG_FREE 0
#define ALLOC_HEADER_FLAG_LAST 1
void set_alloc_header_size(alloc_header* header, uint32_t size)
{
// align the integer, ignoring overflowed bits
size <<= ALLOC_FLAG_NUM;
// clear ALLOC_FLAG_NUM-th to 31-th bits
header->size &= ~bit_field_mask_32(ALLOC_FLAG_NUM, 31);
// set bits
header->size |= size;
return;
}
uint32_t read_alloc_header_size(alloc_header* header)
{
return header->size >> ALLOC_FLAG_NUM;
}
uint32_t read_alloc_header_flag(alloc_header* header, uint32_t bit)
{
return (header->flags & bit_mask_32(bit)) == 0 ? 0 : 1;
}
void set_alloc_header_flag(alloc_header* header, uint32_t bit, uint32_t value)
{
value &= bit_mask_32(1);
if(value == 1)
{
header->flags |= bit_mask_32(bit);
}
else
{
header->flags &= ~bit_mask_32(bit);
}
return;
}
int init_alloc(void* base, unsigned int size)
{
if(base != NULL && size >= sizeof(unsigned int))
{
alloc_header* ptr = (alloc_header*)base;
set_alloc_header_size(ptr, size);
set_alloc_header_flag(ptr, ALLOC_HEADER_FLAG_FREE, 1);
set_alloc_header_flag(ptr, ALLOC_HEADER_FLAG_LAST, 1);
return 0;
}
return 1;
}
void alloc_join_free(void *base)
{
if(base != NULL)
{
char* c_ptr = (char*)base;
while(1)
{
uint32_t c_blk_free = read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t c_blk_last = read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t c_blk_size = read_alloc_header_size((alloc_header*)c_ptr);
char* n_ptr = c_blk_last == 1 ? NULL : c_ptr + c_blk_size;
if(n_ptr != NULL && c_blk_free == 1)
{
// if this is not the last block and the prev block is free
uint32_t n_blk_free = read_alloc_header_flag((alloc_header *) n_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t n_blk_last = read_alloc_header_flag((alloc_header *) n_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t n_blk_size = read_alloc_header_size((alloc_header*)n_ptr);
if (n_blk_free == 1)
{
// logically gone
set_alloc_header_size((alloc_header *) c_ptr, n_blk_size + c_blk_size);
set_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, n_blk_last);
continue;
}
}
// update the c_ptr
if(c_blk_last == 0)
{
c_ptr += c_blk_size;
}
else
{
break;
}
}
}
}
int kfree(void* base, void* ptr)
{
if(base != NULL && ptr != NULL)
{
char* c_ptr = (char*)base;
while(1)
{
uint32_t cur_blk_free = read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_last = read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t cur_blk_size = read_alloc_header_size((alloc_header*)c_ptr);
if (cur_blk_free == 0 && ptr == c_ptr + sizeof(alloc_header))
{
// we found the block, mark it as free
set_alloc_header_flag((alloc_header*)c_ptr, ALLOC_HEADER_FLAG_FREE, 1);
// merge blocks
alloc_join_free(base);
return 0;
}
if(cur_blk_last == 1)
{
break;
}
else
{
c_ptr += cur_blk_size;
}
}
}
return 1;
}
int kalloc(void* base, unsigned int size, void** ptr)
{
if(base != NULL && size != 0 && ptr != NULL)
{
unsigned int total_size = size + sizeof(alloc_header);
char* c_ptr = (char*)base;
while(1)
{
uint32_t cur_blk_free = read_alloc_header_flag((alloc_header*)c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_size = read_alloc_header_size((alloc_header*)c_ptr);
uint32_t cur_blk_last = read_alloc_header_flag((alloc_header*)c_ptr, ALLOC_HEADER_FLAG_LAST);
if(cur_blk_free == 0)
{
//if cur block not a free block
if(cur_blk_last == 1)
//if last one, break and fail.
break;
else
c_ptr += cur_blk_size;
}
else if(cur_blk_size >= total_size)
{
// we have a free block with enough size
if(total_size == cur_blk_size ||
cur_blk_size - total_size <= sizeof(alloc_header))
{
// since the space left is not enough for alloc_header
// we alloc the whole block
set_alloc_header_flag((alloc_header*)c_ptr, ALLOC_HEADER_FLAG_FREE, 0);
}
else
{
// we split the block here
// set properties for the first block
set_alloc_header_size((alloc_header*)c_ptr, total_size);
set_alloc_header_flag((alloc_header*)c_ptr, ALLOC_HEADER_FLAG_LAST, 0);
set_alloc_header_flag((alloc_header*)c_ptr, ALLOC_HEADER_FLAG_FREE, 0);
// set properties for the second block
set_alloc_header_size((alloc_header*)(c_ptr + total_size), cur_blk_size - total_size);
set_alloc_header_flag((alloc_header*)(c_ptr + total_size), ALLOC_HEADER_FLAG_LAST, cur_blk_last);
set_alloc_header_flag((alloc_header*)(c_ptr + total_size), ALLOC_HEADER_FLAG_FREE, 1);
}
// return the pointer, skip the alloc header
*ptr = c_ptr + sizeof(alloc_header);
return 0;
}
}
}
// getting here means did not work
if(ptr != NULL)
*ptr = NULL;
return 1;
}
char buffer[1024];
int main()
{
void *a = NULL, *b = NULL, *c = NULL, *d = NULL;
init_alloc(buffer, 1024);
kalloc(buffer, 10, &a);
kalloc(buffer, 10, &b);
kalloc(buffer, 10, &c);
kalloc(buffer, 10, &d);
return 0;
}

View File

@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h>
#define _KERNEL_ABI __attribute__((sysv_abi)) #define _KERNEL_ABI __attribute__((sysv_abi))

View File

@ -2,9 +2,12 @@
#include "../common/sys/type.h" #include "../common/sys/type.h"
#include "mem.h" #include "mem.h"
#define kernel_heap_size 4096 #define KERNEL_HEAP_SIZE 4096
char kernel_heap[KERNEL_HEAP_SIZE];
char *_cur_heap = NULL; char *_cur_heap = NULL;
extern char kernel_heap[kernel_heap_size]; extern char kernel_heap[KERNEL_HEAP_SIZE];
void _KERNEL_ABI hal_write_pt_entry(void *const base, uint64_t const p_addr, uint64_t const attr) void _KERNEL_ABI hal_write_pt_entry(void *const base, uint64_t const p_addr, uint64_t const attr)
{ {
@ -141,7 +144,7 @@ void* _KERNEL_ABI hal_halloc(_IN size_t const size)
{ {
if (_cur_heap == NULL) if (_cur_heap == NULL)
_cur_heap = kernel_heap; _cur_heap = kernel_heap;
if (_cur_heap + size < kernel_heap + kernel_heap_size) if (_cur_heap + size < kernel_heap + KERNEL_HEAP_SIZE)
{ {
_cur_heap = _cur_heap + size; _cur_heap = _cur_heap + size;
return _cur_heap - size; return _cur_heap - size;

1
x64/src/c/kernel/proc.c Normal file
View File

@ -0,0 +1 @@
#include "proc.h"

28
x64/src/c/kernel/proc.h Normal file
View File

@ -0,0 +1,28 @@
//
// Created by Oscar on 2016-04-24.
//
#ifndef _PROC_H
#define _PROC_H
#include "../common/sys/kdef.h"
typedef struct __attribute__((packed))
{
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
} process_context_t;
typedef struct __attribute__((packed))
{
uint32_t process_id;
uint32_t priority;
process_context_t context;
} process_control_block_t;
#endif