online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> /* Constants */ #define ARRAY_SIZE 128 #define GEN_BITS 6 #define INDEX_BITS 7 #define MAX_PID ((1 << (GEN_BITS + INDEX_BITS)) - 1) /* Macros to pack and unpack PIDs */ #define PID_TO_INDEX(pid) ((pid) & ((1 << INDEX_BITS) - 1)) #define PID_TO_GEN(pid) ((pid) >> INDEX_BITS) #define MAKE_PID(gen, index) (((gen) << INDEX_BITS) | (index)) struct procinfo { const char *name; /* In reality, we'd store other information here */ }; struct pid_entry { /* Information we need to make the table work */ unsigned short generation; bool is_free; /* Information we want to store */ struct procinfo info; }; struct pid_array { struct pid_entry processes[ARRAY_SIZE]; int last_allocated; }; /* We only have the one, so it's fine to make it global */ static struct pid_array pid_array; /* Allocate a PID for a process with the given name. */ unsigned int pid_alloc(const char *name) { int start = pid_array.last_allocated + 1; for (int i = 0; i < ARRAY_SIZE; i++) { int index = (start + i) % ARRAY_SIZE; if (pid_array.processes[index].is_free) { pid_array.processes[index].is_free = false; unsigned int pid = MAKE_PID( pid_array.processes[index].generation, index); pid_array.last_allocated = index; pid_array.processes[index].info.name = name; return pid; } } return MAX_PID + 1; // Error: no free PIDs } /* Free a PID. */ void pid_free(unsigned int pid) { unsigned int index = PID_TO_INDEX(pid); unsigned int generation = PID_TO_GEN(pid); if (index < ARRAY_SIZE && pid_array.processes[index].generation == generation && !pid_array.processes[index].is_free) { pid_array.processes[index].is_free = true; pid_array.processes[index].generation = (generation + 1) & ((1 << GEN_BITS) - 1); } } /* Get the process information for a PID. */ struct procinfo * pid_to_info(unsigned int pid) { unsigned int index = PID_TO_INDEX(pid); unsigned int generation = PID_TO_GEN(pid); if (index < ARRAY_SIZE && pid_array.processes[index].generation == generation && !pid_array.processes[index].is_free) { return &pid_array.processes[index].info; } return NULL; } /* Initialize the PID array. */ void pid_array_bootstrap(void) { for (int i = 0; i < ARRAY_SIZE; i++) { pid_array.processes[i].is_free = true; pid_array.processes[i].generation = 0; } pid_array.last_allocated = 0; } /* Test the PID allocator. */ int main(void) { pid_array_bootstrap(); printf("Allocating three PIDs\n"); unsigned int pid1 = pid_alloc("Alice"); unsigned int pid2 = pid_alloc("Betty"); unsigned int pid3 = pid_alloc("Chloe"); printf("\nProcess names:\n"); printf("PID %u: %s\n", pid1, pid_to_info(pid1)->name); printf("PID %u: %s\n", pid2, pid_to_info(pid2)->name); printf("PID %u: %s\n", pid3, pid_to_info(pid3)->name); pid_free(pid2); printf("\nFreed PID %u\n", pid2); /* Churn through 125 more PIDs to get to where we finally reuse an array * slot, but not a PID. */ printf("\nChurning through more PIDs\n"); for (int i = 0; i < 125; i++) { unsigned int pid = pid_alloc("Zarek"); pid_free(pid); } unsigned int pid4 = pid_alloc("Diane"); printf("Allocated new process with PID: %u\n", pid4); printf("PID %u: %s (actually in slot %u)\n", pid4, pid_to_info(pid4)->name, PID_TO_INDEX(pid4)); pid_free(pid1); printf("\nFreed PID %u\n", pid1); /* Churn through 127+62*128 = 8062 more PIDs, calculated get to where we * finally reuse PID 1 */ printf("\nChurning through *LOTS* more PIDs\n"); for (int i = 0; i < 8063; i++) { unsigned int pid = pid_alloc("Yanni"); pid_free(pid); } unsigned int pid5 = pid_alloc("Ellen"); printf("Allocated new process with PID: %u\n", pid5); printf("PID %u: %s\n", pid5, pid_to_info(pid5)->name); return 0; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue