diff --git a/Lab2/Makefile b/Lab2/Makefile new file mode 100644 index 0000000..14c9f31 --- /dev/null +++ b/Lab2/Makefile @@ -0,0 +1,10 @@ +all: main.o factorial.o readline.o + gcc main.o factorial.o readline.o -o myfactorial -lgmp +main.o: main.c factorial.h readline.h + gcc -c main.c +factorial.o: factorial.c factorial.h + gcc -c factorial.c +readline.o: readline.c readline.h + gcc -c readline.c +clean: + rm -f *.o myfactorial diff --git a/Lab2/factorial.c b/Lab2/factorial.c new file mode 100644 index 0000000..d42d3a1 --- /dev/null +++ b/Lab2/factorial.c @@ -0,0 +1,16 @@ +#include "gmp.h" +#include "factorial.h" +#include +#include + +char *factorial(const int aNumber) { + int i; + mpz_t p; + mpz_init_set_ui(p, 1); + for (int i = 1; i <= aNumber; ++i) { + mpz_mul_ui(p, p, i); + } + char * ret = mpz_get_str(NULL, 10, p); + mpz_clear(p); + return ret; +} diff --git a/Lab2/factorial.c~ b/Lab2/factorial.c~ new file mode 100644 index 0000000..d42d3a1 --- /dev/null +++ b/Lab2/factorial.c~ @@ -0,0 +1,16 @@ +#include "gmp.h" +#include "factorial.h" +#include +#include + +char *factorial(const int aNumber) { + int i; + mpz_t p; + mpz_init_set_ui(p, 1); + for (int i = 1; i <= aNumber; ++i) { + mpz_mul_ui(p, p, i); + } + char * ret = mpz_get_str(NULL, 10, p); + mpz_clear(p); + return ret; +} diff --git a/Lab2/factorial.h b/Lab2/factorial.h new file mode 100644 index 0000000..ef64ffa --- /dev/null +++ b/Lab2/factorial.h @@ -0,0 +1,6 @@ +#ifndef FACTORIAL_H +#define FACTORIAL_H + +char *factorial(const int aNumber); + +#endif diff --git a/Lab2/main.c~ b/Lab2/main.c~ new file mode 100644 index 0000000..609a017 --- /dev/null +++ b/Lab2/main.c~ @@ -0,0 +1,28 @@ +#include +#include +#include "readline.h" +#include "factorial.h" + +int main(int argc, char *argv[]) { + char *str = (char *) malloc(51); + int t = 0, + i = 0; + scanf("%d\n", &t); + while (i < t) { + if (read_line(str)) { + int a = atoi(str); + char *str = factorial(a); + if (t != NULL) { + puts(t); + free(t); + } else { + printf("Overflow!\n"); + } + } else { + printf("%d\n", -1); + } + ++i; + } + free(str); + return 0; +} diff --git a/Lab2/readline.c b/Lab2/readline.c new file mode 100644 index 0000000..adf0f0e --- /dev/null +++ b/Lab2/readline.c @@ -0,0 +1,17 @@ +#include "readline.h" +#include +#include +#include + +int read_line(char *str) { + fgets(str, 51, stdin); + fputs(str, stdout); + int i = 0; + while (str[i] != '\n') { + if (!isdigit(str[i])) { + return 0; + } + ++i; + } + return 1; +} diff --git a/Lab2/readline.h b/Lab2/readline.h new file mode 100644 index 0000000..660ac9b --- /dev/null +++ b/Lab2/readline.h @@ -0,0 +1,6 @@ +#ifndef READ_LINE_H +#define READ_LINE_H + +int read_line(char *str); + +#endif diff --git a/Lab3/Makefile b/Lab3/Makefile new file mode 100644 index 0000000..19675a4 --- /dev/null +++ b/Lab3/Makefile @@ -0,0 +1,9 @@ +all: ex1.o ex2.o + gcc ex1.o -o ex1 -lgmp + gcc ex2.o -o ex2 +ex1.o: ex1.c + gcc -c ex1.c +ex2.o: ex2.c + gcc -c ex2.c +clean: + rm -f *.o ex1 ex2 diff --git a/Lab3/[L06]-Nguyen Minh Tien-1713484-Lab3.zip b/Lab3/[L06]-Nguyen Minh Tien-1713484-Lab3.zip new file mode 100644 index 0000000..38e3274 Binary files /dev/null and b/Lab3/[L06]-Nguyen Minh Tien-1713484-Lab3.zip differ diff --git a/Lab3/ex1 b/Lab3/ex1 new file mode 100644 index 0000000..00cd2c0 Binary files /dev/null and b/Lab3/ex1 differ diff --git a/Lab3/ex1.c b/Lab3/ex1.c new file mode 100644 index 0000000..1cb0e55 --- /dev/null +++ b/Lab3/ex1.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include + +#define FILE_NAME "numbers.txt" +#define MAX_SIZE 10 + +mpz_t array[MAX_SIZE]; +int size = 0; + +void readfile() { + FILE *file; + char str[80]; + mpz_t temp; + mpz_init(temp); + file = fopen(FILE_NAME, "r"); + if (file == NULL) { + perror("Can't open file!\n"); + exit(1); + } + while (1) { + fgets(str, 80, file); + if (feof(file)) { + break; + } + if (mpz_set_str(temp, str, 10)) { + perror("Error! Not a number"); + exit(1); + } + mpz_set(array[size++], temp); + } + mpz_clear(temp); + fclose(file); +} + +void count(int n) { + int count = 0; + mpz_t temp; + mpz_init(temp); + for (int i = 0; i < size; ++i) { + mpz_mod_ui(temp, array[i], n); + if (!mpz_cmp_ui(temp, 0)) { + ++count; + } + } + printf("Co %d so chia het cho %d.\n", count, n); + mpz_clear(temp); +} + +int main() { + int child1_pid = 0, + child2_pid = 0, + child3_pid = 0, + parrent_pid = getpid(); + readfile(); + child1_pid = fork(); + if (child1_pid < 0) { + perror("Error at 1st pork()!\n"); + exit(1); + } else if (child1_pid == 0) { + count(2); + } + if (parrent_pid == getpid()) { + child2_pid = fork(); + if (child2_pid < 0) { + perror("Error at 2nd pork()!\n"); + exit(1); + } else if (child2_pid == 0) { + count(3); + } + } + if (parrent_pid == getpid()) { + child3_pid = fork(); + if (child3_pid < 0) { + perror("Error at 3rd pork()!\n"); + exit(1); + } else if (child3_pid == 0) { + count(5); + } + } + return 0; +} diff --git a/Lab3/ex1.o b/Lab3/ex1.o new file mode 100644 index 0000000..280ba85 Binary files /dev/null and b/Lab3/ex1.o differ diff --git a/Lab3/ex2 b/Lab3/ex2 new file mode 100644 index 0000000..099aeaa Binary files /dev/null and b/Lab3/ex2 differ diff --git a/Lab3/ex2.o b/Lab3/ex2.o new file mode 100644 index 0000000..1ce65a3 Binary files /dev/null and b/Lab3/ex2.o differ diff --git a/Lab3/numbers(1).docx b/Lab3/numbers(1).docx new file mode 100644 index 0000000..1c673bb Binary files /dev/null and b/Lab3/numbers(1).docx differ diff --git a/Lab3/numbers.docx b/Lab3/numbers.docx new file mode 100644 index 0000000..1ef76bd Binary files /dev/null and b/Lab3/numbers.docx differ diff --git a/Lab3/numbers.txt~ b/Lab3/numbers.txt~ new file mode 100644 index 0000000..81c1773 --- /dev/null +++ b/Lab3/numbers.txt~ @@ -0,0 +1,9 @@ +12918237493729473291790579217597 +4213412542666666666666665 +321456765 +4432524352352365 +106235754869 +11356243645879870 +345943809680943809584352245 +jweois +209345790jdsljflks diff --git a/Lab4/Makefile b/Lab4/Makefile new file mode 100644 index 0000000..6e416d6 --- /dev/null +++ b/Lab4/Makefile @@ -0,0 +1,8 @@ +all: main.o ex1.o + gcc main.o ex1.o -o ex1 -lm +main.o: main.c ex1.h + gcc -c main.c +ex1.o: ex1.c ex1.h + gcc -c ex1.c +clean: + rm -f *.o ex1 diff --git a/Lab4/ex1.c b/Lab4/ex1.c new file mode 100644 index 0000000..3b2b0b5 --- /dev/null +++ b/Lab4/ex1.c @@ -0,0 +1,94 @@ +#include "ex1.h" + +/* Tim block trong dau tien co size thich hop */ +blk *find_fit(unsigned int size) +{ + blk *cur = head; + while (cur != NULL) + { + if (cur->is_free == 1 && cur->size >= size) + break; + cur = cur->next; + } + return cur; +} + +void *aligned_malloc(unsigned int size, unsigned int align) +{ + if (size == 0) + return NULL; + /* Kiem tra align la so mu cua 2 */ + if (IS_POWER_OF_2(align) == 0) + return NULL; + /* Tong gia tri do lon cua block can xin */ + unsigned int total_size = size + align - 1 + sizeof(blk) + sizeof(blk *); + /* Tim block trong thich hop (neu co) */ + blk *blk_head = find_fit(total_size); + void *ret; + if (blk_head != NULL) + { + /* Gan gia tri "da duoc dung" */ + blk_head->is_free = 0; + /* Tim vi tri tra ve thich hop */ + ret = (void *)(ALIGN(blk_head + sizeof(blk) + sizeof(blk *), align)); + /* Luu con tro den vi tri giu thong tin cua block */ + *(blk **)((size_t)ret - sizeof(blk *)) = blk_head; + return ret; + } + void *block = sbrk(total_size); + if (block == (void *)-1) + return NULL; + /* Vi tri luu thong tin cua block */ + blk_head = block; + blk_head->size = total_size; + blk_head->is_free = 0; + blk_head->next = NULL; + if (head == NULL) + head = blk_head; + if (tail != NULL) + tail->next = blk_head; + tail = blk_head; + /* Tim vi tri tra ve thich hop */ + ret = (void *)(ALIGN(block + sizeof(blk) + sizeof(blk *), align)); + /* Luu con tro den vi tri giu thong tin cua block */ + *(blk **)((size_t)ret - sizeof(blk *)) = blk_head; + return ret; +} + +/* Ham nay khong nhat thiet phai tra ve con tro (void *), tuy nhien em lam theo prototype de bai yeu cau */ +void *aligned_free(void *ptr) +{ + if (ptr == NULL) + return NULL; + /* Tro den vi tri luu thong tin cua block */ + blk *blk_head = *((blk **)((size_t)ptr - sizeof(blk *))); + void *prg_brk = sbrk(0); + /* Neu block nam o sat diem break, (neu co thi block nay phai o tail) */ + if ((size_t)blk_head + blk_head->size == (size_t)prg_brk) + { + if (head == tail) + { + head = NULL; + tail = NULL; + } + else + { + blk *tmp = head; + while (tmp != NULL) + { + if (tmp->next == tail) + { + tmp->next = NULL; + tail = tmp; + } + tmp = tmp->next; + } + } + sbrk(0 - (unsigned int)blk_head->size); + return NULL; + } + /* Neu khong giai phong duoc vung nho, danh dau block la "trong" */ + blk_head->is_free = 1; + /* Tra ve con tro toi vi tri luu thong tin cua block (co the dung de debug) */ + return (void *)blk_head; +} diff --git a/Lab4/ex1.c~ b/Lab4/ex1.c~ new file mode 100644 index 0000000..09dfced --- /dev/null +++ b/Lab4/ex1.c~ @@ -0,0 +1,71 @@ +#include "ex1.h" + +memNode *findFree(size_t size) +{ + memNode *cur = head; + while (cur != NULL) { + if (cur->isFree == 1 && cur->size >= size) + return cur; + cur = cur->next; + } + return NULL; +} + +void *aligned_malloc(unsigned int size, unsigned int align) +{ + if (size == 0) + return NULL; + if (ceil(log2((long)align)) != floor(log2((long)align))) + return NULL; + unsigned int total_size = size + align - 1 + sizeof(memNode); + memNode *header = findFree(total_size); + void *ret = NULL; + if (header != NULL) { + header->isFree = 0; + ret = (void *) (((size_t)header + sizeof(memNode) + align - 1) & ~((size_t) align - 1)); + *((void **)((size_t)ret - sizeof(memNode))) = header; + return ret; + } + void *block = sbrk(total_size); + if (block == (void *) -1) + return NULL; + header = block; + header->size = total_size; + header->block = (size_t)block; + header->isFree = 0; + header->next = NULL; + if (head == NULL) + head = header; + if (tail != NULL) + tail->next = header; + tail = header; + ret = (void *) (((size_t)header + sizeof(memNode) + align - 1) & ~((size_t) align - 1)); + *((void **)((size_t)ret - sizeof(memNode))) = header; + return ret; +} + +void aligned_free(void *ptr) +{ + if (ptr == NULL) + return; + memNode *header = (memNode *)((size_t)ptr - sizeof(memNode)); + void *prgBrk = sbrk(0); + if (header->block + header->size == (size_t)prgBrk) { + if (head == tail) { + head = NULL; + tail = NULL; + } else { + memNode *tmp = head; + while (tmp != NULL) { + if (tmp->next == tail) { + tmp->next = NULL; + tail = tmp; + } + tmp = tmp->next; + } + } + sbrk(0 - (unsigned int)header->size - sizeof(memNode)); + return; + } + header->isFree = 1; +} diff --git a/Lab4/ex1.h b/Lab4/ex1.h new file mode 100644 index 0000000..17cc64f --- /dev/null +++ b/Lab4/ex1.h @@ -0,0 +1,26 @@ +#ifndef EX1_H +#define EX1_H + +#include +#include +#include + +#define ALIGN(size, align) ((((size_t)size) + (align - 1)) & ~((size_t)align - 1)) +#define IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0)) + +struct newStruct +{ + unsigned int size; + unsigned int is_free; + struct newStruct *next; +}; + +typedef struct newStruct blk; + +static blk *head = NULL, *tail = NULL; + +blk *find_fit(unsigned int size); +void *aligned_malloc(unsigned int size, unsigned int align); +void *aligned_free(void *ptr); + +#endif // EX1_H diff --git a/Lab4/ex1.o b/Lab4/ex1.o new file mode 100644 index 0000000..b09740a Binary files /dev/null and b/Lab4/ex1.o differ diff --git a/Lab4/ex1_bak.c b/Lab4/ex1_bak.c new file mode 100644 index 0000000..bed3808 --- /dev/null +++ b/Lab4/ex1_bak.c @@ -0,0 +1,86 @@ +#include "ex1.h" + +/* Tim block trong */ +memNode *findFree(size_t size) +{ + memNode *cur = head; + while (cur != NULL) + { + if (cur->isFree == 1 && cur->size >= size) + return cur; + cur = cur->next; + } + return NULL; +} + +void *aligned_malloc(unsigned int size, unsigned int align) +{ + if (size == 0) + return NULL; + /* Kiem tra so mu cua 2 */ + if (ceil(log2((float)align)) != floor(log2((float)align))) + return NULL; + /* Tong gia tri do lon cua block can xin */ + unsigned int total_size = size + align - 1 + sizeof(memNode); + memNode *header = findFree(total_size); + void *ret = NULL; + if (header != NULL) + { + header->isFree = 0; + ret = (void *)(((size_t)header + sizeof(memNode) + align - 1) & ~((size_t)align - 1)); + *((void **)((size_t)ret - sizeof(memNode))) = header; + return ret; + } + void *block = sbrk(total_size); + if (block == (void *)-1) + return NULL; + header = block; + header->size = total_size; + header->block = (size_t)block; + header->isFree = 0; + header->next = NULL; + if (head == NULL) + head = header; + if (tail != NULL) + tail->next = header; + tail = header; + /* Tim vi tri tra ve thoa man */ + ret = (void *)(((size_t)header + sizeof(memNode) + align - 1) & ~((size_t)align - 1)); + /* Luu tru thong tin block tai khong gian truoc gia tri tra ve */ + *((void **)((size_t)ret - sizeof(memNode))) = header; + return ret; +} + +void aligned_free(void *ptr) +{ + if (ptr == NULL) + return; + /* Lay lai thong tin cua block */ + memNode *header = (memNode *)((size_t)ptr - sizeof(memNode)); + void *prgBrk = sbrk(0); + /* Neu block nam o sat diem break */ + if (header->block + header->size == (size_t)prgBrk) + { + if (head == tail) + { + head = NULL; + tail = NULL; + } + else + { + memNode *tmp = head; + while (tmp != NULL) + { + if (tmp->next == tail) + { + tmp->next = NULL; + tail = tmp; + } + tmp = tmp->next; + } + } + sbrk(0 - (unsigned int)header->size - sizeof(memNode)); + return; + } + header->isFree = 1; +} diff --git a/Lab4/main.c b/Lab4/main.c new file mode 100644 index 0000000..26b2657 --- /dev/null +++ b/Lab4/main.c @@ -0,0 +1,15 @@ +#include "ex1.h" +#include + +int main(int argc, char *argv[]) +{ + printf("PID: %d\n", getpid()); + for (unsigned int align = 2; align <= pow(2, 22); align *= 2) + { + void *p = aligned_malloc(1024, align); + printf("%10d %p %15ld %ld \n", align, p, + (unsigned long)p, ((unsigned long)p) % align); + aligned_free(p); + } + return 0; +} \ No newline at end of file diff --git a/Lab4/main.o b/Lab4/main.o new file mode 100644 index 0000000..a273c87 Binary files /dev/null and b/Lab4/main.o differ diff --git a/Lab5/[L06]-Nguyen Minh Tien-1713484-Lab5.zip b/Lab5/[L06]-Nguyen Minh Tien-1713484-Lab5.zip new file mode 100644 index 0000000..7fc6423 Binary files /dev/null and b/Lab5/[L06]-Nguyen Minh Tien-1713484-Lab5.zip differ diff --git a/Lab5/code.c b/Lab5/code.c new file mode 100644 index 0000000..4fb0afe --- /dev/null +++ b/Lab5/code.c @@ -0,0 +1,18 @@ +#include +#include +void *hello(void *tid) +{ + printf("Hello from thread %ld\n", (long)tid); +} + +int main() +{ + pthread_t tid[10]; + long i; + for (i = 0; i < 10; i++) + { + pthread_create(&tid[i], NULL, hello, (void *)i); + pthread_join(tid[i], NULL); + } + pthread_exit(NULL); +} \ No newline at end of file diff --git a/Lab5/code.o b/Lab5/code.o new file mode 100644 index 0000000..af76dd0 Binary files /dev/null and b/Lab5/code.o differ diff --git a/Lab5/makefile b/Lab5/makefile new file mode 100644 index 0000000..22e7a68 --- /dev/null +++ b/Lab5/makefile @@ -0,0 +1,21 @@ +all: pi_serial.o pi_multi-thread.o code.o + gcc -o pi_serial pi_serial.o + gcc -o pi_multi-thread pi_multi-thread.o -lpthread + gcc -o code code.o -lpthread +pi: pi_serial.o pi_multi-thread.o + gcc -o pi_serial pi_serial.o + gcc -o pi_multi-thread pi_multi-thread.o -lpthread +pi_serial: pi_serial.o + gcc -o pi_serial pi_serial.o +pi_multi-thread: pi_multi-thread.o + gcc -o pi_multi-thread pi_multi-thread.o -lpthread +code: code.o + gcc -o code code.o -lpthread +pi_serial.o: pi_serial.c + gcc -c pi_serial.c +pi_multi-thread.o: pi_multi-thread.c + gcc -c pi_multi-thread.c +code.o: code.c + gcc -c code.c +clean: + rm -rf *.o pi_serial pi_multi-thread code diff --git a/Lab5/pi_multi-thread.o b/Lab5/pi_multi-thread.o new file mode 100644 index 0000000..2e49b58 Binary files /dev/null and b/Lab5/pi_multi-thread.o differ diff --git a/Lab5/pi_serial b/Lab5/pi_serial new file mode 100644 index 0000000..7b1163d Binary files /dev/null and b/Lab5/pi_serial differ diff --git a/Lab5/pi_serial.c b/Lab5/pi_serial.c new file mode 100644 index 0000000..b69784e --- /dev/null +++ b/Lab5/pi_serial.c @@ -0,0 +1,38 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + clock_t t1, t2; + srand(time(NULL)); + double x, y; + int count, nPoints, i; + if (argc != 2) + { + fprintf(stderr, "usage: pi_serial \n"); + return -1; + } + nPoints = atoi(argv[1]); + if (nPoints < 0) + { + fprintf(stderr, "%d must be >= 0\n", nPoints); + return -1; + } + time(&t1); + count = 0; + unsigned int state = rand(); + for (i = 0; i < nPoints; ++i) + { + x = (double)rand_r(&state) / RAND_MAX; + y = (double)rand_r(&state) / RAND_MAX; + if (x * x + y * y - 1 <= 0) + { + ++count; + } + } + time(&t2); + printf("Time to Execute: %lds\n", (t2 - t1)); + printf("PI = %lf\n", 4 * (double)count / nPoints); + return 0; +} \ No newline at end of file diff --git a/Lab6/pi_multi-thread.o b/Lab6/pi_multi-thread.o new file mode 100644 index 0000000..97c427f Binary files /dev/null and b/Lab6/pi_multi-thread.o differ diff --git a/Test/Test.c b/Test/Test.c new file mode 100644 index 0000000..9365b0e --- /dev/null +++ b/Test/Test.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +#define NUM_THREADS 4 + +int n; +pthread_t thdArr[NUM_THREADS]; +pthread_attr_t attr; + +void *runner(void *arg) +{ + long t = (long)arg; + double x, y; + long i, count; + count = 0; + for (i = 0; i < n; ++i) + { + x = ((double)rand() / RAND_MAX); + y = ((double)rand() / RAND_MAX); + if (x * x + y * y - 1 <= 0) + { + ++count; + } + } + pthread_exit((void *)count); +} + +int main(int argc, char *argv[]) +{ + clock_t t1, t2; + srand(time(NULL)); + int count, rc, nPoints; + long t; + if (argc != 2) + { + fprintf(stderr, "usage: pi_multi-thread \n"); + return -1; + } + nPoints = atoi(argv[1]); + if (nPoints <= 0) + { + fprintf(stderr, "%d must be > 0\n", nPoints); + return -1; + } + n = nPoints / NUM_THREADS; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + t1 = clock(); + for (t = 0; t < NUM_THREADS; ++t) + { + rc = pthread_create(&thdArr[t], &attr, runner, (void *)t); + if (rc) + { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + } + count = 0; + for (t = NUM_THREADS; t >= 0; --t) + { + void *ret; + pthread_join(thdArr[t], &ret); + count += (long)ret; + } + t2 = clock(); + printf("Time to Execute: %lf\n", (double)(t2 - t1) / CLOCKS_PER_SEC); + printf("PI = %lf\n", 4 * (double)count / nPoints); + return 0; +} \ No newline at end of file diff --git a/lab7/.vscode/ipch/55ff02b8125cbad4/mmap_address.bin b/lab7/.vscode/ipch/55ff02b8125cbad4/mmap_address.bin new file mode 100644 index 0000000..30a792c Binary files /dev/null and b/lab7/.vscode/ipch/55ff02b8125cbad4/mmap_address.bin differ diff --git a/lab7/.vscode/ipch/55ff02b8125cbad4/queue.ipch b/lab7/.vscode/ipch/55ff02b8125cbad4/queue.ipch new file mode 100644 index 0000000..72bdaaf Binary files /dev/null and b/lab7/.vscode/ipch/55ff02b8125cbad4/queue.ipch differ diff --git a/lab7/.vscode/ipch/f2e166a5537f49e0/sched.ipch b/lab7/.vscode/ipch/f2e166a5537f49e0/sched.ipch new file mode 100644 index 0000000..358fdbc Binary files /dev/null and b/lab7/.vscode/ipch/f2e166a5537f49e0/sched.ipch differ diff --git a/lab7/queue.c b/lab7/queue.c new file mode 100644 index 0000000..22a0b11 --- /dev/null +++ b/lab7/queue.c @@ -0,0 +1,67 @@ + +#include +#include "queue.h" +#include + +/* Remember to initilize the queue before using it */ +void initialize_queue(struct pqueue_t *q) +{ + q->head = q->tail = NULL; + pthread_mutex_init(&q->lock, NULL); +} + +/* Return non-zero if the queue is empty */ +int empty(struct pqueue_t *q) +{ + return (q->head == NULL); +} + +/* Get PCB of a process from the queue (q). + * Return NULL if the queue is empty */ +struct pcb_t *de_queue(struct pqueue_t *q) +{ + struct pcb_t *proc = NULL; + // TODO: return q->head->data and remember to update the queue's head + // and tail if necessary. Remember to use 'lock' to avoid race + // condition + + // YOUR CODE HERE + if (empty(q)) + return NULL; + pthread_mutex_lock(&q->lock); + proc = q->head->data; + struct qitem_t *pdel = q->head; + if (q->head == q->tail) + q->head = q->tail = NULL; + else + q->head = q->head->next; + free(pdel); + pthread_mutex_unlock(&q->lock); + + return proc; +} + +/* Put PCB of a process to the queue. */ +void en_queue(struct pqueue_t *q, struct pcb_t *proc) +{ + // TODO: Update q->tail. + // Remember to use 'lock' to avoid race condition + + // YOUR CODE HERE + pthread_mutex_lock(&q->lock); + struct qitem_t *new_data = malloc(sizeof(struct qitem_t)); + if (new_data == NULL) + return; + new_data->data = proc; + new_data->next = NULL; + if (empty(q)) + { + q->head = q->tail = new_data; + } + else + { + q->tail->next = new_data; + q->tail = q->tail->next; + } + pthread_mutex_unlock(&q->lock); +} diff --git a/lab7/sched b/lab7/sched new file mode 100644 index 0000000..705a82a Binary files /dev/null and b/lab7/sched differ diff --git a/lab7/sched.c b/lab7/sched.c new file mode 100644 index 0000000..ec83ac7 --- /dev/null +++ b/lab7/sched.c @@ -0,0 +1,130 @@ + +#include "queue.h" +#include +#include +#include +#include + +#define TIME_UNIT 100 // In microsecond + +static struct pqueue_t in_queue; // Queue for incomming processes +static struct pqueue_t ready_queue; // Queue for ready processes + +static int load_done = 0; + +static int timeslot; // The maximum amount of time a process is allowed + // to be run on CPU before being swapped out + +// Emulate the CPU +void *cpu(void *arg) +{ + int timestamp = 0; + /* Keep running until we have loaded all process from the input file + * and there is no process in ready queue */ + while (!load_done || !empty(&ready_queue)) + { + /* Pickup the first process from the queue */ + struct pcb_t *proc = de_queue(&ready_queue); + if (proc == NULL) + { + /* If there is no process in the queue then we + * wait until the next time slice */ + timestamp++; + usleep(TIME_UNIT); + } + else + { + /* Execute the process */ + int start = timestamp; // Save timestamp + int id = proc->pid; // and PID for tracking + /* Decide the amount of time that CPU will spend + * on the process and write it to 'exec_time'. + * It should not exeed 'timeslot'. + */ + int exec_time = 0; + + // TODO: Calculate exec_time from process's PCB + + // YOUR CODE HERE + exec_time = (proc->burst_time > 2) ? 2 : proc->burst_time; + + /* Emulate the execution of the process by using + * 'usleep()' function */ + usleep(exec_time * TIME_UNIT); + + /* Update the timestamp */ + timestamp += exec_time; + + // TODO: Check if the process has terminated (i.e. its + // burst time is zero. If so, free its PCB. Otherwise, + // put its PCB back to the queue. + + // YOUR CODE HERE + proc->burst_time -= (timestamp - start); + if (proc->burst_time > 0) + en_queue(&ready_queue, proc); + + /* Track runtime status */ + printf("%2d-%2d: Execute %d\n", start, timestamp, id); + } + } +} + +// Emulate the loader +void *loader(void *arg) +{ + int timestamp = 0; + /* Keep loading new process until the in_queue is empty*/ + while (!empty(&in_queue)) + { + struct pcb_t *proc = de_queue(&in_queue); + /* Loader sleeps until the next process available */ + int wastetime = proc->arrival_time - timestamp; + usleep(wastetime * TIME_UNIT); + /* Update timestamp and put the new process to ready queue */ + timestamp += wastetime; + en_queue(&ready_queue, proc); + } + /* We have no process to load */ + load_done = 1; +} + +/* Read the list of process to be executed from stdin */ +void load_task() +{ + int num_proc = 0; + scanf("%d %d\n", ×lot, &num_proc); + int i; + for (i = 0; i < num_proc; i++) + { + struct pcb_t *proc = + (struct pcb_t *)malloc(sizeof(struct pcb_t)); + scanf("%d %d\n", &proc->arrival_time, &proc->burst_time); + proc->pid = i; + en_queue(&in_queue, proc); + } +} + +int main() +{ + pthread_t cpu_id; // CPU ID + pthread_t loader_id; // LOADER ID + + /* Initialize queues */ + initialize_queue(&in_queue); + initialize_queue(&ready_queue); + + /* Read a list of jobs to be run */ + load_task(); + + /* Start cpu */ + pthread_create(&cpu_id, NULL, cpu, NULL); + /* Start loader */ + pthread_create(&loader_id, NULL, loader, NULL); + + /* Wait for cpu and loader */ + pthread_join(cpu_id, NULL); + pthread_join(loader_id, NULL); + + pthread_exit(NULL); +} diff --git a/lab7/test.sh b/lab7/test.sh new file mode 100644 index 0000000..8fd7b7c --- /dev/null +++ b/lab7/test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo "Input file:" +cat input.txt +echo "Results" +gcc sched.c queue.c -o sched -lpthread +cat input.txt | ./sched diff --git a/lab7_old/.vscode/ipch/13a97e7003756a01/mmap_address.bin b/lab7_old/.vscode/ipch/13a97e7003756a01/mmap_address.bin new file mode 100644 index 0000000..d2ccf0c Binary files /dev/null and b/lab7_old/.vscode/ipch/13a97e7003756a01/mmap_address.bin differ diff --git a/lab7_old/.vscode/ipch/13a97e7003756a01/sched.ipch b/lab7_old/.vscode/ipch/13a97e7003756a01/sched.ipch new file mode 100644 index 0000000..fedaf0b Binary files /dev/null and b/lab7_old/.vscode/ipch/13a97e7003756a01/sched.ipch differ diff --git a/lab7_old/.vscode/ipch/5661da7ee988a7e9/mmap_address.bin b/lab7_old/.vscode/ipch/5661da7ee988a7e9/mmap_address.bin new file mode 100644 index 0000000..26c4b36 Binary files /dev/null and b/lab7_old/.vscode/ipch/5661da7ee988a7e9/mmap_address.bin differ diff --git a/lab7_old/.vscode/ipch/5a5a417a4b857205/mmap_address.bin b/lab7_old/.vscode/ipch/5a5a417a4b857205/mmap_address.bin new file mode 100644 index 0000000..88d63b8 Binary files /dev/null and b/lab7_old/.vscode/ipch/5a5a417a4b857205/mmap_address.bin differ diff --git a/lab7_old/.vscode/ipch/61904e83bd77f3b5/mmap_address.bin b/lab7_old/.vscode/ipch/61904e83bd77f3b5/mmap_address.bin new file mode 100644 index 0000000..1871c6b Binary files /dev/null and b/lab7_old/.vscode/ipch/61904e83bd77f3b5/mmap_address.bin differ diff --git a/lab7_old/.vscode/ipch/f2e166a5537f49e0/mmap_address.bin b/lab7_old/.vscode/ipch/f2e166a5537f49e0/mmap_address.bin new file mode 100644 index 0000000..ae9c0a0 Binary files /dev/null and b/lab7_old/.vscode/ipch/f2e166a5537f49e0/mmap_address.bin differ diff --git a/lab7_old/.vscode/ipch/f2e166a5537f49e0/sched.ipch b/lab7_old/.vscode/ipch/f2e166a5537f49e0/sched.ipch new file mode 100644 index 0000000..2b5c085 Binary files /dev/null and b/lab7_old/.vscode/ipch/f2e166a5537f49e0/sched.ipch differ diff --git a/lab7_old/.vscode/ipch/f2e171a5537f5c91/mmap_address.bin b/lab7_old/.vscode/ipch/f2e171a5537f5c91/mmap_address.bin new file mode 100644 index 0000000..4f4ff90 Binary files /dev/null and b/lab7_old/.vscode/ipch/f2e171a5537f5c91/mmap_address.bin differ diff --git a/lab7_old/.vscode/ipch/f2e171a5537f5c91/sched.ipch b/lab7_old/.vscode/ipch/f2e171a5537f5c91/sched.ipch new file mode 100644 index 0000000..6b0753c Binary files /dev/null and b/lab7_old/.vscode/ipch/f2e171a5537f5c91/sched.ipch differ diff --git a/lab7_old/.vscode/ipch/f4a020768ce7ca5f/mmap_address.bin b/lab7_old/.vscode/ipch/f4a020768ce7ca5f/mmap_address.bin new file mode 100644 index 0000000..80240ae Binary files /dev/null and b/lab7_old/.vscode/ipch/f4a020768ce7ca5f/mmap_address.bin differ diff --git a/lab7_old/queue.h b/lab7_old/queue.h new file mode 100644 index 0000000..36b7a96 --- /dev/null +++ b/lab7_old/queue.h @@ -0,0 +1,11 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include "structs.h" + +void initialize_queue(struct pqueue_t *q); +struct pcb_t *de_queue(struct pqueue_t *q); +void en_queue(struct pqueue_t *q, struct pcb_t *proc); +int empty(struct pqueue_t *q); + +#endif \ No newline at end of file diff --git a/lab7_old/sched.c b/lab7_old/sched.c new file mode 100644 index 0000000..1dea3f0 --- /dev/null +++ b/lab7_old/sched.c @@ -0,0 +1,36 @@ +#include "queue.h" +#include +#include +#include +#include + +#define TIME_UNIT 100 + +static struct pqueue_t in_queue; +static struct pqueue_t ready_queue; + +static int load_done = 0; +static int timeslot; + +void *cpu(void *arg); +void *loader(void *arg); +void load_task(); + +int main() +{ + pthread_t cpu_id; + pthread_t loader_id; + + initialize_queue(&in_queue); + initialize_queue(&ready_queue); + + load_task(); + + pthread_create(&cpu_id, NULL, cpu, NULL); + pthread_create(&loader_id, NULL, loader, NULL); + + pthread_join(cpu_id, NULL); + pthread_join(loader_id, NULL); + + pthread_exit(NULL); +} diff --git a/lab7_old/sched.o b/lab7_old/sched.o new file mode 100644 index 0000000..c55f92d Binary files /dev/null and b/lab7_old/sched.o differ