Trish @trish0x2a.bsky.social · 31/08/2026github.com/TrisH0x2A/pl...github.comGitHub - TrisH0x2A/plynk: Fast, offline brutalist Kanban & Whiteboard desktop workspaceFast, offline brutalist Kanban & Whiteboard desktop workspace - TrisH0x2A/plynk 010
Trish @trish0x2a.bsky.social · 31/08/2026i built Plynk because i wanted a productivity app that doesn't need a server to work a fast local-first Kanban + infinite whiteboard desktop app Tauri + Rust + React + TypeScript + SQLite everything stays on your machine — boards, cards, whiteboards, activity logs, backups 120
Trish @trish0x2a.bsky.social · 30/08/2026Kanban boards + a built-in whiteboard for planning, organizing, and visualizing your work. Fast, offline, and available on Windows, Linux & macOS github.com/Trish0x2A/pl...github.comGitHub - TrisH0x2A/plynk: Fast, offline brutalist Kanban & Whiteboard desktop workspaceFast, offline brutalist Kanban & Whiteboard desktop workspace - TrisH0x2A/plynk 000
Trish @trish0x2a.bsky.social · 28/08/2026github.com/TrisH0x2A/pl...github.comGitHub - TrisH0x2A/plynk: Fast, offline brutalist Kanban desktop workspaceFast, offline brutalist Kanban desktop workspace. Contribute to TrisH0x2A/plynk development by creating an account on GitHub. 000
Trish @trish0x2a.bsky.social · 09/05/2026Memory Allocators 101 - Write a simple memory allocator This article is about writing a simple memory allocator in C. You will implement malloc(), calloc(), realloc() and free() 100
Trish @trish0x2a.bsky.social · 09/05/2026and that's it! a simple asteroid dodging game. controls are 'a' for left, 'd' for right. the game gets pretty intense when multiple asteroids are falling! compile with: gcc asteroid_game.c -o asteroid_game github - github.com/dexter-xD/pr... 010
Trish @trish0x2a.bsky.social · 09/05/202610/ finally, checking for collisions and updating the score. Game ends if you hit an asteroid: 100
Trish @trish0x2a.bsky.social · 09/05/20269/ spawning new asteroids randomly (10% chance each frame) and handling player input: 100
Trish @trish0x2a.bsky.social · 09/05/20268/ moving asteroids and cleaning up ones that hit the bottom. had to be careful with the array manipulation here: 100
Trish @trish0x2a.bsky.social · 09/05/20267/ drawing the game field - nested loops to check each position for ship ('O') or asteroids ('*'): 100
Trish @trish0x2a.bsky.social · 09/05/20266/ the main game loop is where it gets interesting. we clear the screen, show the score, and draw everything: 100
Trish @trish0x2a.bsky.social · 09/05/20265/ collision detection is simple - just check if the ship and asteroid are at the same position: 110
Trish @trish0x2a.bsky.social · 09/05/20264/ moving right is similar, just checking the other boundary: 100
Trish @trish0x2a.bsky.social · 09/05/20263/ our ship starts at the bottom center and can move left/right. added boundary checking so it doesn't go off-screen: 100
Trish @trish0x2a.bsky.social · 09/05/20262/ creating asteroids is straightforward - they spawn randomly at the top and fall down. the srand() call seeds our random number generator: 100
Trish @trish0x2a.bsky.social · 09/05/20261/ first, let's set up our basic structures. we need points for positions and separate structs for our ship and asteroids: 100
Trish @trish0x2a.bsky.social · 09/05/2026if you've ever wanted to build a game but thought it was too complicated -> you haven't tried making one in terminal yet here's how to build an addictive asteroid dodger in C from 100
Trish @trish0x2a.bsky.social · 06/05/2026the linux kernel's min() macro is one of the most carefully engineered macros ever written standard C's #define min(a,b) ((a)<(b)?(a):(b)) evaluates a or b TWICE and if you pass min(x++, y) you get a double increment the kernel uses a GCC extension: statement expressions. 100
Trish @trish0x2a.bsky.social · 06/05/2026NULL is a billion dollar mistake but at least it's honest. JavaScript's undefined is a billion dollar lie. 020
Trish @trish0x2a.bsky.social · 06/05/2026C still supports the original 1972 function syntax without proper type checking on parameters K&R style: name the params in the signature and declare their types separately below. calls without a prototype can bypass full type checking the CPU just gets whatever bytes you pass. it's removed in C23 000
Trish @trish0x2a.bsky.social · 05/05/2026the reason LD_PRELOAD works is basically this you load a .so into the process, its constructors fire before main, and by the time your code runs the symbols are already replaced. that's how you intercept malloc, open, read and anything in libc without touching the binary 000
Trish @trish0x2a.bsky.social · 05/05/2026and destructor priorities work in reverse, higher number runs first on teardown, it's symmetric on purpose 100
Trish @trish0x2a.bsky.social · 05/05/2026the priority number is what makes it actually useful lower number runs first, so if two libraries both register constructors, the one with priority 101 runs before 102 glibc reserves everything below 100 for itself you're not supposed to touch those 100
Trish @trish0x2a.bsky.social · 05/05/2026gcc lets you run code before main() even starts __attribute__((constructor)) marks a function to execute at load time __attribute__((destructor)) runs after main() returns this is how shared libraries initialize themselves when you dlopen() them 100
Trish @trish0x2a.bsky.social · 05/05/2026the linux kernel embeds structs inside other structs and navigates between them using pointer math. you have a pointer to a member and you want the parent struct, therefore subtract the member's byte offset from the address and you're there this is container_of, heavily used in the linux kernel 010
Trish @trish0x2a.bsky.social · 05/05/2026the classic XOR swap is broken on modern CPUs. it's slower, and if both operands refer to the same memory it corrupts the value. __typeof__ + a temp is the right way. it works for any type, evaluates once and the compiler typically eliminates the temp entirely. 000
Trish @trish0x2a.bsky.social · 04/05/2026remember when 512MB RAM felt like a lot? people actually cared about memory back then. you tried not to waste it. now it’s just “eh, we have more RAM”. 32GB machines and apps still manage to feel heavy. feels like we stopped caring somewhere along the way. hardware improved but habits didn’t. 120
Trish @trish0x2a.bsky.social · 04/05/2026the math is simple: (count + 7) / 8 rounds up the number of iterations. count % 8 decides where to enter. if count is 11, it starts at case 3, copies 3 items, then continues processing full chunks of 8 until don 000
Trish @trish0x2a.bsky.social · 04/05/2026the trick is combining loop unrolling with C fallthrough semantics. instead of a separate loop for leftovers, Duff jumps straight into the middle of the unrolled loop using a switch 100
Trish @trish0x2a.bsky.social · 04/05/2026in 1983 a Lucasfilm engineer discovered you can legally interleave a switch and a do-while in C it's called Duff's Device. it still compiles and technically valid C Tom Duff's own words: "it amazes me that after 10 years of writing C there are still corners I haven't fully explored." 110
Trish @trish0x2a.bsky.social · 02/05/2026the cleanest way to implement a ring buffer in C without malloc, dynamic sizing or locks if you have one reader and one writer 010
Trish @trish0x2a.bsky.social · 01/05/2026xor linked list is one of those things that looks super smart instead of storing prev and next, you just store prev ^ next, so yeah you save one pointer per node but now moving forward needs the previous node every time, you can’t just go to next directly 010
Trish @trish0x2a.bsky.social · 01/05/2026i know there’s neovim, emacs, vscode and all, they’re great but i keep coming back to clion and intellij idea especially intellij for java, it just feels right 000
Trish @trish0x2a.bsky.social · 01/05/2026developers will spend $3000 on a MacBook but refuse to pay $200/year for an IDE that makes them 10x more productive 010
Trish @trish0x2a.bsky.social · 30/04/2026unpopular opinion: the more you rely on ai the less you think slowly making yourself dumb 000
Trish @trish0x2a.bsky.social · 29/04/2026what this allocator is still missing 1. malloc should return pointers aligned for any built-in type (up to 8 bytes in C) 2. reuse only the space you need 3. adjacent free blocks should coalesce this is ~100 lines. real allocators like dlmalloc, tcmalloc, and jemalloc solve all of this and more. 000
Trish @trish0x2a.bsky.social · 29/04/2026realloc and calloc round it out: calloc is just malloc + memset. realloc mallocs a new block, copies old data, frees the old one. 100
Trish @trish0x2a.bsky.social · 29/04/2026now free. to get back to the metadata struct from a user pointer: free doesn't return memory to the OS. it just flips the flag. the block stays in the linked list, available for the next malloc call. during development, without those asserts, there was a bug that would've caused data corruption. 100
Trish @trish0x2a.bsky.social · 29/04/2026now the full malloc: block+1 isn't adding 1 byte. it adds sizeof(struct block_meta) bytes. pointer arithmetic. 100
Trish @trish0x2a.bsky.social · 29/04/2026no free block found? ask the OS for more heap via request_space(): 100
Trish @trish0x2a.bsky.social · 29/04/2026we keep a global linked list of all blocks, and a global base pointer: void *global_base = NULL; when malloc is called, first we walk this list looking for a free block big enough to reuse. if we find one that's great. if not then we grow the heap. this is find_free_block(): 100
Trish @trish0x2a.bsky.social · 29/04/2026to support free(), you need to track metadata per block. the trick: stash it just below the pointer you return. caller never sees it. so when you ask for 0x400 bytes, malloc actually calls sbrk(0x400 + META_SIZE) and returns a pointer past the struct. the struct is hidden right before it. 100
Trish @trish0x2a.bsky.social · 29/04/2026the dumbest possible malloc: this works. it actually allocates memory. but you can't free anything. every call eats more heap forever. we need to do better. 100
Trish @trish0x2a.bsky.social · 29/04/2026malloc's job is simple: void *malloc(size_t size); takes a byte count, returns a pointer to a block of that size. the OS gives your process a heap and sbrk() lets you grow it. sbrk(0) → current top of heap sbrk(n) → grows heap by n bytes, returns old top 110
Trish @trish0x2a.bsky.social · 29/04/2026malloc(size) takes a byte count and returns a pointer to a block of that size. that's it. one function. but to implement it you need to understand how the OS hands out memory, how to track free blocks, and how to inject your code into any binary without recompiling it. let's build it from scratch 100
Trish @trish0x2a.bsky.social · 28/04/2026your C code goes through a pipeline preprocess compile assemble link execute learn this flow once and C starts making real sense 000
Trish @trish0x2a.bsky.social · 28/04/2026the 4 rules to not embarrass yourself with file I/O in C: 1. always check if fopen() returned NULL 2. match the mode to your intent ("w" wipes, "a" doesn't) 3. use stderr for errors, not stdout 4. always fclose() every open handle is a resource 010
Trish @trish0x2a.bsky.social · 28/04/2026here's a real example: read names from a file, write greetings to another. feof() tells you if you hit end of file always close your handles leaked file descriptors are a real problem under load 110