diff --git a/bitset2.c b/bitset2.c new file mode 100644 index 0000000..212fcbe --- /dev/null +++ b/bitset2.c @@ -0,0 +1,15 @@ +#include +#include + +#define BITSET_WORD_BITS (sizeof(bitset_word_t) * 8U) +#define BITSET_WORD(idx) ((uintptr_t *)(bits))[(idx) / BITSET_WORD_BITS] +#define BITSET_MASK(idx) ((uintptr_t)1 << ((idx) % BITSET_WORD_BITS)) + +#define BITSET_SET(bits, idx) (BITSET_WORD(idx) |= BITSET_MASK(idx)) +#define BITSET_CLEAR(bits, idx) (BITSET_WORD(idx) &= ~BITSET_MASK(idx)) +#define BITSET_FLIP(bits, idx) (BITSET_WORD(idx) ^= BITSET_MASK(idx)) +#define BITSET_TEST(bits, idx) (!!((BITSET_WORD(idx) & BITSET_MASK(idx)))) /* forces 0/1 */ +// #define BITSET_PUT(bits, idx, v) do { if (v) BITSET_SET(bits,idx); else BITSET_CLEAR(bits,idx); } while(0) +int main(void) { + return 0; +} diff --git a/dijk.c b/dijk.c new file mode 100644 index 0000000..c89f579 --- /dev/null +++ b/dijk.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: MIT */ + +/* + * Imbus 2025 + * + * PQ-less dijkstra in quadratic complexity + */ + +#include +#include + +#define DIM 26 + +#define A 0 +#define B 1 +#define C 2 +#define D 3 +#define E 4 +#define F 5 +#define G 6 +#define H 7 +#define I 8 +#define J 9 +#define K 10 +#define L 11 +#define M 12 +#define N 13 +#define O 14 +#define P 15 +#define Q 16 +#define R 17 +#define S 18 +#define T 19 +#define U 20 +#define V 21 +#define W 22 +#define X 23 +#define Y 24 +#define Z 25 + +/* Node to character */ +#define ntoch(n) ('A' + (char)(n % 26)) + +/* Some helpers */ +#define set_dist(from, to, d) g[((int)from)][((int)to)] = (int)d +#define get_dist(from, to) g[((int)from)][((int)to)] + +/* Adjacency matrix */ +int g[DIM][DIM] = {}; + +void printmat(int mat[DIM][DIM]) { + printf("## "); + for (int h = 0; h < DIM; h++) printf("%c ", ntoch(h)); + printf("\n"); + printf(" "); + for (int h = 0; h < DIM; h++) printf("%s", "__"); + printf("\n"); + for (int i = 0; i < DIM; i++) { + printf("%c |", ntoch(i)); + for (int j = 0; j < DIM; j++) { + printf("%c ", ntoch(mat[i][j])); + } + printf("\n"); + } +} + +void dijkstra(int mat[DIM][DIM], int prev[DIM], int dist[DIM], int s) { + int visited[DIM] = {0}; + + for (int i = 0; i < DIM; i++) { + dist[i] = INT_MAX; + prev[i] = -1; + } + + dist[s] = 0; + prev[s] = 0; + + for (int i = 0; i < DIM; i++) { + // Pick first unvisited with smallest dist + int u = -1; + int min = INT_MAX; + + for (int j = 0; j < DIM; j++) { + if (!visited[j] && dist[j] < min) { + min = dist[j]; + u = j; + } + } + + if (u == -1) + break; + visited[u] = 1; + + for (int v = 0; v < DIM; v++) { + if (get_dist(u, v) > 0 && !visited[v]) { + if (dist[u] + get_dist(u, v) < dist[v]) { + dist[v] = dist[u] + get_dist(u, v); + prev[v] = u; + } + } + } + } +} + +void path_reconstruct(int prev[DIM], int dist[DIM], int s, int t) { + if (dist[t] == INT_MAX) { + printf("No path from %c to %c\n", ntoch(s), ntoch(t)); + return; + } + + int path[DIM]; + int len = 0; + + // Walk backwards from target to source + for (int v = t; v != -1; v = prev[v]) { + path[len++] = v; + if (v == s) + break; + } + + if (path[len - 1] != s) { + printf("No path from %c to %c\n", ntoch(s), ntoch(t)); + return; + } + + // Print path in correct order + printf("Path (cost %d): ", dist[t]); + for (int i = len - 1; i >= 0; i--) { + printf("%c", ntoch(path[i])); + if (i > 0) + printf(" -> "); + } + printf("\n"); +} + +void init_graph(void) { + set_dist(A, B, 4); + set_dist(A, C, 9); + set_dist(B, D, 2); + set_dist(B, E, 5); + set_dist(C, B, 2); + set_dist(C, F, 7); + set_dist(D, C, 1); + set_dist(E, C, 2); + set_dist(F, G, 3); + set_dist(G, H, 6); + set_dist(H, I, 1); + set_dist(I, J, 8); + set_dist(J, K, 4); + set_dist(K, L, 5); + set_dist(L, M, 2); + set_dist(M, N, 3); + set_dist(N, O, 7); + set_dist(O, P, 1); + set_dist(P, Q, 2); + set_dist(Q, R, 6); + set_dist(R, S, 3); + set_dist(S, T, 5); + set_dist(T, U, 2); + set_dist(U, V, 1); + set_dist(V, W, 4); + set_dist(W, X, 7); + set_dist(X, Y, 2); + set_dist(Y, Z, 3); + set_dist(Z, A, 8); +} + +int main(void) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + g[i][j] = -1; + } + } + + init_graph(); + + printmat(g); + + int prev[DIM] = {0}; + int dist[DIM] = {0}; + dijkstra(g, prev, dist, A); + + for (int k = 0; k < DIM; k++) { + printf("%c prev: %c\n", ntoch(k), ntoch(prev[k])); + } + + path_reconstruct(prev, dist, A, Z); +} diff --git a/interfaces.c b/interfaces.c new file mode 100644 index 0000000..b1a915a --- /dev/null +++ b/interfaces.c @@ -0,0 +1,70 @@ +#include +#include + +// Here's a basic interface for geometric shapes. +typedef struct { + double (*area)(void *); + double (*perim)(void *); +} geometry; + +// For our example we'll implement this interface on +// `rect` and `circle` types. +typedef struct { + double width, height; +} rect; + +typedef struct { + double radius; +} circle; + +// To implement an interface in C, we need to define functions +// that match the function pointers in the interface. +// Here we implement `geometry` on `rect`s. +double rect_area(void *r) { + rect *rect_ptr = (rect *)r; + return rect_ptr->width * rect_ptr->height; +} + +double rect_perim(void *r) { + rect *rect_ptr = (rect *)r; + return 2 * rect_ptr->width + 2 * rect_ptr->height; +} + +// The implementation for `circle`s. +double circle_area(void *c) { + circle *circle_ptr = (circle *)c; + return M_PI * circle_ptr->radius * circle_ptr->radius; +} + +double circle_perim(void *c) { + circle *circle_ptr = (circle *)c; + return 2 * M_PI * circle_ptr->radius; +} + +// If a variable has an interface type, then we can call +// methods that are in the named interface. Here's a +// generic `measure` function taking advantage of this +// to work on any `geometry`. +void measure(void *g, geometry *geom) { + printf("Area: %f\n", geom->area(g)); + printf("Perimeter: %f\n", geom->perim(g)); +} + +int main() { + rect r = {.width = 3, .height = 4}; + circle c = {.radius = 5}; + + // The `circle` and `rect` struct types both + // implement the `geometry` interface so we can use + // instances of these structs as arguments to `measure`. + geometry rect_geometry = {rect_area, rect_perim}; + geometry circle_geometry = {circle_area, circle_perim}; + + printf("Rectangle:\n"); + measure(&r, &rect_geometry); + + printf("\nCircle:\n"); + measure(&c, &circle_geometry); + + return 0; +} diff --git a/riscv-vm.c b/riscv-vm.c new file mode 100644 index 0000000..d3f9eec --- /dev/null +++ b/riscv-vm.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#define PPN_MASK (UINT64_MAX >> 20) + +#define PPN_TO_PA(PPN) ((PPN & PPN_MASK) << 12) +#define PA_TO_PPN(PA) (PA >> 12) + +#define ALIGN_UP(n, align) (((n) + (align) - 1) & ~((align) - 1)) +#define ALIGN_DOWN(n, align) ((n) & ~((align) - 1)) + +#define IS_ALIGNED(x, align) (((uintptr_t)(x) & ((uintptr_t)(align) - 1)) == 0) +#define IS_ALIGNED_ANY(x, align) (((uintptr_t)(x) % (uintptr_t)(align)) == 0) + +#define IS_POWER_OF_TWO(x) (((x) != 0) && (((x) & ((x) - 1)) == 0)) +#define IS_ALIGNED_POW2(x, align) \ + (assert(IS_POWER_OF_TWO((uintptr_t)(align))), (((uintptr_t)(x) & ((uintptr_t)(align) - 1)) == 0)) + +#define VM_MODE_SV39 (2 << 64) + +#define PTE_V (1 << 0) +#define PTE_R (1 << 1) +#define PTE_W (1 << 2) +#define PTE_X (1 << 3) +/* And so on... */ + +#define IS_LEAF(PTE) ((PTE & (PTE_R | PTE_W | PTE_X)) != 0) + +#define PTE_PPN(PTE, LEVEL) (((PTE) >> (10 + ((LEVEL) * 9)) & 0x1FF)) + +int main(void) { + assert(IS_ALIGNED(0, 1)); + assert(IS_ALIGNED(8, 8)); + assert(IS_ALIGNED(12, 4)); + assert(!IS_ALIGNED(66, 16)); + assert(!IS_ALIGNED(234, 4096)); + assert(!IS_ALIGNED(4099, 4096)); + + assert(PPN_MASK == 0b11111111111111111111111111111111111111111111); + assert(PPN_MASK == 17592186044415); + assert(PPN_MASK == 0xFFFFFFFFFFF); + + printf("%lu", PPN_TO_PA(0xAAAAAA)); + assert(IS_ALIGNED(PPN_TO_PA(0xAAAAAAAAAAAA), 4096)); + + uint64_t pte = 0b11111111110000000001111111110000000001111111111; + + assert(pte & PTE_V); + assert(pte & PTE_R); + assert(pte & PTE_W); + assert(pte & PTE_X); + + assert(IS_LEAF(pte)); + + assert(PTE_PPN(pte, 0) == 0); + assert(PTE_PPN(pte, 1) == 0b111111111); + assert(PTE_PPN(pte, 2) == 0); + pte <<= 9; + assert(PTE_PPN(pte, 0) == 0b111111111); + assert(PTE_PPN(pte, 1) == 0); + assert(PTE_PPN(pte, 2) == 0b111111111); + + assert(!IS_LEAF(pte)); // Rightmost bits are now shifted out + +} diff --git a/socket_inet/Makefile b/socket_inet/Makefile new file mode 100644 index 0000000..cd2294a --- /dev/null +++ b/socket_inet/Makefile @@ -0,0 +1,19 @@ +CC ?= gcc +CFLAGS ?= -Wall -g + +all: server.elf client.elf + +server.elf: server.c +client.elf: client.c + +%.elf: %.c + @echo CC $@ + @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test: all + bash test.sh + +clean: + rm -f *.elf *.o + +.PHONY: test clean diff --git a/socket_inet/client.c b/socket_inet/client.c new file mode 100644 index 0000000..287ab6f --- /dev/null +++ b/socket_inet/client.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX 80 +#define PORT 8080 + +void func(int sockfd) { + char buff[MAX]; + + for (;;) { + char *msg = "Ping\n"; + write(sockfd, msg, sizeof(buff)); + + bzero(buff, sizeof(buff)); + read(sockfd, buff, sizeof(buff)); + + printf("From Server : %s", buff); + if ((strncmp(buff, "exit", 4)) == 0) { + printf("Client Exit...\n"); + break; + } + + exit(0); + } +} + +int main() { + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + exit(0); + } + printf("Socket successfully created..\n"); + + struct sockaddr_in servaddr; + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + servaddr.sin_port = htons(PORT); + + if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { + printf("connection with the server failed...\n"); + exit(0); + } + + func(sockfd); + close(sockfd); +} diff --git a/socket_inet/server.c b/socket_inet/server.c new file mode 100644 index 0000000..7bfb2fe --- /dev/null +++ b/socket_inet/server.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX 80 +#define PORT 8080 + +void func(int connfd) { + char buff[MAX]; + + for (;;) { + bzero(buff, MAX); + + ssize_t recv_n = recv(connfd, buff, sizeof(buff), 0); + if (recv_n >= MAX) { + /* Likely more data, realloc */ + } + + buff[recv_n - 1] = '\0'; + printf("From client: %s\n", buff); + bzero(buff, MAX); + + char *msg = "Hello!\n"; + send(connfd, msg, strlen(msg), 0); + + if (strncmp("exit", buff, 4) == 0) { + printf("Server Exit...\n"); + break; + } + } +} + +int main() { + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + exit(0); + } + + struct sockaddr_in servaddr; + bzero(&servaddr, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(PORT); + + if ((bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) != 0) { + printf("socket bind failed...\n"); + exit(0); + } + + if ((listen(sockfd, 5)) != 0) { + printf("Listen failed...\n"); + exit(0); + } + + struct sockaddr_in cli; + socklen_t len = sizeof(cli); + + int connfd = accept(sockfd, (struct sockaddr *)&cli, &len); + if (connfd < 0) { + printf("server accept failed...\n"); + exit(0); + } + + func(connfd); + close(sockfd); +} diff --git a/socket_inet/socket.c b/socket_inet/socket.c new file mode 100644 index 0000000..9115379 --- /dev/null +++ b/socket_inet/socket.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include + +#define SOCKET_PATH "/tmp/demosocket" +#define BUF_SIZE 128 + +int main(void) { + int server_fd, client_fd; + struct sockaddr_un addr; + char buf[BUF_SIZE]; + + // Clean up any leftover socket file + unlink(SOCKET_PATH); + + // Create socket + server_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (server_fd == -1) { + perror("socket"); + exit(EXIT_FAILURE); + } + + // Zero out and set up the address structure + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); + + // Bind the socket to the path + if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + perror("bind"); + close(server_fd); + exit(EXIT_FAILURE); + } + + // Listen for a connection + if (listen(server_fd, 1) == -1) { + perror("listen"); + close(server_fd); + exit(EXIT_FAILURE); + } + + printf("Server listening on %s...\n", SOCKET_PATH); + + // Accept a connection + client_fd = accept(server_fd, NULL, NULL); + if (client_fd == -1) { + perror("accept"); + close(server_fd); + exit(EXIT_FAILURE); + } + + // Receive a message + ssize_t received = recv(client_fd, buf, BUF_SIZE - 1, 0); + if (received > 0) { + buf[received] = '\0'; + printf("Received: %s", buf); + + // Send a reply + const char *reply = "Got your message!\n"; + send(client_fd, reply, strlen(reply), 0); + } else { + perror("recv"); + } + + // Clean up + close(client_fd); + close(server_fd); + unlink(SOCKET_PATH); + return 0; +} diff --git a/socket_inet/test.sh b/socket_inet/test.sh new file mode 100644 index 0000000..acb788e --- /dev/null +++ b/socket_inet/test.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +SOCKET_PATH="/tmp/demosocket" + +# Cleanup function to be run on exit +cleanup() { + echo "Cleaning up..." + if [[ -n "$SERVER_PID" ]]; then + kill "$SERVER_PID" 2>/dev/null || true + wait "$SERVER_PID" 2>/dev/null || true + fi + rm -f "$SOCKET_PATH" +} + +# Trap EXIT to ensure cleanup runs +trap cleanup EXIT + +echo "Starting server..." +./server.elf & +SERVER_PID=$! + +# Wait briefly for the server to start +sleep 0.2 + +echo "Running client..." +./client.elf