saving current changes

This commit is contained in:
2026-05-01 15:47:18 +01:00
parent 0a76c24490
commit 0f4e3f7c72
9 changed files with 9270 additions and 70408 deletions

View File

@@ -20,10 +20,10 @@ void free(void * __capability ptr);
void * __capability malloc(size_t size); void * __capability malloc(size_t size);
/* Initializes vector or matrix, sequentially, with indices. */ /* Initializes vector or matrix, sequentially, with indices. */
void init_seq(double * __capability a, const unsigned n_rows_a, const unsigned n_cols_a) { void init_seq(int * __capability a, const unsigned n_rows_a, const unsigned n_cols_a) {
for (size_t i = 0; i < n_rows_a; i++) { for (size_t i = 0; i < n_rows_a; i++) {
for (size_t j = 0; j < n_cols_a; j++) { for (size_t j = 0; j < n_cols_a; j++) {
a[i*n_cols_a + j] = 2.0; a[i*n_cols_a + j] = 2;
} }
} }
} }
@@ -50,7 +50,7 @@ void init_seq(double * __capability a, const unsigned n_rows_a, const unsigned n
It's also flat in memory, i.e., 1-D, but it should be looked at as a transpose It's also flat in memory, i.e., 1-D, but it should be looked at as a transpose
of m, meaning, n_rows_t == n_cols_m, and n_cols_t == n_rows_m. of m, meaning, n_rows_t == n_cols_m, and n_cols_t == n_rows_m.
The original matrix m stays intact. */ The original matrix m stays intact. */
double __capability * transpose(const double __capability *m, const unsigned n_rows_m, const unsigned n_cols_m, double __capability *t) { int __capability * transpose(const int __capability *m, const unsigned n_rows_m, const unsigned n_cols_m, int __capability *t) {
for (size_t i = 0; i < n_rows_m; i++) { for (size_t i = 0; i < n_rows_m; i++) {
for (size_t j = 0; j < n_cols_m; j++) { for (size_t j = 0; j < n_cols_m; j++) {
t[j*n_rows_m + i] = m[i*n_cols_m + j]; t[j*n_rows_m + i] = m[i*n_cols_m + j];
@@ -63,25 +63,27 @@ double __capability * transpose(const double __capability *m, const unsigned n_r
/* Dot product of two arrays, or matrix product /* Dot product of two arrays, or matrix product
* Allocates and returns an array. * Allocates and returns an array.
* This variant doesn't transpose matrix b, and it's a lot slower. */ * This variant doesn't transpose matrix b, and it's a lot slower. */
double * __capability dot_simple(const double * __capability a, const unsigned n_rows_a, const unsigned n_cols_a,\ int * __capability dot_simple(const int * __capability a, const unsigned n_rows_a, const unsigned n_cols_a,\
const double * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) { const int * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) {
if (n_cols_a != n_rows_b) { if (n_cols_a != n_rows_b) {
// printf("#columns A must be equal to #rows B!\n"); // printf("#columns A must be equal to #rows B!\n");
// system("pause"); // system("pause");
// exit(-2); // exit(-2);
while(1);
} }
double *__capability c = malloc(n_rows_a * n_cols_b * sizeof(*c)); int * __capability c = malloc(n_rows_a * n_cols_b * sizeof(*c));
if (c == NULL) { if (c == NULL) {
// printf("Couldn't allocate memory!\n"); // printf("Couldn't allocate memory!\n");
// system("pause"); // system("pause");
// exit(-1); // exit(-1);
while(1);
} }
for (size_t i = 0; i < n_rows_a; i++) { for (size_t i = 0; i < n_rows_a; i++) {
for (size_t k = 0; k < n_cols_b; k++) { for (size_t k = 0; k < n_cols_b; k++) {
double sum = 0.0; int sum = 0;
for (size_t j = 0; j < n_cols_a; j++) { for (size_t j = 0; j < n_cols_a; j++) {
sum += a[i*n_cols_a + j] * b[j*n_cols_b + k]; sum += a[i*n_cols_a + j] * b[j*n_cols_b + k];
} }
@@ -95,8 +97,8 @@ double * __capability dot_simple(const double * __capability a, const unsigned n
/* Dot product of two arrays, or matrix product /* Dot product of two arrays, or matrix product
* Allocates and returns an array. * Allocates and returns an array.
* This variant transposes matrix b, and it's a lot faster. */ * This variant transposes matrix b, and it's a lot faster. */
double * __capability dot(const double __capability *a, const unsigned n_rows_a, const unsigned n_cols_a, \ int * __capability dot(const int * __capability a, const unsigned n_rows_a, const unsigned n_cols_a, \
const double * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) { const int * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) {
if (n_cols_a != n_rows_b) { if (n_cols_a != n_rows_b) {
// printf("#columns A must be equal to #rows B!\n"); // printf("#columns A must be equal to #rows B!\n");
@@ -104,9 +106,9 @@ double * __capability dot(const double __capability *a, const unsigned n_rows_a
// exit(-2); // exit(-2);
} }
double * __capability bt = malloc(n_rows_b * n_cols_b * sizeof(*b)); int * __capability bt = malloc(n_rows_b * n_cols_b * sizeof(*b));
double * __capability c = malloc(n_rows_a * n_cols_b * sizeof(*c)); int * __capability c = malloc(n_rows_a * n_cols_b * sizeof(*c));
if ((c == NULL) || (bt == NULL)) { if ((c == NULL) || (bt == NULL)) {
// printf("Couldn't allocate memory!\n"); // printf("Couldn't allocate memory!\n");
@@ -118,7 +120,7 @@ double * __capability dot(const double __capability *a, const unsigned n_rows_a
for (size_t i = 0; i < n_rows_a; i++) { for (size_t i = 0; i < n_rows_a; i++) {
for (size_t k = 0; k < n_cols_b; k++) { for (size_t k = 0; k < n_cols_b; k++) {
double sum = 0.0; int sum = 0;
for (size_t j = 0; j < n_cols_a; j++) { for (size_t j = 0; j < n_cols_a; j++) {
sum += a[i*n_cols_a + j] * bt[k*n_rows_b + j]; sum += a[i*n_cols_a + j] * bt[k*n_rows_b + j];
} }
@@ -149,18 +151,18 @@ int main(void) {
// srand(0); // srand(0);
/* For measuring time */ /* For measuring time */
double t0, t1; int t0, t1;
const unsigned scale = 14; const unsigned scale = 20;
const unsigned n_rows_a = 4 * scale; const unsigned n_rows_a = 4 * scale;
const unsigned n_cols_a = 3 * scale; const unsigned n_cols_a = 3 * scale;
const unsigned n_rows_b = 3 * scale; const unsigned n_rows_b = 3 * scale;
const unsigned n_cols_b = 2 * scale; const unsigned n_cols_b = 2 * scale;
double __capability *a = malloc(n_rows_a * n_cols_a * sizeof(*a)); int __capability *a = malloc(n_rows_a * n_cols_a * sizeof(*a));
double __capability *b = malloc(n_rows_b * n_cols_b * sizeof(*b)); int __capability *b = malloc(n_rows_b * n_cols_b * sizeof(*b));
double __capability *c = NULL; int __capability *c = NULL;
double __capability *d = NULL; int __capability *d = NULL;
if (!a || !b) { if (!a || !b) {
// printf("Couldn't allocate memory!\n"); // printf("Couldn't allocate memory!\n");

View File

@@ -384,13 +384,13 @@ int bench() {
wkq = pkt(wkq, I_DEVA, K_DEV); wkq = pkt(wkq, I_DEVA, K_DEV);
wkq = pkt(wkq, I_DEVA, K_DEV); wkq = pkt(wkq, I_DEVA, K_DEV);
createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0); // createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0);
wkq = pkt(0, I_DEVB, K_DEV); // wkq = pkt(0, I_DEVB, K_DEV);
wkq = pkt(wkq, I_DEVB, K_DEV); // wkq = pkt(wkq, I_DEVB, K_DEV);
wkq = pkt(wkq, I_DEVB, K_DEV); // wkq = pkt(wkq, I_DEVB, K_DEV);
createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0); // createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0);
// wkq = 0; // wkq = 0;
// createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0); // createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0);
@@ -434,9 +434,9 @@ int inner_loop(int inner) {
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
//INITREGULARALLOC(); //INITREGULARALLOC();
int iterations = 10; int iterations = 1;
int warmup = 0; int warmup = 0;
int inner_iterations = 10; int inner_iterations = 1;
// parse_argv(argc, argv, &iterations, &warmup, &inner_iterations); // parse_argv(argc, argv, &iterations, &warmup, &inner_iterations);

View File

@@ -15,8 +15,5 @@ SECTIONS
_end = .; _end = .;
__malloc_start = .; __malloc_start = .;
. = . + 0x100000; . = . + 0x10000;
/* End of uninitalized data segement */
_end = .;
} }

View File

@@ -63,35 +63,37 @@ void test() {
// } // }
int main(void) { int main(void) {
char * __capability a = malloc(30); int * __capability a = malloc(30);
char * __capability b = malloc(16); char * __capability b = malloc(16);
// if (!a || !b) return -1; // if (!a || !b) return -1;
a[0] = 'A'; a[0] = 1;
a[1] = 'C'; a[1] = 'C';
b[0] = 'B'; b[0] = 'B';
b[10] = 'D';
// This will fault (out-of-bounds) // This will fault (out-of-bounds)
// a[20] = 'X'; // a[20] = 'X';
if (a[1] != 'C') { if (a[0] != 1) {
while (1); while (1);
} }
if (b[0] != 'B') { if (b[10] != 'D') {
while (1); while (1);
} }
// free(b); free(a);
// b = NULL; // b = NULL;
// if (b[0] == 'B') { // if (b[0] == 'B') {
// while (1); // while (1);
// } // }
char * __capability c = malloc(16); // char * __capability c = malloc(16);
// if (c[0] != 'B') { // if (c[0] != 'B') {
// while (1); // while (1);

View File

@@ -32,6 +32,23 @@ void tiny_free(void*);
// void * __capability next; // void * __capability next;
// } free_node_t; // } free_node_t;
static uintptr_t next_virtual = 0x10000000;
uintptr_t compute_physical_base(size_t size) {
// 1. Determine the required alignment for this size in CHERI
size_t mask = cheri_representable_alignment_mask(size);
// 2. Round up the current next_virtual to the required alignment
uintptr_t base = (next_virtual + ~mask) & mask;
// 3. Ensure the length itself is representable
size_t representable_len = cheri_representable_length(size);
// 4. Update the global pointer for the next call
next_virtual = base + representable_len;
return base;
}
// Add delta value for TLB translation // Add delta value for TLB translation
@@ -51,46 +68,66 @@ static inline void * __capability add_delta(void * __capability cap, int offset)
// Malloc wrapper // Malloc wrapper
// Malloc wrapper
// void * __capability malloc(size_t size) {
// uintptr_t raw = (uintptr_t)tiny_malloc(size);
// // void *__capability cap = (void *__capability)raw;
// void *__capability cap = cheri_ddc_get();
// // // Set address from raw pointer
// cap = cheri_address_set(cap, raw);
// int delta = 12;
// delta = (delta + ALIGN - 1) & ~(ALIGN - 1);
// cap = add_delta(cap, delta);
// size_t aligned = cheri_representable_length(size);
// cap = cheri_bounds_set(cap, aligned);
// // // Align to 8 bytes (important for capability safety)
// // size = (size + 7) & ~7;
// // if (bump + size > HEAP_SIZE)
// // return NULL;
// // void * __capability base = cheri_ddc_get();
// // uintptr_t addr = (uintptr_t)(heap + bump);
// // // Create capability to this region
// // void * __capability cap = cheri_address_set(base, addr);
// // // Enforce bounds (this is the key CHERI feature)
// // cap = cheri_bounds_set(cap, size);
// // // Hard-coded delta value
// // cap = add_delta(cap, 10);
// // bump += size;
// return cap;
// }
void * __capability malloc(size_t size) { void * __capability malloc(size_t size) {
void * phys_ptr = tiny_malloc(size);
if (!phys_ptr) return NULL;
uintptr_t raw = (uintptr_t)tiny_malloc(size); uintptr_t raw_phys = (uintptr_t)phys_ptr;
intptr_t p_base = compute_physical_base(size);
intptr_t delta = p_base - (intptr_t)raw_phys;
// void *__capability cap = (void *__capability)raw; void * __capability cap = cheri_ddc_get();
void *__capability cap = cheri_ddc_get(); cap = cheri_address_set(cap, raw_phys);
// // Set address from raw pointer cap = add_delta(cap, (int)delta);
cap = cheri_address_set(cap, raw);
int delta = 12; size_t aligned_size = cheri_representable_length(size);
cap = cheri_bounds_set(cap, aligned_size);
delta = (delta + ALIGN - 1) & ~(ALIGN - 1);
cap = add_delta(cap, delta);
size_t aligned = cheri_representable_length(size);
cap = cheri_bounds_set(cap, aligned);
// // Align to 8 bytes (important for capability safety)
// size = (size + 7) & ~7;
// if (bump + size > HEAP_SIZE)
// return NULL;
// void * __capability base = cheri_ddc_get();
// uintptr_t addr = (uintptr_t)(heap + bump);
// // Create capability to this region
// void * __capability cap = cheri_address_set(base, addr);
// // Enforce bounds (this is the key CHERI feature)
// cap = cheri_bounds_set(cap, size);
// // Hard-coded delta value
// cap = add_delta(cap, 10);
// bump += size;
return cap; return cap;
} }

View File

@@ -0,0 +1,97 @@
#include <stdint.h>
#include <stddef.h>
#define HEAP_SIZE 0x10000
extern uint8_t __malloc_start;
static uint8_t* heap = &__malloc_start;
typedef struct block {
size_t size;
int free;
struct block* next;
} block;
static block* free_list;
static intptr_t next_virtual = 0x10000000;
intptr_t compute_virtual_base() {
intptr_t v = next_virtual;
next_virtual += 0x1000; // or size
return v;
}
void mem_init() {
free_list = (block*)heap;
free_list->size = HEAP_SIZE - sizeof(block);
free_list->free = 1;
free_list->next = NULL;
}
void* my_malloc(size_t size) {
block* curr = free_list;
while (curr) {
if (curr->free && curr->size >= size) {
if (curr->size > size + sizeof(block)) {
block* newb =
(block*)((uint8_t*)curr + sizeof(block) + size);
newb->size = curr->size - size - sizeof(block);
newb->free = 1;
newb->next = curr->next;
curr->next = newb;
curr->size = size;
}
curr->free = 0;
// TODO: lift off delta to a earlier stage
void* phys = (uint8_t*)curr + sizeof(block);
// compute delta for this allocation
intptr_t delta = compute_virtual_base() - (intptr_t)phys;
// apply hardware instruction assumption:
asm volatile("add_delta %0, %0, %1"
: "+r"(phys)
: "r"(delta));
return phys;
}
curr = curr->next;
}
return NULL;
}
void my_free(void* ptr) {
if (!ptr) return;
// delta is guaranteed 0 → treat pointer as physical
block* b = (block*)((uint8_t*)ptr - sizeof(block));
b->free = 1;
// coalesce adjacent free blocks (pure physical heap logic)
block* curr = free_list;
while (curr && curr->next) {
if (curr->free && curr->next->free) {
curr->size += sizeof(block) + curr->next->size;
curr->next = curr->next->next;
} else {
curr = curr->next;
}
}
}

Binary file not shown.

View File

@@ -0,0 +1 @@
*.txt

File diff suppressed because it is too large Load Diff