diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ce94c57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Created by https://www.toptal.com/developers/gitignore/api/c +# Edit at https://www.toptal.com/developers/gitignore?templates=c + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# User specific +/kernel-sign + +# End of https://www.toptal.com/developers/gitignore/api/c diff --git a/bitmap.c b/bitmap.c new file mode 100644 index 0000000..c738724 --- /dev/null +++ b/bitmap.c @@ -0,0 +1,85 @@ +#include "bitmap.h" +#include +#include + +#ifdef bitmap_64 +#define bitmap_type unsigned long long int +#define bitmap_shift 6 +#define bitmap_mask 63 +#define bitmap_wordlength 64 +#define bitmap_fmt "%016llx" +#else // assumed to be 32 bits +#define bitmap_type unsigned int +#define bitmap_shift 5 +#define bitmap_mask 31 +#define bitmap_wordlength 32 +#define bitmap_fmt "%08x" +#endif + +// get the types right +#define bitmap_one (bitmap_type)1 + +// we expect 0 <= n and n < b->bits, but it is not verified + +// arch a 8 bit +// bitmap shift 3 +// wordlength 8 + +// n = 10 -> 00001010 +// 00000001 -> word = 1 +// +// n = 12 -> 00001100 +// mask = 7 -> 00000111 +// 00000100 = 4 +// 00000001 -> word = 1 +// +// n = 32 -> 00100000 +// mask = 7 -> 00000111 +// 00000000 +// 00000100 -> word = 4 +// +// n = 127 -> 01111111 +// mask = 7 -> 00000111 +// position = 7 -> 00000111 +// + +void bitmap_set(bitmap *b, int n) { + int word = n >> bitmap_shift; // n / bitmap_wordlength + int position = n & bitmap_mask; // n % bitmap_wordlength + b->array[word] |= bitmap_one << position; +} + +void bitmap_clear(bitmap *b, int n) { + int word = n >> bitmap_shift; // n / bitmap_wordlength + int position = n & bitmap_mask; // n % bitmap_wordlength + b->array[word] &= ~(bitmap_one << position); +} + +int bitmap_read(bitmap *b, int n) { + int word = n >> bitmap_shift; // n / bitmap_wordlength + int position = n & bitmap_mask; // n % bitmap_wordlength + return (b->array[word] >> position) & 1; +} + +bitmap *bitmap_allocate(int bits) { + // error-checking should be better :-) + bitmap *b = malloc(sizeof(bitmap)); + b->bits = bits; + b->words = (bits + bitmap_wordlength - 1) / bitmap_wordlength; + // divide, but round up for the ceiling + b->array = calloc(b->words, sizeof(bitmap_type)); + return b; +} + +void bitmap_deallocate(bitmap *b) { + // error-checking should be better :-) + free(b->array); + free(b); +} + +void bitmap_print(bitmap *b) { + for (int i = 0; i < b->words; i++) { + printf(" " bitmap_fmt, b->array[i]); + } + printf("\n"); +} diff --git a/bitmap.h b/bitmap.h new file mode 100644 index 0000000..7b4d45d --- /dev/null +++ b/bitmap.h @@ -0,0 +1,22 @@ +// use dynamic allocation with these functions +// compile with -Dbitmap_64 to force 64-bit words +// compile with -O [dash capital o] for more efficient machine code + +#ifdef bitmap_64 +#define bitmap_type unsigned long long int +#else // assumed to be 32 bits +#define bitmap_type unsigned int +#endif + +typedef struct { + int bits; // number of bits in the array + int words; // number of words in the array + bitmap_type *array; +} bitmap; + +void bitmap_set(bitmap *b, int n); // n is a bit index +void bitmap_clear(bitmap *b, int n); +int bitmap_read(bitmap *b, int n); +bitmap *bitmap_allocate(int bits); +void bitmap_deallocate(bitmap *b); +void bitmap_print(bitmap *b); diff --git a/collatz.c b/collatz.c new file mode 100644 index 0000000..d04276b --- /dev/null +++ b/collatz.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +int collatz(int, int[], int); +void print_buffer(int buff[]); + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("Usage: collatz NUMBER\n"); + return EXIT_FAILURE; + } + + int n = atoi(argv[1]); + if (n <= 1) { + perror("The number MUST be greater than 1\n"); + return EXIT_FAILURE; + } + + printf("Collatz of %d\n", n); + + pid_t pid = fork(); + if (pid == 0) { + int buff[1024] = {0}; + collatz(n, buff, 0); + print_buffer(buff); + } else if (pid > 0) { + wait(NULL); + } + + return EXIT_SUCCESS; +} + +int collatz(int n, int buff[], int steps) { + buff[steps] = n; + if (n == 1) { + return n; + } else if (n % 2 == 0) { + return collatz(n / 2, buff, steps + 1); + } else { + return collatz(3 * n + 1, buff, steps + 1); + } +} + +void print_buffer(int buff[]) { + int i = 0; + while (buff[i] != 0) { + printf("%d ", buff[i]); + i++; + } + printf("\n"); +} diff --git a/collatz_shm.c b/collatz_shm.c new file mode 100644 index 0000000..0528c72 --- /dev/null +++ b/collatz_shm.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SIZE 4096 +#define SHM_NAME "collatz" + +int collatz(int, void *); + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("Usage: collatz NUMBER\n"); + return EXIT_FAILURE; + } + + int n = atoi(argv[1]); + if (n <= 1) { + perror("The number MUST be greater than 1\n"); + return EXIT_FAILURE; + } + + printf("Collatz of %d\n", n); + + // Create memory shared object + int fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0600); + ftruncate(fd, SIZE); + void *ptr = (int *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + pid_t pid = fork(); + if (pid == 0) { + collatz(n, ptr); + } else if (pid > 0) { + wait(NULL); + + printf("%s\n", (char *)ptr); + shm_unlink(SHM_NAME); + } + + return EXIT_SUCCESS; +} + +int collatz(int n, void *shm) { + char buff[50]; + sprintf(buff, "%d", n); + sprintf(shm, "%s", buff); + shm += strlen(buff); + + sprintf(shm, "%s", " "); + shm += 1; + + if (n == 1) { + return n; + } else if (n % 2 == 0) { + return collatz(n / 2, shm); + } else { + return collatz(3 * n + 1, shm); + } +} diff --git a/collatz_shm2.c b/collatz_shm2.c new file mode 100644 index 0000000..dfef3ef --- /dev/null +++ b/collatz_shm2.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int collatz(int, int *, int); +void print_buffer(int buff[]); + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("Usage: collatz NUMBER\n"); + return EXIT_FAILURE; + } + + int n = atoi(argv[1]); + if (n <= 1) { + perror("The number MUST be greater than 1\n"); + return EXIT_FAILURE; + } + + printf("Collatz of %d\n", n); + + int *buff = mmap(NULL, sizeof(int *) * 1024, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + + pid_t pid = fork(); + if (pid == 0) { + collatz(n, buff, 0); + } else if (pid > 0) { + wait(NULL); + print_buffer(buff); + } + + return EXIT_SUCCESS; +} + +int collatz(int n, int *shm, int steps) { + *(shm + steps) = n; + if (n == 1) { + return n; + } else if (n % 2 == 0) { + return collatz(n / 2, shm, steps + 1); + } else { + return collatz(3 * n + 1, shm, steps + 1); + } +} + +void print_buffer(int buff[]) { + int i = 0; + while (buff[i] != 0) { + printf("%d ", buff[i]); + i++; + } + printf("\n"); +} diff --git a/cons.c b/cons.c new file mode 100644 index 0000000..409b1b8 --- /dev/null +++ b/cons.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + const int SIZE = 4096; + const char *name = "OS"; + + int shm_fd; + void *ptr; + + shm_fd = shm_open(name, O_RDONLY, 0666); + ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); + printf("%s", (char *)ptr); + shm_unlink(name); +} diff --git a/ex1.c b/ex1.c new file mode 100644 index 0000000..9015b9c --- /dev/null +++ b/ex1.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +struct MyStruct { + int value; +}; + +int value = 5; + +int main(void) +{ + struct MyStruct *str; + str->value = 5; + + int *p = malloc(sizeof(int)); + *p = 100; + + printf("PARENT: %p\n", &value); + printf("PARENT: %p\n", str); + printf("PARENT: %p\n", p); + + pid_t pid; + pid = fork(); + + if (pid == 0) { + value += 15; + str->value += 15; + *p += 10; + printf("CHILD: %p, %d\n", &value, value); + printf("CHILD: %p, %d\n", &str->value, str->value); + printf("CHILD: %p, %d\n", p, *p); + return 0; + } else if (pid > 0) { + wait(NULL); + printf("PARENT: value = %d\n", value); + printf("PARENT: value = %d\n", str->value); + printf("PARENT: value = %d\n", *p); + + free(p); + + return 0; + } +} diff --git a/ex12.c b/ex12.c new file mode 100644 index 0000000..96a6ea3 --- /dev/null +++ b/ex12.c @@ -0,0 +1,39 @@ +#include +#include +#include + +void add_children(pid_t children[], pid_t pid); + +int main(void) +{ + pid_t parent_pid = getpid(); + pid_t children[1024] = {-1}; + for (int i = 0; i < 4; i++) { + pid_t pid = fork(); + add_children(children, pid); + } + + if (parent_pid = getpid()) { + wait(NULL); + printf("pids: "); + for (int i = 0; i < 1024; i++) { + if (children[i] == -1) { + printf("\n"); + break; + } + printf("%d ", children[i]); + } + } + + return 0; +} + +void add_children(pid_t children[], pid_t pid) +{ + for (int i = 0; i < 1024; i++) { + if (children[i] < 0) { + children[i] = pid; + break; + } + } +} diff --git a/ex13.c b/ex13.c new file mode 100644 index 0000000..25d804a --- /dev/null +++ b/ex13.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +int main(void) +{ + pid_t pid; + pid = fork(); + + if (pid < 0) { + fprintf(stderr, "Fork failed\n"); + return 1; + } else if (pid == 0) { + execlp("/bin/ls", "ls", NULL); + printf("LINEA J\n"); + } else { + wait(NULL); + printf("Child complete\n"); + } + + return 0; +} diff --git a/ex14.c b/ex14.c new file mode 100644 index 0000000..2e10389 --- /dev/null +++ b/ex14.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +int main(void) { + pid_t pid, pid1; + + pid = fork(); + + if (pid < 0) { + fprintf(stderr, "Fork failed"); + return EXIT_FAILURE; + } else if (pid == 0) { + pid1 = getpid(); + printf("child: pid = %d\n", pid); // A + printf("child: pid1 = %d\n", pid1); // B + } else { + pid1 = getpid(); + printf("parent: pid = %d\n", pid); // C + printf("parent: pid1 = %d\n", pid1); // D + wait(NULL); + } + + return EXIT_SUCCESS; +} diff --git a/ex17.c b/ex17.c new file mode 100644 index 0000000..4e0d87d --- /dev/null +++ b/ex17.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#define SIZE 5 + +int nums[SIZE] = {0, 1, 2, 3, 4}; + +int main(void) { + int i; + pid_t pid; + + pid = fork(); + + if (pid == 0) { + for (i = 0; i < SIZE; i++) { + nums[i] *= -i; + printf("CHILD : %d\n", nums[i]); // Linea X + } + } else if (pid > 0) { + wait(NULL); + for (i = 0; i < SIZE; i++) { + printf("PARENT: %d\n", nums[i]); // Linea Y + } + } + + return EXIT_SUCCESS; +} diff --git a/ex19.c b/ex19.c new file mode 100644 index 0000000..6def429 --- /dev/null +++ b/ex19.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +int main(void) { + pid_t parent_pid = getpid(); + pid_t pid = fork(); + + if (pid > 0) { + printf("PARENT PID = %d, CHILD PID = %d\n", parent_pid, pid); + sleep(10); + wait(NULL); + } + + return EXIT_SUCCESS; +} diff --git a/pid_manager.c b/pid_manager.c new file mode 100644 index 0000000..bd21294 --- /dev/null +++ b/pid_manager.c @@ -0,0 +1,63 @@ +#include "pid_manager.h" +#include +#include +#include + +#define MIN_PID 300 +#define MAX_PID 5000 +#define SIZE (MAX_PID - MIN_PID + 1) + +bool pids[SIZE]; + +int allocate_map(void) { + for (int i = 0; i < SIZE; i++) { + pids[i] = false; + } + return 1; +} + +int allocate_pid(void) { + for (int i = 0; i < SIZE; i++) { + if (!pids[i]) { + pids[i] = true; + return i + MIN_PID; + } + } + return -1; +} + +void release_pid(int pid) { + if (pid >= MIN_PID && pid <= MAX_PID) { + pids[pid - MIN_PID] = false; + } +} + +int main(void) { + if (allocate_map() != 1) { + perror("Failed to initialiaze PID Manager\n"); + exit(1); + } + + for (int i = 0; i < SIZE; i++) { + printf("Allocate PID = %d\n", allocate_pid()); + } + + int last = allocate_pid(); + printf("Attempt to allocate another PID, result %d\n", last); + + if (last == -1) { + printf("Release a PID 4000\n"); + release_pid(4000); + } + + printf("Allocate another PID: %d\n", allocate_pid()); + + printf("Release PIDs 300 and 5000\n"); + release_pid(300); + release_pid(5000); + + printf("Allocate another PID: %d\n", allocate_pid()); + printf("Allocate another PID: %d\n", allocate_pid()); + + return 0; +} diff --git a/pid_manager.h b/pid_manager.h new file mode 100644 index 0000000..a8011f8 --- /dev/null +++ b/pid_manager.h @@ -0,0 +1,15 @@ +#if !defined(__PID_MANGER_H__) +#define __PID_MANGER_H__ + +// Crea e inizializza una struttura per rappresentare i pid; +// restituisce -1 in caso di insuccesso e 1 in caso di successo. +int allocate_map(void); + +// Alloca e restituisce un pid, restituisce -1 se non รจ possibile +// assegnare un PID (tutti i pid sono in uso). +int allocate_pid(void); + +// Rilascia un pid +void release_pid(int pid); + +#endif diff --git a/prod.c b/prod.c new file mode 100644 index 0000000..181a349 --- /dev/null +++ b/prod.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + const int SIZE = 4096; + const char *name = "OS"; + const char *message_0 = "Hello"; + const char *message_1 = "World!"; + + int shm_fd; + void *ptr; + + shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); + ftruncate(shm_fd, SIZE); + ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); + sprintf(ptr, "%s", message_0); + ptr += strlen(message_0); + sprintf(ptr, "%s", " "); + ptr += 1; + sprintf(ptr, "%s", message_1); + ptr += strlen(message_1); + + return 0; +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..8ec4683 --- /dev/null +++ b/test.c @@ -0,0 +1,7 @@ +#include + +int main(void) { + int n; + printf("%d\n", n); + return 0; +}