├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── sysopy.iml └── vcs.xml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── kolos2 └── cheatsheet2.c ├── zestaw1 ├── zad1 │ ├── library.c │ ├── library.h │ └── makefile ├── zad2 │ ├── library.c │ ├── library.h │ ├── main.c │ └── makefile ├── zad3a │ ├── library.c │ ├── library.h │ ├── main.c │ ├── main_dynamic.c │ └── makefile └── zad3b │ ├── library.c │ ├── library.h │ ├── main.c │ ├── main_dynamic.c │ └── makefile ├── zestaw2 ├── zad1 │ ├── main.c │ ├── makefile │ ├── osx_tests │ ├── ubuntu_tests.txt │ └── wyniki.txt └── zad2 │ └── main.c ├── zestaw3 ├── zad1 │ └── main.c ├── zad2 │ ├── breaker.c │ ├── main.c │ └── sample └── zad3 │ ├── big_cpu.c │ ├── big_data.c │ ├── breaker.c │ ├── main.c │ ├── makefile │ └── sample ├── zestaw4 ├── zad1 │ ├── dater.sh │ ├── main.c │ └── main_2.c ├── zad2 │ ├── child.c │ ├── main.c │ └── makefile └── zad3 │ └── main.c ├── zestaw5 ├── zad1 │ ├── main.c │ └── sample └── zad2 │ ├── Makefile │ ├── main.c │ ├── master.c │ └── slave.c ├── zestaw6 ├── zad1 │ ├── Makefile │ ├── client.c │ ├── communication.h │ └── server.c └── zad2 │ ├── Makefile │ ├── client.c │ ├── communication.h │ └── server.c ├── zestaw7 ├── zad1 │ ├── Makefile │ ├── barber.c │ ├── handler_of_clients.c │ └── shared_utils.h └── zad2 │ ├── Makefile │ ├── barber.c │ ├── handler_of_clients.c │ └── shared_utils.h ├── zestaw8 ├── edge_detection.txt ├── elephant.txt ├── jablko.jpeg ├── jablko.pgm ├── jablko_1.pgm ├── jablko_2.pgm ├── jablko_4.pgm ├── jablko_8.pgm ├── main.c ├── makefile ├── melon.jpeg ├── melon.pgm ├── melon_1.pgm ├── melon_2.pgm ├── melon_4.pgm ├── melon_8.pgm └── time_res.txt └── zestaw9 ├── zad1 ├── Pan_Tadeusz.txt ├── config ├── main.c └── makefile └── zad2 ├── Pan_Tadeusz.txt ├── config ├── main.c └── makefile /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 45 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/sysopy.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | project(sysopy) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | add_executable(sysopy 7 | zestaw1/zad1/library.c 8 | zestaw1/zad1/library.h 9 | zestaw1/zad2/library.c 10 | zestaw1/zad2/library.h 11 | zestaw1/zad2/main.c 12 | zestaw1/zad3a/library.c 13 | zestaw1/zad3a/library.h 14 | zestaw1/zad3a/main.c 15 | zestaw1/zad3a/main_dynamic.c 16 | zestaw1/zad3b/library.c 17 | zestaw1/zad3b/library.h 18 | zestaw1/zad3b/main.c 19 | zestaw1/zad3b/main_dynamic.c 20 | zestaw2/zad1/main.c 21 | zestaw2/zad2/main.c 22 | zestaw3/zad1/main.c 23 | zestaw3/zad2/main.c 24 | zestaw3/zad3/big_cpu.c 25 | zestaw3/zad3/big_data.c 26 | zestaw3/zad3/main.c zestaw4/zad3/main.c 27 | zestaw5/zad1/main.c 28 | zestaw5/zad2/master.c 29 | zestaw5/zad2/slave.c 30 | zestaw7/zad1/barber.c 31 | zestaw7/zad1/handler_of_clients.c 32 | zestaw7/zad1/shared_utils.h 33 | zestaw7/zad2/barber.c 34 | zestaw7/zad2/handler_of_clients.c 35 | zestaw7/zad2/shared_utils.h 36 | zestaw8/main.c 37 | zestaw9/zad1/main.c 38 | zestaw9/zad2/main.c 39 | 40 | 41 | kolos2/cheatsheet2.c) 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Giant Penis License (GPL) 2 | Copyright (c) osdnk 2k18-present 3 | 4 | ▄▄██▄██▄▄ 5 | ▄█ █ █▄ 6 | ▄█ █▄ 7 | █ █ 8 | █ █ 9 | █ █ 10 | █ █ 11 | █ █ 12 | █▄ █ ▄█ 13 | █ ▄▄▄ █ 14 | █ █ 15 | █ █ 16 | █ █ 17 | █ █ 18 | █ █ 19 | █ █ 20 | █ █ 21 | █ █ 22 | █ █ 23 | █ █ 24 | █ █ 25 | █ █ 26 | ▄████▄█ █▄████▄ 27 | ▄█ █▄ 28 | █ █ 29 | █ █ 30 | █ █ 31 | █ █ 32 | █ ▄▄█▄▄ █ 33 | █ █ █ █ 34 | █▄ ▄█ █▄ ▄█ 35 | █▄▄▄▄▄█ █▄▄▄▄▄█ 36 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy 38 | of this software and associated documentation files (the "Software"), to deal 39 | in the Software without restriction, including without limitation the rights 40 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 41 | copies of the Software, and to permit persons to whom the Software is 42 | furnished to do so, subject to the following conditions: 43 | The above copyright notice and this permission notice shall be included in 44 | all copies or substantial portions of the Software. 45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 51 | THE SOFTWARE. 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sysopy 2 | This special repo is made to provide solutions for SO course 3 | I decided to use commit names in Polish. The reason is a wide range of vulgarisms in this language. I truly believe that names "chuj", "kurwa", "jebać to gówno", "make-kurwa-file" are fairly fine for this stuff and express my emotional involvement 4 | 5 | License 6 | --- 7 | sysopy is currently under [**Giant Penis License (GPL)**](http://giant-penis-license.org) which is a deformed M.I.T license including penis text art. 8 | -------------------------------------------------------------------------------- /kolos2/cheatsheet2.c: -------------------------------------------------------------------------------- 1 | 2 | // kolejki komunikatow 3 | 4 | // System V 5 | 6 | int main() { 7 | key_t publicKey = ftok(path, PROJECT_ID); 8 | if(publicKey == -1) 9 | FAILURE_EXIT("server: generation of publicKey failed\n"); 10 | 11 | int queue_descriptor = msgget(publicKey, IPC_CREAT | IPC_EXCL | 0666); 12 | if(queue_descriptor == -1) 13 | FAILURE_EXIT("server: creation of public queue failed\n"); 14 | 15 | Message buffer; 16 | while(1) { 17 | if (active == 0) { 18 | if (msgctl(queue_descriptor, IPC_STAT, ¤t_state) == -1) 19 | FAILURE_EXIT("server: getting current state of public queue failed\n"); 20 | if (current_state.msg_qnum == 0) break; 21 | } 22 | 23 | if (msgrcv(queue_descriptor, &buffer, MSG_SIZE, 0, 0) < 0) 24 | FAILURE_EXIT("server: receiving message failed\n"); 25 | handle_public_queue(&buffer); 26 | } 27 | 28 | int tmp = msgctl(queue_descriptor, IPC_RMID, NULL); 29 | }; 30 | int sender() { 31 | queue_descriptor = create_queue(path, PROJECT_ID); 32 | 33 | key_t privateKey = ftok(path, getpid()); 34 | if (privateKey == -1) 35 | FAILURE_EXIT("Generation of private key failed"); 36 | 37 | privateID = msgget(privateKey, IPC_CREAT | IPC_EXCL | 0666); 38 | if (privateID == -1) 39 | FAILURE_EXIT("Creation of private queue failed"); 40 | 41 | Message msg; 42 | msg.mtype = LOGIN; 43 | msg.sender_pid = getpid(); 44 | sprintf(msg.message_text, "%d", privateKey); 45 | 46 | if (msgsnd(queue_descriptor, &msg, MSG_SIZE, 0) == -1) 47 | FAILURE_EXIT("client: LOGIN request failed\n"); 48 | if (msgrcv(privateID, &msg, MSG_SIZE, 0, 0) == -1) 49 | FAILURE_EXIT("client: catching LOGIN response failed\n") 50 | } 51 | 52 | // - POSIX 53 | 54 | int main() { 55 | mqd_t queue_descriptor = mq_open(server_path, O_RDONLY | O_CREAT | O_EXCL, 0666, &posix_attr); 56 | 57 | if (queue_descriptor == -1) 58 | FAILURE_EXIT("server: creation of public queue failed\n"); 59 | 60 | Message buffer; 61 | while(1) { 62 | if(active == 0) { 63 | if (mq_getattr(queue_descriptor, ¤t_state) == -1) 64 | FAILURE_EXIT("server: couldnt read public queue parameters\n"); 65 | if (current_state.mq_curmsgs == 0) exit(0); 66 | } 67 | 68 | if (mq_receive(queue_descriptor,(char*) &buffer, MESSAGE_SIZE, NULL) == -1) 69 | FAILURE_EXIT("server: receiving message by server failed\n"); 70 | handle_public_queue(&buffer); 71 | } 72 | mq_close(queue_descriptor); 73 | mq_unlink(server_path); 74 | 75 | }; 76 | 77 | ins sender ( ){ 78 | queue_descriptor = mq_open(server_path, O_WRONLY); 79 | mq_send(queue_descriptor, (char*) &msg, MESSAGE_SIZE, 1); 80 | mq_close(queue_descriptor); 81 | } 82 | 83 | //Shared memory - SYSTEM V 84 | 85 | 86 | struct shared_struct{ 87 | int val; 88 | }; 89 | // server 90 | int main(int argc, char **argv) 91 | { 92 | 93 | if(argc !=2){ 94 | printf("Not a suitable number of program parameters\n"); 95 | return(1); 96 | } 97 | key_t my_key = ftok(SHM_NAME, 4); 98 | int shm_id = shmget(my_key, sizeof(struct shared_struct), IPC_CREAT | S_IRWXU); 99 | struct shared_struct *my_shared = shmat(shm_id, NULL, 0); 100 | my_shared -> val = atoi(argv[1]); 101 | return 0; 102 | } 103 | 104 | //receiver 105 | 106 | int main(int argc, char **argv) 107 | { 108 | 109 | sleep(1); 110 | int val =0; 111 | key_t my_key = ftok(SHM_NAME, 4); 112 | int shm_id = shmget(my_key, 0, 0); 113 | struct shared_struct *got_shared_struct=shmat(shm_id, NULL, 0); 114 | printf("Liczba: %d\n", got_shared_struct -> val); 115 | shmctl(shm_id, IPC_RMID, NULL); 116 | return 0; 117 | } 118 | 119 | 120 | // POSIX 121 | // sender 122 | int main(int argc, char **argv) 123 | { 124 | 125 | if(argc !=2){ 126 | printf("Not a suitable number of program parameters\n"); 127 | return(1); 128 | } 129 | 130 | int fd_shm = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRWXU); 131 | off_t shared_struct_size=sizeof(struct shared_struct); 132 | ftruncate(fd_shm, shared_struct_size); 133 | void* shm_addr = mmap(NULL, shared_struct_size, PROT_WRITE, MAP_SHARED, fd_shm, 0); 134 | struct shared_struct *my_shared = (struct shared_struct *) shm_addr; 135 | my_shared->val=atoi(argv[1]); 136 | sleep(152); 137 | munmap(shm_addr, shared_struct_size); 138 | shm_unlink(SHM_NAME); 139 | 140 | return 0; 141 | } 142 | 143 | // receiver 144 | int main(int argc, char **argv) 145 | { 146 | 147 | sleep(1); 148 | int val =0; 149 | int fd_shm=shm_open(SHM_NAME, O_RDWR, S_IRWXU); 150 | off_t shared_struct_size=sizeof(struct shared_struct); 151 | ftruncate(fd_shm, shared_struct_size); 152 | void* shm_addr = mmap(NULL, shared_struct_size, PROT_WRITE, MAP_SHARED, fd_shm, 0); 153 | struct shared_struct *my_shared = (struct shared_struct*) shm_addr; 154 | printf("My val: %d\n", my_shared->val); 155 | return 0; 156 | } 157 | 158 | 159 | // SEMAFOR - V 160 | 161 | key_t sem_key = ftok(FILE_NAME, 2); 162 | int sem_id = semget(sem_key, 1, IPC_CREAT | S_IRWXU); 163 | union semun sem_info; 164 | sem_info.val =1; 165 | semctl(sem_id, 0, SETVAL, sem_info); 166 | 167 | struct sembuf* sops=malloc(sizeof(struct sembuf)); 168 | sops -> sem_num=0; 169 | sops -> sem_flg=0; 170 | 171 | 172 | sops -> sem_op = -1; 173 | semop(sem_id, sops, 1); 174 | 175 | 176 | sops -> sem_op = 1; 177 | semop(sem_id, sops, 1); 178 | 179 | 180 | 181 | // POSIX 182 | sem_t *my_semaphore=sem_open(SEM_NAME, O_RDWR | O_CREAT, S_IRWXU, 1); 183 | 184 | sem_wait(my_semaphore); 185 | sem_post(my_semaphore)K 186 | 187 | sem_close(my_semaphore); 188 | sem_unlink(SEM_NAME); 189 | 190 | // Wątki 191 | 192 | 193 | int i; 194 | pthread_t arr[n]; 195 | int indexes[n]; 196 | for(i=0; i y) 257 | pthread_cond_broadcast(&cond); 258 | pthread_mutex_unlock(&mutex); 259 | -------------------------------------------------------------------------------- /zestaw1/zad1/library.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #include "library.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | char *global_arr[1000000]; 13 | 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static) { 16 | if (number_of_blocks < 0) { 17 | return NULL; 18 | } 19 | struct wrapped_arr *res = malloc(sizeof(struct wrapped_arr)); 20 | res->number_of_blocks = number_of_blocks; 21 | res->is_static = is_static; 22 | if (is_static) { 23 | res->arr = global_arr; 24 | } else { 25 | char **arr = (char **) calloc(number_of_blocks, sizeof(char *)); 26 | res->arr = arr; 27 | } 28 | return res; 29 | } 30 | 31 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index) { 32 | if (index >= arr->number_of_blocks || index < 0) { 33 | return; 34 | } 35 | arr->arr[index] = calloc(strlen(block), sizeof(char)); 36 | strcpy(arr->arr[index], block); 37 | } 38 | 39 | void delete_block_at_index(struct wrapped_arr *arr, int index) { 40 | if (arr == NULL || arr->arr[index] == NULL) { 41 | return; 42 | } 43 | free(arr->arr[index]); 44 | arr->arr[index] = NULL; 45 | 46 | } 47 | 48 | void delete_array(struct wrapped_arr *arr) { 49 | for (int i = 0; i < arr->number_of_blocks; i++) { 50 | if (arr->arr[i] != NULL) { 51 | free(arr->arr[i]); 52 | } 53 | } 54 | } 55 | 56 | int get_int_block(char *block) { 57 | int res = 0; 58 | int len = strlen(block); 59 | for (int i = 0; i < len; i++) 60 | res += (int) block[i]; 61 | return res; 62 | } 63 | 64 | char *find_closest(struct wrapped_arr *arr, int value) { 65 | char *res = NULL; 66 | int min_diff = INT_MAX; 67 | for (int i = 0; i < arr->number_of_blocks; i++) { 68 | char *block = arr->arr[i]; 69 | if (block != NULL) { 70 | int diff = abs(get_int_block(block) - value); 71 | if (min_diff > diff) { 72 | min_diff = diff; 73 | res = block; 74 | } 75 | } 76 | } 77 | return res; 78 | } 79 | -------------------------------------------------------------------------------- /zestaw1/zad1/library.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #ifndef SYSOPY_LIBRARY_H 6 | #define SYSOPY_LIBRARY_H 7 | 8 | 9 | struct wrapped_arr { 10 | int number_of_blocks; 11 | char **arr; 12 | int is_static; 13 | }; 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static); 16 | 17 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index); 18 | 19 | void delete_block_at_index(struct wrapped_arr *arr, int index); 20 | 21 | void delete_array(struct wrapped_arr *arr); 22 | 23 | char *find_closest(struct wrapped_arr *arr, int value); 24 | 25 | #endif //SYSOPY_LIBRARY_H 26 | -------------------------------------------------------------------------------- /zestaw1/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | 4 | all: static shared clean 5 | 6 | static: 7 | $(CC) -c library.c 8 | ar rcs library.a library.o 9 | 10 | shared: 11 | $(CC) -c -fPIC library.c 12 | $(CC) -shared -fPIC -o library.so library.o 13 | 14 | clean: 15 | rm -f *.o -------------------------------------------------------------------------------- /zestaw1/zad2/library.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #include "library.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | char *global_arr[1000000]; 13 | 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static) { 16 | if (number_of_blocks < 0) { 17 | return NULL; 18 | } 19 | struct wrapped_arr *res = malloc(sizeof(struct wrapped_arr)); 20 | res->number_of_blocks = number_of_blocks; 21 | res->is_static = is_static; 22 | if (is_static) { 23 | res->arr = global_arr; 24 | } else { 25 | char **arr = (char **) calloc(number_of_blocks, sizeof(char *)); 26 | res->arr = arr; 27 | } 28 | return res; 29 | } 30 | 31 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index) { 32 | if (index >= arr->number_of_blocks || index < 0) { 33 | return; 34 | } 35 | arr->arr[index] = calloc(strlen(block), sizeof(char)); 36 | strcpy(arr->arr[index], block); 37 | } 38 | 39 | void delete_block_at_index(struct wrapped_arr *arr, int index) { 40 | if (arr == NULL || arr->arr[index] == NULL) { 41 | return; 42 | } 43 | free(arr->arr[index]); 44 | arr->arr[index] = NULL; 45 | 46 | } 47 | 48 | void delete_array(struct wrapped_arr *arr) { 49 | for (int i = 0; i < arr->number_of_blocks; i++) { 50 | if (arr->arr[i] != NULL) { 51 | free(arr->arr[i]); 52 | } 53 | } 54 | } 55 | 56 | int get_int_block(char *block) { 57 | int res = 0; 58 | int len = strlen(block); 59 | for (int i = 0; i < len; i++) 60 | res += (int) block[i]; 61 | return res; 62 | } 63 | 64 | char *find_closest(struct wrapped_arr *arr, int value) { 65 | char *res = NULL; 66 | int min_diff = INT_MAX; 67 | for (int i = 0; i < arr->number_of_blocks; i++) { 68 | char *block = arr->arr[i]; 69 | if (block != NULL) { 70 | int diff = abs(get_int_block(block) - value); 71 | if (min_diff > diff) { 72 | min_diff = diff; 73 | res = block; 74 | } 75 | } 76 | } 77 | return res; 78 | } 79 | -------------------------------------------------------------------------------- /zestaw1/zad2/library.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #ifndef SYSOPY_LIBRARY_H 6 | #define SYSOPY_LIBRARY_H 7 | 8 | 9 | struct wrapped_arr { 10 | int number_of_blocks; 11 | char **arr; 12 | int is_static; 13 | }; 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static); 16 | 17 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index); 18 | 19 | void delete_block_at_index(struct wrapped_arr *arr, int index); 20 | 21 | void delete_array(struct wrapped_arr *arr); 22 | 23 | char *find_closest(struct wrapped_arr *arr, int value); 24 | 25 | #endif //SYSOPY_LIBRARY_H 26 | -------------------------------------------------------------------------------- /zestaw1/zad2/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 10/03/2018. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "library.h" 12 | 13 | char *generate_random_string(int max_size) { 14 | if (max_size < 1) return NULL; 15 | char *base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 16 | size_t dict_len = strlen(base); 17 | char *res = (char *) malloc((max_size) * sizeof(char)); 18 | 19 | for (int i = 0; i < max_size-1; i++) { 20 | res[i] = base[rand() % dict_len]; 21 | } 22 | res[max_size-1] = '\0'; 23 | 24 | return res; 25 | } 26 | 27 | void fil_array(struct wrapped_arr *arr, int block_size) { 28 | for (int i = 0; i < arr->number_of_blocks; i++) { 29 | char *randomString = generate_random_string(block_size); 30 | add_block_at_index(arr, randomString, i); 31 | 32 | } 33 | } 34 | 35 | void add_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index, int block_size) { 36 | for (int i = 0; i < number; i++) { 37 | char *block = generate_random_string(block_size); 38 | add_block_at_index(arr, block, i + start_index); 39 | } 40 | } 41 | 42 | void remove_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index) { 43 | for (int i = 0; i < number; i++) { 44 | delete_block_at_index(arr, i + start_index); 45 | } 46 | } 47 | 48 | void delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 49 | remove_specific_number_of_blocks(arr, number, 0); 50 | add_specific_number_of_blocks(arr, number, 0, block_size); 51 | } 52 | 53 | void alt_delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 54 | for (int i = 0; i < number; i++) { 55 | delete_block_at_index(arr, i); 56 | add_block_at_index(arr, generate_random_string(block_size), i); 57 | } 58 | } 59 | 60 | double calculate_time(clock_t start, clock_t end) { 61 | return (double) (end - start) / sysconf(_SC_CLK_TCK); 62 | } 63 | 64 | void exec_operation(char *arg, int param, int block_size, struct wrapped_arr *arr) { 65 | 66 | 67 | if (strcmp(arg, "change") == 0) { 68 | delete_then_add(arr, param, block_size); 69 | 70 | } else if (strcmp(arg, "change_alt") == 0) { 71 | alt_delete_then_add(arr, param, block_size); 72 | 73 | } else if (strcmp(arg, "find") == 0) { 74 | find_closest(arr, block_size); 75 | 76 | } else if (strcmp(arg, "remove") == 0) { 77 | delete_array(arr); 78 | } 79 | 80 | } 81 | 82 | int main(int argc, char **argv) { 83 | if (argc < 4) { 84 | printf("Meh, wrong arguments. Give me please: number of blocks, blocksize, mode of alloc and then list of job (max 2)!"); 85 | return 1; 86 | } 87 | srand((unsigned int) time(NULL)); 88 | int array_size = (int) strtol(argv[1], NULL, 10); 89 | int block_size = (int) strtol(argv[2], NULL, 10); 90 | 91 | int is_static; 92 | if (strcmp(argv[3], "dynamic") == 0) { 93 | is_static = 0; 94 | } else if (strcmp(argv[3], "static") == 0) { 95 | is_static = 1; 96 | } else { 97 | printf("Wrong type of allocation!"); 98 | return 1; 99 | } 100 | 101 | char *first_operation; 102 | int first_arg = -1; 103 | char *second_operation; 104 | int second_arg = -1; 105 | if (argc >= 5) { 106 | first_operation = argv[4]; 107 | } 108 | if (argc >= 6) { 109 | first_arg = (int) strtol(argv[5], NULL, 10); 110 | } 111 | if (argc >= 7) { 112 | second_operation = argv[6]; 113 | } 114 | if (argc >= 8) { 115 | second_arg = (int) strtol(argv[7], NULL, 10); 116 | } 117 | 118 | struct tms **tms_time = malloc(6 * sizeof(struct tms *)); 119 | clock_t real_time[6]; 120 | for (int i = 0; i < 6; i++) { 121 | tms_time[i] = (struct tms *) malloc(sizeof(struct tms *)); 122 | } 123 | 124 | printf(" Real User System\n"); 125 | 126 | 127 | struct wrapped_arr *arr; 128 | arr = create(array_size, is_static); 129 | 130 | 131 | real_time[0] = times(tms_time[0]); 132 | 133 | fil_array(arr, block_size); 134 | 135 | real_time[1] = times(tms_time[1]); 136 | 137 | 138 | printf("%s", "create\n"); 139 | printf("%lf ", calculate_time(real_time[0], real_time[1])); 140 | printf("%lf ", calculate_time(tms_time[0]->tms_utime, tms_time[1]->tms_utime)); 141 | 142 | printf("%lf ", calculate_time(tms_time[0]->tms_stime, tms_time[1]->tms_stime)); 143 | printf("\n"); 144 | 145 | if (argc >= 5) { 146 | 147 | real_time[2] = times(tms_time[2]); 148 | exec_operation(first_operation, first_arg, block_size, arr); 149 | real_time[3] = times(tms_time[3]); 150 | 151 | 152 | printf("%s %s", first_operation, " \n"); 153 | printf("%lf ", calculate_time(real_time[2], real_time[3])); 154 | printf("%lf ", calculate_time(tms_time[2]->tms_utime, tms_time[3]->tms_utime)); 155 | printf("%lf ", calculate_time(tms_time[2]->tms_stime, tms_time[3]->tms_stime)); 156 | printf("\n"); 157 | } 158 | 159 | if (argc >= 7) { 160 | 161 | real_time[4] = times(tms_time[4]); 162 | 163 | exec_operation(second_operation, 300000, block_size, arr); 164 | real_time[5] = times(tms_time[5]); 165 | 166 | printf("%s %s", second_operation, " \n"); 167 | printf("%lf ", calculate_time(real_time[4], real_time[5])); 168 | printf("%lf ", calculate_time(tms_time[4]->tms_utime, tms_time[5]->tms_utime)); 169 | printf("%lf ", calculate_time(tms_time[4]->tms_stime, tms_time[5]->tms_stime)); 170 | printf("\n"); 171 | } 172 | 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /zestaw1/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | 4 | all: static shared clean 5 | 6 | static: 7 | $(CC) -c library.c 8 | ar rcs library.a library.o 9 | 10 | shared: 11 | $(CC) -c -fPIC library.c 12 | $(CC) -shared -fPIC -o library.so library.o 13 | 14 | clean: 15 | rm -f *.o 16 | 17 | 18 | zad2_static: 19 | make static 20 | $(CC) -o test main.c library.a -I . 21 | # works :) 22 | make tests 23 | 24 | zad2_shared: 25 | make shared 26 | $(CC) -o test main.c -L. library.so -I . 27 | # works :) 28 | make tests 29 | 30 | tests: 31 | # static 32 | ./test 301231 43 static 33 | ./test 620000 51 static find 5402300 34 | ./test 620000 33 static change 200000 35 | ./test 600000 32 static change_alt 123123 36 | 37 | # dynamic 38 | ./test 301231 43 dynamic 39 | ./test 620000 51 dynamic find 5402300 40 | ./test 620000 33 dynamic change 200000 41 | ./test 600000 32 dynamic change_alt 123123 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /zestaw1/zad3a/library.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #include "library.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | char *global_arr[1000000]; 13 | 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static) { 16 | if (number_of_blocks < 0) { 17 | return NULL; 18 | } 19 | struct wrapped_arr *res = malloc(sizeof(struct wrapped_arr)); 20 | res->number_of_blocks = number_of_blocks; 21 | res->is_static = is_static; 22 | if (is_static) { 23 | res->arr = global_arr; 24 | } else { 25 | char **arr = (char **) calloc(number_of_blocks, sizeof(char *)); 26 | res->arr = arr; 27 | } 28 | return res; 29 | } 30 | 31 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index) { 32 | if (index >= arr->number_of_blocks || index < 0) { 33 | return; 34 | } 35 | arr->arr[index] = calloc(strlen(block), sizeof(char)); 36 | strcpy(arr->arr[index], block); 37 | } 38 | 39 | void delete_block_at_index(struct wrapped_arr *arr, int index) { 40 | if (arr == NULL || arr->arr[index] == NULL) { 41 | return; 42 | } 43 | free(arr->arr[index]); 44 | arr->arr[index] = NULL; 45 | 46 | } 47 | 48 | void delete_array(struct wrapped_arr *arr) { 49 | for (int i = 0; i < arr->number_of_blocks; i++) { 50 | if (arr->arr[i] != NULL) { 51 | free(arr->arr[i]); 52 | } 53 | } 54 | } 55 | 56 | int get_int_block(char *block) { 57 | int res = 0; 58 | int len = strlen(block); 59 | for (int i = 0; i < len; i++) 60 | res += (int) block[i]; 61 | return res; 62 | } 63 | 64 | char *find_closest(struct wrapped_arr *arr, int value) { 65 | char *res = NULL; 66 | int min_diff = INT_MAX; 67 | for (int i = 0; i < arr->number_of_blocks; i++) { 68 | char *block = arr->arr[i]; 69 | if (block != NULL) { 70 | int diff = abs(get_int_block(block) - value); 71 | if (min_diff > diff) { 72 | min_diff = diff; 73 | res = block; 74 | } 75 | } 76 | } 77 | return res; 78 | } 79 | -------------------------------------------------------------------------------- /zestaw1/zad3a/library.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #ifndef SYSOPY_LIBRARY_H 6 | #define SYSOPY_LIBRARY_H 7 | 8 | 9 | struct wrapped_arr { 10 | int number_of_blocks; 11 | char **arr; 12 | int is_static; 13 | }; 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static); 16 | 17 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index); 18 | 19 | void delete_block_at_index(struct wrapped_arr *arr, int index); 20 | 21 | void delete_array(struct wrapped_arr *arr); 22 | 23 | char *find_closest(struct wrapped_arr *arr, int value); 24 | 25 | #endif //SYSOPY_LIBRARY_H 26 | -------------------------------------------------------------------------------- /zestaw1/zad3a/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 10/03/2018. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "library.h" 12 | 13 | char *generate_random_string(int max_size) { 14 | if (max_size < 1) return NULL; 15 | char *base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 16 | size_t dict_len = strlen(base); 17 | char *res = (char *) malloc((max_size) * sizeof(char)); 18 | 19 | for (int i = 0; i < max_size-1; i++) { 20 | res[i] = base[rand() % dict_len]; 21 | } 22 | res[max_size-1] = '\0'; 23 | 24 | return res; 25 | } 26 | 27 | void fil_array(struct wrapped_arr *arr, int block_size) { 28 | for (int i = 0; i < arr->number_of_blocks; i++) { 29 | char *randomString = generate_random_string(block_size); 30 | add_block_at_index(arr, randomString, i); 31 | 32 | } 33 | } 34 | 35 | void add_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index, int block_size) { 36 | for (int i = 0; i < number; i++) { 37 | char *block = generate_random_string(block_size); 38 | add_block_at_index(arr, block, i + start_index); 39 | } 40 | } 41 | 42 | void remove_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index) { 43 | for (int i = 0; i < number; i++) { 44 | delete_block_at_index(arr, i + start_index); 45 | } 46 | } 47 | 48 | void delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 49 | remove_specific_number_of_blocks(arr, number, 0); 50 | add_specific_number_of_blocks(arr, number, 0, block_size); 51 | } 52 | 53 | void alt_delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 54 | for (int i = 0; i < number; i++) { 55 | delete_block_at_index(arr, i); 56 | add_block_at_index(arr, generate_random_string(block_size), i); 57 | } 58 | } 59 | 60 | double calculate_time(clock_t start, clock_t end) { 61 | return (double) (end - start) / sysconf(_SC_CLK_TCK); 62 | } 63 | 64 | void exec_operation(char *arg, int param, int block_size, struct wrapped_arr *arr) { 65 | 66 | 67 | if (strcmp(arg, "change") == 0) { 68 | delete_then_add(arr, param, block_size); 69 | 70 | } else if (strcmp(arg, "change_alt") == 0) { 71 | alt_delete_then_add(arr, param, block_size); 72 | 73 | } else if (strcmp(arg, "find") == 0) { 74 | find_closest(arr, block_size); 75 | 76 | } else if (strcmp(arg, "remove") == 0) { 77 | delete_array(arr); 78 | } 79 | 80 | } 81 | 82 | int main(int argc, char **argv) { 83 | if (argc < 4) { 84 | printf("Meh, wrong arguments. Give me please: number of blocks, blocksize, mode of alloc and then list of job (max 2)!"); 85 | return 1; 86 | } 87 | srand((unsigned int) time(NULL)); 88 | int array_size = (int) strtol(argv[1], NULL, 10); 89 | int block_size = (int) strtol(argv[2], NULL, 10); 90 | 91 | int is_static; 92 | if (strcmp(argv[3], "dynamic") == 0) { 93 | is_static = 0; 94 | } else if (strcmp(argv[3], "static") == 0) { 95 | is_static = 1; 96 | } else { 97 | printf("Wrong type of allocation!"); 98 | return 1; 99 | } 100 | 101 | char *first_operation; 102 | int first_arg = -1; 103 | char *second_operation; 104 | int second_arg = -1; 105 | if (argc >= 5) { 106 | first_operation = argv[4]; 107 | } 108 | if (argc >= 6) { 109 | first_arg = (int) strtol(argv[5], NULL, 10); 110 | } 111 | if (argc >= 7) { 112 | second_operation = argv[6]; 113 | } 114 | if (argc >= 8) { 115 | second_arg = (int) strtol(argv[7], NULL, 10); 116 | } 117 | 118 | struct tms **tms_time = malloc(6 * sizeof(struct tms *)); 119 | clock_t real_time[6]; 120 | for (int i = 0; i < 6; i++) { 121 | tms_time[i] = (struct tms *) malloc(sizeof(struct tms *)); 122 | } 123 | 124 | printf(" Real User System\n"); 125 | 126 | 127 | struct wrapped_arr *arr; 128 | arr = create(array_size, is_static); 129 | 130 | 131 | real_time[0] = times(tms_time[0]); 132 | 133 | fil_array(arr, block_size); 134 | 135 | real_time[1] = times(tms_time[1]); 136 | 137 | 138 | printf("%s", "create\n"); 139 | printf("%lf ", calculate_time(real_time[0], real_time[1])); 140 | printf("%lf ", calculate_time(tms_time[0]->tms_utime, tms_time[1]->tms_utime)); 141 | 142 | printf("%lf ", calculate_time(tms_time[0]->tms_stime, tms_time[1]->tms_stime)); 143 | printf("\n"); 144 | 145 | if (argc >= 5) { 146 | 147 | real_time[2] = times(tms_time[2]); 148 | exec_operation(first_operation, first_arg, block_size, arr); 149 | real_time[3] = times(tms_time[3]); 150 | 151 | 152 | printf("%s %s", first_operation, " \n"); 153 | printf("%lf ", calculate_time(real_time[2], real_time[3])); 154 | printf("%lf ", calculate_time(tms_time[2]->tms_utime, tms_time[3]->tms_utime)); 155 | printf("%lf ", calculate_time(tms_time[2]->tms_stime, tms_time[3]->tms_stime)); 156 | printf("\n"); 157 | } 158 | 159 | if (argc >= 7) { 160 | 161 | real_time[4] = times(tms_time[4]); 162 | 163 | exec_operation(second_operation, 300000, block_size, arr); 164 | real_time[5] = times(tms_time[5]); 165 | 166 | printf("%s %s", second_operation, " \n"); 167 | printf("%lf ", calculate_time(real_time[4], real_time[5])); 168 | printf("%lf ", calculate_time(tms_time[4]->tms_utime, tms_time[5]->tms_utime)); 169 | printf("%lf ", calculate_time(tms_time[4]->tms_stime, tms_time[5]->tms_stime)); 170 | printf("\n"); 171 | } 172 | 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /zestaw1/zad3a/main_dynamic.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 10/03/2018. 3 | // 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "library.h" 13 | 14 | 15 | void *dl_handle; 16 | 17 | typedef void *(*arbitrary)(); 18 | 19 | 20 | char *generate_random_string(int max_size) { 21 | if (max_size < 1) return NULL; 22 | char *base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 23 | size_t dict_len = strlen(base); 24 | char *res = (char *) malloc((max_size) * sizeof(char)); 25 | 26 | for (int i = 0; i < max_size-1; i++) { 27 | res[i] = base[rand() % dict_len]; 28 | } 29 | res[max_size-1] = '\0'; 30 | 31 | return res; 32 | } 33 | 34 | void fil_array(struct wrapped_arr *arr, int block_size) { 35 | for (int i = 0; i < arr->number_of_blocks; i++) { 36 | char *randomString = generate_random_string(block_size); 37 | arbitrary fadd_block_at_index; 38 | *(void **) (&fadd_block_at_index) = dlsym(dl_handle, "add_block_at_index"); 39 | fadd_block_at_index(arr, randomString, i); 40 | 41 | } 42 | } 43 | 44 | void add_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index, int block_size) { 45 | for (int i = 0; i < number; i++) { 46 | char *block = generate_random_string(block_size); 47 | arbitrary fadd_block_at_index; 48 | *(void **) (&fadd_block_at_index) = dlsym(dl_handle, "add_block_at_index"); 49 | fadd_block_at_index(arr, block, i + start_index); 50 | } 51 | } 52 | 53 | void remove_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index) { 54 | for (int i = 0; i < number; i++) { 55 | arbitrary fdelete_block_at_index; 56 | *(void **) (&fdelete_block_at_index) = dlsym(dl_handle, "delete_block_at_index"); 57 | fdelete_block_at_index(arr, i + start_index); 58 | } 59 | } 60 | 61 | void delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 62 | remove_specific_number_of_blocks(arr, number, 0); 63 | add_specific_number_of_blocks(arr, number, 0, block_size); 64 | } 65 | 66 | void alt_delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 67 | for (int i = 0; i < number; i++) { 68 | arbitrary fdelete_block_at_index; 69 | *(void **) (&fdelete_block_at_index) = dlsym(dl_handle, "delete_block_at_index"); 70 | fdelete_block_at_index(arr, i); 71 | arbitrary fadd_block_at_index; 72 | *(void **) (&fadd_block_at_index) = dlsym(dl_handle, "add_block_at_index"); 73 | fadd_block_at_index(arr, generate_random_string(block_size), i); 74 | } 75 | } 76 | 77 | double calculate_time(clock_t start, clock_t end) { 78 | return (double) (end - start) / sysconf(_SC_CLK_TCK); 79 | } 80 | 81 | void exec_operation(char *arg, int param, int block_size, struct wrapped_arr *arr) { 82 | 83 | 84 | if (strcmp(arg, "change") == 0) { 85 | delete_then_add(arr, param, block_size); 86 | 87 | } else if (strcmp(arg, "change_alt") == 0) { 88 | alt_delete_then_add(arr, param, block_size); 89 | 90 | } else if (strcmp(arg, "find") == 0) { 91 | arbitrary ffind_closest; 92 | *(void **) (&ffind_closest) = dlsym(dl_handle, "find_closest"); 93 | ffind_closest(arr, block_size); 94 | 95 | } else if (strcmp(arg, "remove") == 0) { 96 | arbitrary fdelete_array; 97 | *(void **) (&fdelete_array) = dlsym(dl_handle, "delete_array"); 98 | fdelete_array(arr); 99 | } 100 | 101 | } 102 | 103 | int main(int argc, char **argv) { 104 | 105 | dl_handle = dlopen("./library.so", RTLD_LAZY); 106 | if (!dl_handle) { 107 | printf("!!! %s\n", dlerror()); 108 | return 0; 109 | } 110 | 111 | 112 | srand((unsigned int) time(NULL)); 113 | int array_size = (int) strtol(argv[1], NULL, 10); 114 | int block_size = (int) strtol(argv[2], NULL, 10); 115 | 116 | int is_static; 117 | if (strcmp(argv[3], "dynamic")) { 118 | is_static = 0; 119 | } else if (strcmp(argv[3], "static")) { 120 | is_static = 1; 121 | } else { 122 | printf("Wrong type of allocation!"); 123 | return 0; 124 | } 125 | 126 | char *first_operation; 127 | int first_arg = -1; 128 | char *second_operation; 129 | int second_arg = -1; 130 | if (argc >= 5) { 131 | first_operation = argv[4]; 132 | } 133 | if (argc >= 6) { 134 | first_arg = (int) strtol(argv[5], NULL, 10); 135 | } 136 | if (argc >= 7) { 137 | second_operation = argv[6]; 138 | } 139 | if (argc >= 8) { 140 | second_arg = (int) strtol(argv[7], NULL, 10); 141 | } 142 | 143 | struct tms **tms_time = malloc(6 * sizeof(struct tms *)); 144 | clock_t real_time[6]; 145 | for (int i = 0; i < 6; i++) { 146 | tms_time[i] = (struct tms *) malloc(sizeof(struct tms *)); 147 | } 148 | 149 | printf(" Real User System\n"); 150 | 151 | arbitrary fcreate; 152 | *(void **) (&fcreate) = dlsym(dl_handle, "create"); 153 | 154 | 155 | struct wrapped_arr *arr; 156 | arr = fcreate(array_size, is_static); 157 | 158 | 159 | real_time[0] = times(tms_time[0]); 160 | 161 | fil_array(arr, block_size); 162 | 163 | real_time[1] = times(tms_time[1]); 164 | 165 | 166 | printf("%s", "create\n"); 167 | printf("%lf ", calculate_time(real_time[0], real_time[1])); 168 | printf("%lf ", calculate_time(tms_time[0]->tms_utime, tms_time[1]->tms_utime)); 169 | 170 | printf("%lf ", calculate_time(tms_time[0]->tms_stime, tms_time[1]->tms_stime)); 171 | printf("\n"); 172 | 173 | if (argc >= 5) { 174 | 175 | real_time[2] = times(tms_time[2]); 176 | exec_operation(first_operation, first_arg, block_size, arr); 177 | real_time[3] = times(tms_time[3]); 178 | 179 | 180 | printf("%s %s", first_operation, " \n"); 181 | printf("%lf ", calculate_time(real_time[2], real_time[3])); 182 | printf("%lf ", calculate_time(tms_time[2]->tms_utime, tms_time[3]->tms_utime)); 183 | printf("%lf ", calculate_time(tms_time[2]->tms_stime, tms_time[3]->tms_stime)); 184 | printf("\n"); 185 | } 186 | 187 | if (argc >= 7) { 188 | 189 | real_time[4] = times(tms_time[4]); 190 | 191 | exec_operation(second_operation, 300000, block_size, arr); 192 | real_time[5] = times(tms_time[5]); 193 | 194 | printf("%s %s", second_operation, " \n"); 195 | printf("%lf ", calculate_time(real_time[4], real_time[5])); 196 | printf("%lf ", calculate_time(tms_time[4]->tms_utime, tms_time[5]->tms_utime)); 197 | printf("%lf ", calculate_time(tms_time[4]->tms_stime, tms_time[5]->tms_stime)); 198 | printf("\n"); 199 | } 200 | 201 | 202 | return 0; 203 | } 204 | -------------------------------------------------------------------------------- /zestaw1/zad3a/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | 4 | all: static shared clean 5 | 6 | static: 7 | $(CC) -c library.c 8 | ar rcs library.a library.o 9 | 10 | shared: 11 | $(CC) -c -fPIC library.c 12 | $(CC) -shared -fPIC -o library.so library.o 13 | 14 | clean: 15 | rm -f *.o 16 | 17 | zad3_static: 18 | make static 19 | $(CC) -o test main.c library.a -I . 20 | # works :) 21 | make tests 22 | 23 | zad3_dynamic: 24 | make shared 25 | $(CC) -o test main_dynamic.c -I . 26 | # works :) 27 | make tests 28 | 29 | zad3_shared: 30 | make shared 31 | $(CC) -o test main.c -L. library.so -I . 32 | # works :) 33 | make tests 34 | 35 | 36 | tests: 37 | # static 38 | ./test 301231 43 static 39 | ./test 620000 51 static find 5402300 40 | ./test 620000 33 static change 200000 41 | ./test 600000 32 static change_alt 123123 42 | 43 | # dynamic 44 | ./test 301231 43 dynamic 45 | ./test 620000 51 dynamic find 5402300 46 | ./test 620000 33 dynamic change 200000 47 | ./test 600000 32 dynamic change_alt 123123 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /zestaw1/zad3b/library.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #include "library.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | char *global_arr[1000000]; 13 | 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static) { 16 | if (number_of_blocks < 0) { 17 | return NULL; 18 | } 19 | struct wrapped_arr *res = malloc(sizeof(struct wrapped_arr)); 20 | res->number_of_blocks = number_of_blocks; 21 | res->is_static = is_static; 22 | if (is_static) { 23 | res->arr = global_arr; 24 | } else { 25 | char **arr = (char **) calloc(number_of_blocks, sizeof(char *)); 26 | res->arr = arr; 27 | } 28 | return res; 29 | } 30 | 31 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index) { 32 | if (index >= arr->number_of_blocks || index < 0) { 33 | return; 34 | } 35 | arr->arr[index] = calloc(strlen(block), sizeof(char)); 36 | strcpy(arr->arr[index], block); 37 | } 38 | 39 | void delete_block_at_index(struct wrapped_arr *arr, int index) { 40 | if (arr == NULL || arr->arr[index] == NULL) { 41 | return; 42 | } 43 | free(arr->arr[index]); 44 | arr->arr[index] = NULL; 45 | 46 | } 47 | 48 | void delete_array(struct wrapped_arr *arr) { 49 | for (int i = 0; i < arr->number_of_blocks; i++) { 50 | if (arr->arr[i] != NULL) { 51 | free(arr->arr[i]); 52 | } 53 | } 54 | } 55 | 56 | int get_int_block(char *block) { 57 | int res = 0; 58 | int len = strlen(block); 59 | for (int i = 0; i < len; i++) 60 | res += (int) block[i]; 61 | return res; 62 | } 63 | 64 | char *find_closest(struct wrapped_arr *arr, int value) { 65 | char *res = NULL; 66 | int min_diff = INT_MAX; 67 | for (int i = 0; i < arr->number_of_blocks; i++) { 68 | char *block = arr->arr[i]; 69 | if (block != NULL) { 70 | int diff = abs(get_int_block(block) - value); 71 | if (min_diff > diff) { 72 | min_diff = diff; 73 | res = block; 74 | } 75 | } 76 | } 77 | return res; 78 | } 79 | -------------------------------------------------------------------------------- /zestaw1/zad3b/library.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 08/03/2018. 3 | // 4 | 5 | #ifndef SYSOPY_LIBRARY_H 6 | #define SYSOPY_LIBRARY_H 7 | 8 | 9 | struct wrapped_arr { 10 | int number_of_blocks; 11 | char **arr; 12 | int is_static; 13 | }; 14 | 15 | struct wrapped_arr *create(int number_of_blocks, int is_static); 16 | 17 | void add_block_at_index(struct wrapped_arr *arr, char *block, int index); 18 | 19 | void delete_block_at_index(struct wrapped_arr *arr, int index); 20 | 21 | void delete_array(struct wrapped_arr *arr); 22 | 23 | char *find_closest(struct wrapped_arr *arr, int value); 24 | 25 | #endif //SYSOPY_LIBRARY_H 26 | -------------------------------------------------------------------------------- /zestaw1/zad3b/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 10/03/2018. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "library.h" 12 | 13 | char *generate_random_string(int max_size) { 14 | if (max_size < 1) return NULL; 15 | char *base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 16 | size_t dict_len = strlen(base); 17 | char *res = (char *) malloc((max_size) * sizeof(char)); 18 | 19 | for (int i = 0; i < max_size-1; i++) { 20 | res[i] = base[rand() % dict_len]; 21 | } 22 | res[max_size-1] = '\0'; 23 | 24 | return res; 25 | } 26 | 27 | void fil_array(struct wrapped_arr *arr, int block_size) { 28 | for (int i = 0; i < arr->number_of_blocks; i++) { 29 | char *randomString = generate_random_string(block_size); 30 | add_block_at_index(arr, randomString, i); 31 | 32 | } 33 | } 34 | 35 | void add_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index, int block_size) { 36 | for (int i = 0; i < number; i++) { 37 | char *block = generate_random_string(block_size); 38 | add_block_at_index(arr, block, i + start_index); 39 | } 40 | } 41 | 42 | void remove_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index) { 43 | for (int i = 0; i < number; i++) { 44 | delete_block_at_index(arr, i + start_index); 45 | } 46 | } 47 | 48 | void delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 49 | remove_specific_number_of_blocks(arr, number, 0); 50 | add_specific_number_of_blocks(arr, number, 0, block_size); 51 | } 52 | 53 | void alt_delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 54 | for (int i = 0; i < number; i++) { 55 | delete_block_at_index(arr, i); 56 | add_block_at_index(arr, generate_random_string(block_size), i); 57 | } 58 | } 59 | 60 | double calculate_time(clock_t start, clock_t end) { 61 | return (double) (end - start) / sysconf(_SC_CLK_TCK); 62 | } 63 | 64 | void exec_operation(char *arg, int param, int block_size, struct wrapped_arr *arr) { 65 | 66 | 67 | if (strcmp(arg, "change") == 0) { 68 | delete_then_add(arr, param, block_size); 69 | 70 | } else if (strcmp(arg, "change_alt") == 0) { 71 | alt_delete_then_add(arr, param, block_size); 72 | 73 | } else if (strcmp(arg, "find") == 0) { 74 | find_closest(arr, block_size); 75 | 76 | } else if (strcmp(arg, "remove") == 0) { 77 | delete_array(arr); 78 | } 79 | 80 | } 81 | 82 | int main(int argc, char **argv) { 83 | if (argc < 4) { 84 | printf("Meh, wrong arguments. Give me please: number of blocks, blocksize, mode of alloc and then list of job (max 2)!"); 85 | return 1; 86 | } 87 | srand((unsigned int) time(NULL)); 88 | int array_size = (int) strtol(argv[1], NULL, 10); 89 | int block_size = (int) strtol(argv[2], NULL, 10); 90 | 91 | int is_static; 92 | if (strcmp(argv[3], "dynamic") == 0) { 93 | is_static = 0; 94 | } else if (strcmp(argv[3], "static") == 0) { 95 | is_static = 1; 96 | } else { 97 | printf("Wrong type of allocation!"); 98 | return 1; 99 | } 100 | 101 | char *first_operation; 102 | int first_arg = -1; 103 | char *second_operation; 104 | int second_arg = -1; 105 | if (argc >= 5) { 106 | first_operation = argv[4]; 107 | } 108 | if (argc >= 6) { 109 | first_arg = (int) strtol(argv[5], NULL, 10); 110 | } 111 | if (argc >= 7) { 112 | second_operation = argv[6]; 113 | } 114 | if (argc >= 8) { 115 | second_arg = (int) strtol(argv[7], NULL, 10); 116 | } 117 | 118 | struct tms **tms_time = malloc(6 * sizeof(struct tms *)); 119 | clock_t real_time[6]; 120 | for (int i = 0; i < 6; i++) { 121 | tms_time[i] = (struct tms *) malloc(sizeof(struct tms *)); 122 | } 123 | 124 | printf(" Real User System\n"); 125 | 126 | 127 | struct wrapped_arr *arr; 128 | arr = create(array_size, is_static); 129 | 130 | 131 | real_time[0] = times(tms_time[0]); 132 | 133 | fil_array(arr, block_size); 134 | 135 | real_time[1] = times(tms_time[1]); 136 | 137 | 138 | printf("%s", "create\n"); 139 | printf("%lf ", calculate_time(real_time[0], real_time[1])); 140 | printf("%lf ", calculate_time(tms_time[0]->tms_utime, tms_time[1]->tms_utime)); 141 | 142 | printf("%lf ", calculate_time(tms_time[0]->tms_stime, tms_time[1]->tms_stime)); 143 | printf("\n"); 144 | 145 | if (argc >= 5) { 146 | 147 | real_time[2] = times(tms_time[2]); 148 | exec_operation(first_operation, first_arg, block_size, arr); 149 | real_time[3] = times(tms_time[3]); 150 | 151 | 152 | printf("%s %s", first_operation, " \n"); 153 | printf("%lf ", calculate_time(real_time[2], real_time[3])); 154 | printf("%lf ", calculate_time(tms_time[2]->tms_utime, tms_time[3]->tms_utime)); 155 | printf("%lf ", calculate_time(tms_time[2]->tms_stime, tms_time[3]->tms_stime)); 156 | printf("\n"); 157 | } 158 | 159 | if (argc >= 7) { 160 | 161 | real_time[4] = times(tms_time[4]); 162 | 163 | exec_operation(second_operation, 300000, block_size, arr); 164 | real_time[5] = times(tms_time[5]); 165 | 166 | printf("%s %s", second_operation, " \n"); 167 | printf("%lf ", calculate_time(real_time[4], real_time[5])); 168 | printf("%lf ", calculate_time(tms_time[4]->tms_utime, tms_time[5]->tms_utime)); 169 | printf("%lf ", calculate_time(tms_time[4]->tms_stime, tms_time[5]->tms_stime)); 170 | printf("\n"); 171 | } 172 | 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /zestaw1/zad3b/main_dynamic.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 10/03/2018. 3 | // 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "library.h" 13 | 14 | 15 | void *dl_handle; 16 | 17 | typedef void *(*arbitrary)(); 18 | 19 | 20 | char *generate_random_string(int max_size) { 21 | if (max_size < 1) return NULL; 22 | char *base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 23 | size_t dict_len = strlen(base); 24 | char *res = (char *) malloc((max_size) * sizeof(char)); 25 | 26 | for (int i = 0; i < max_size-1; i++) { 27 | res[i] = base[rand() % dict_len]; 28 | } 29 | res[max_size-1] = '\0'; 30 | 31 | return res; 32 | } 33 | 34 | void fil_array(struct wrapped_arr *arr, int block_size) { 35 | for (int i = 0; i < arr->number_of_blocks; i++) { 36 | char *randomString = generate_random_string(block_size); 37 | arbitrary fadd_block_at_index; 38 | *(void **) (&fadd_block_at_index) = dlsym(dl_handle, "add_block_at_index"); 39 | fadd_block_at_index(arr, randomString, i); 40 | 41 | } 42 | } 43 | 44 | void add_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index, int block_size) { 45 | for (int i = 0; i < number; i++) { 46 | char *block = generate_random_string(block_size); 47 | arbitrary fadd_block_at_index; 48 | *(void **) (&fadd_block_at_index) = dlsym(dl_handle, "add_block_at_index"); 49 | fadd_block_at_index(arr, block, i + start_index); 50 | } 51 | } 52 | 53 | void remove_specific_number_of_blocks(struct wrapped_arr *arr, int number, int start_index) { 54 | for (int i = 0; i < number; i++) { 55 | arbitrary fdelete_block_at_index; 56 | *(void **) (&fdelete_block_at_index) = dlsym(dl_handle, "delete_block_at_index"); 57 | fdelete_block_at_index(arr, i + start_index); 58 | } 59 | } 60 | 61 | void delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 62 | remove_specific_number_of_blocks(arr, number, 0); 63 | add_specific_number_of_blocks(arr, number, 0, block_size); 64 | } 65 | 66 | void alt_delete_then_add(struct wrapped_arr *arr, int number, int block_size) { 67 | for (int i = 0; i < number; i++) { 68 | arbitrary fdelete_block_at_index; 69 | *(void **) (&fdelete_block_at_index) = dlsym(dl_handle, "delete_block_at_index"); 70 | fdelete_block_at_index(arr, i); 71 | arbitrary fadd_block_at_index; 72 | *(void **) (&fadd_block_at_index) = dlsym(dl_handle, "add_block_at_index"); 73 | fadd_block_at_index(arr, generate_random_string(block_size), i); 74 | } 75 | } 76 | 77 | double calculate_time(clock_t start, clock_t end) { 78 | return (double) (end - start) / sysconf(_SC_CLK_TCK); 79 | } 80 | 81 | void exec_operation(char *arg, int param, int block_size, struct wrapped_arr *arr) { 82 | 83 | 84 | if (strcmp(arg, "change") == 0) { 85 | delete_then_add(arr, param, block_size); 86 | 87 | } else if (strcmp(arg, "change_alt") == 0) { 88 | alt_delete_then_add(arr, param, block_size); 89 | 90 | } else if (strcmp(arg, "find") == 0) { 91 | arbitrary ffind_closest; 92 | *(void **) (&ffind_closest) = dlsym(dl_handle, "find_closest"); 93 | ffind_closest(arr, block_size); 94 | 95 | } else if (strcmp(arg, "remove") == 0) { 96 | arbitrary fdelete_array; 97 | *(void **) (&fdelete_array) = dlsym(dl_handle, "delete_array"); 98 | fdelete_array(arr); 99 | } 100 | 101 | } 102 | 103 | int main(int argc, char **argv) { 104 | 105 | dl_handle = dlopen("./library.so", RTLD_LAZY); 106 | if (!dl_handle) { 107 | printf("!!! %s\n", dlerror()); 108 | return 0; 109 | } 110 | 111 | 112 | srand((unsigned int) time(NULL)); 113 | int array_size = (int) strtol(argv[1], NULL, 10); 114 | int block_size = (int) strtol(argv[2], NULL, 10); 115 | 116 | int is_static; 117 | if (strcmp(argv[3], "dynamic")) { 118 | is_static = 0; 119 | } else if (strcmp(argv[3], "static")) { 120 | is_static = 1; 121 | } else { 122 | printf("Wrong type of allocation!"); 123 | return 0; 124 | } 125 | 126 | char *first_operation; 127 | int first_arg = -1; 128 | char *second_operation; 129 | int second_arg = -1; 130 | if (argc >= 5) { 131 | first_operation = argv[4]; 132 | } 133 | if (argc >= 6) { 134 | first_arg = (int) strtol(argv[5], NULL, 10); 135 | } 136 | if (argc >= 7) { 137 | second_operation = argv[6]; 138 | } 139 | if (argc >= 8) { 140 | second_arg = (int) strtol(argv[7], NULL, 10); 141 | } 142 | 143 | struct tms **tms_time = malloc(6 * sizeof(struct tms *)); 144 | clock_t real_time[6]; 145 | for (int i = 0; i < 6; i++) { 146 | tms_time[i] = (struct tms *) malloc(sizeof(struct tms *)); 147 | } 148 | 149 | printf(" Real User System\n"); 150 | 151 | arbitrary fcreate; 152 | *(void **) (&fcreate) = dlsym(dl_handle, "create"); 153 | 154 | 155 | struct wrapped_arr *arr; 156 | arr = fcreate(array_size, is_static); 157 | 158 | 159 | real_time[0] = times(tms_time[0]); 160 | 161 | fil_array(arr, block_size); 162 | 163 | real_time[1] = times(tms_time[1]); 164 | 165 | 166 | printf("%s", "create\n"); 167 | printf("%lf ", calculate_time(real_time[0], real_time[1])); 168 | printf("%lf ", calculate_time(tms_time[0]->tms_utime, tms_time[1]->tms_utime)); 169 | 170 | printf("%lf ", calculate_time(tms_time[0]->tms_stime, tms_time[1]->tms_stime)); 171 | printf("\n"); 172 | 173 | if (argc >= 5) { 174 | 175 | real_time[2] = times(tms_time[2]); 176 | exec_operation(first_operation, first_arg, block_size, arr); 177 | real_time[3] = times(tms_time[3]); 178 | 179 | 180 | printf("%s %s", first_operation, " \n"); 181 | printf("%lf ", calculate_time(real_time[2], real_time[3])); 182 | printf("%lf ", calculate_time(tms_time[2]->tms_utime, tms_time[3]->tms_utime)); 183 | printf("%lf ", calculate_time(tms_time[2]->tms_stime, tms_time[3]->tms_stime)); 184 | printf("\n"); 185 | } 186 | 187 | if (argc >= 7) { 188 | 189 | real_time[4] = times(tms_time[4]); 190 | 191 | exec_operation(second_operation, 300000, block_size, arr); 192 | real_time[5] = times(tms_time[5]); 193 | 194 | printf("%s %s", second_operation, " \n"); 195 | printf("%lf ", calculate_time(real_time[4], real_time[5])); 196 | printf("%lf ", calculate_time(tms_time[4]->tms_utime, tms_time[5]->tms_utime)); 197 | printf("%lf ", calculate_time(tms_time[4]->tms_stime, tms_time[5]->tms_stime)); 198 | printf("\n"); 199 | } 200 | 201 | 202 | return 0; 203 | } 204 | -------------------------------------------------------------------------------- /zestaw1/zad3b/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | 4 | all: static shared clean 5 | 6 | static: 7 | $(CC) -c library.c 8 | ar rcs library.a library.o 9 | 10 | shared: 11 | $(CC) -c -fPIC library.c 12 | $(CC) -shared -fPIC -o library.so library.o 13 | 14 | clean: 15 | rm -f *.o 16 | 17 | zad3_static: 18 | make static 19 | $(CC) -o test main.c library.a -I . -O$(Olevel) 20 | # works :) 21 | make tests 22 | 23 | zad3_dynamic: 24 | make shared 25 | $(CC) -o test main_dynamic.c -I . -O$(Olevel) 26 | # works :) 27 | make tests 28 | 29 | zad3_shared: 30 | make shared 31 | $(CC) -o test main.c -L. library.so -I . -O$(Olevel) 32 | # works :) 33 | Smolnik 34 | 35 | tests: 36 | # static 37 | ./test 301231 43 static 38 | ./test 620000 51 static find 5402300 39 | ./test 620000 33 static change 200000 40 | ./test 600000 32 static change_alt 123123 41 | 42 | # dynamic 43 | ./test 301231 43 dynamic 44 | ./test 620000 51 dynamic find 5402300 45 | ./test 620000 33 dynamic change 200000 46 | ./test 600000 32 dynamic change_alt 123123 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /zestaw2/zad1/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 17/03/2018. 3 | // 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #define sys_mode 1 17 | #define lib_mode 0 18 | 19 | double calculate_time(clock_t start, clock_t end) { 20 | return (double) (end - start) / sysconf(_SC_CLK_TCK); 21 | } 22 | 23 | 24 | int generate(char *path, int amount, int len) { 25 | FILE *file = fopen(path, "w+"); // write + read 26 | FILE *rnd = fopen("/dev/urandom", "r"); // open rand generator. urandom seems to be better 27 | char *tmp = malloc(len * sizeof(char) + 1); 28 | for (int i = 0; i < amount; ++i) { 29 | if (fread(tmp, sizeof(char), (size_t) len + 1, rnd) != len + 1) { 30 | return 1; 31 | } 32 | 33 | for (int j = 0; j < len; ++j) { 34 | tmp[j] = (char) (abs(tmp[j]) % 25 + 'a'); 35 | } 36 | 37 | tmp[len] = 10; 38 | 39 | if (fwrite(tmp, sizeof(char), (size_t) len + 1, file) != len + 1) { 40 | return 1; 41 | } 42 | } 43 | fclose(file); // close file 44 | fclose(rnd); // ... and random buffer 45 | free(tmp); 46 | return 0; 47 | }; 48 | 49 | 50 | void generate_wrapper(char *path, int amount, int len) { 51 | if (generate(path, amount, len) != 0) { 52 | printf("%s", "Oops! Something went with generating 🦖"); 53 | } 54 | 55 | } 56 | 57 | int lib_sort(char *path, int amount, int len) { 58 | FILE *file = fopen(path, "r+"); 59 | char *reg1 = malloc((len + 1) * sizeof(char)); 60 | char *reg2 = malloc((len + 1) * sizeof(char)); 61 | 62 | long int offset = (long int) ((len + 1) * sizeof(char)); 63 | 64 | for (int i = 0; i < amount; i++) { 65 | fseek(file, i * offset, 0); // 0 offset from beg 66 | if (fread(reg1, sizeof(char), (size_t)(len + 1), file) != (len + 1)) { // fread -- where?,what?,how many?,from? 67 | return 1; 68 | } 69 | 70 | for (int j = 0; j < i; j++) { 71 | fseek(file, j * offset, 0); 72 | if (fread(reg2, sizeof(char), (size_t)(len + 1), file) != (len + 1)) { 73 | return 1; 74 | } 75 | if (reg2[0] > reg1[0]) { 76 | fseek(file, j * offset, 0); 77 | if (fwrite(reg1, sizeof(char), (size_t)(len + 1), file) != (len + 1)) { 78 | return 1; 79 | } 80 | fseek(file, i * offset, 0); 81 | if (fwrite(reg2, sizeof(char), (size_t)(len + 1), file) != (len + 1)) { // fwrite. Same params 82 | return 1; 83 | } 84 | char *tmp = reg1; 85 | reg1 = reg2; 86 | reg2 = tmp; 87 | } 88 | } 89 | } 90 | 91 | fclose(file); 92 | free(reg1); 93 | free(reg2); 94 | return 0; 95 | }; 96 | 97 | int sys_sort(char *path, int amount, int len) { 98 | int file = open(path, O_RDWR); 99 | char *reg1 = malloc((len + 1) * sizeof(char)); 100 | char *reg2 = malloc((len + 1) * sizeof(char)); 101 | long int offset = (long int) ((len + 1) * sizeof(char)); 102 | 103 | for (int i = 0; i < amount; i++) { 104 | lseek(file, i * offset, SEEK_SET); // SEEK_SET - from beg 105 | 106 | if (read(file, reg1, (size_t)(len + 1) * sizeof(char)) != (len + 1)) { //from, where, how many? 107 | return 1; 108 | } 109 | 110 | for (int j = 0; j < i; j++) { 111 | lseek(file, j * offset, SEEK_SET); 112 | if (read(file, reg2, sizeof(char) * (len + 1)) != (len + 1)) { 113 | return 1; 114 | } 115 | if (reg2[0] > reg1[0]) { 116 | lseek(file, j * offset, 0); 117 | if (write(file, reg1, sizeof(char) * (len + 1)) != (len + 1)) { 118 | return 1; 119 | } 120 | lseek(file, i * offset, 0); 121 | if (write(file, reg2, sizeof(char) * (len + 1)) != (len + 1)) { 122 | return 1; 123 | } 124 | char *tmp = reg1; 125 | reg1 = reg2; 126 | reg2 = tmp; 127 | } 128 | } 129 | } 130 | 131 | close(file); 132 | free(reg1); 133 | free(reg2); 134 | return 0; 135 | } 136 | 137 | 138 | void sort_wrapper(char *path, int amount, int len, int mode) { 139 | if (mode == lib_mode) { 140 | if (lib_sort(path, amount, len) == 1) { 141 | printf("%s", "Oops! Something went with sorting 🦖"); 142 | } 143 | } else { 144 | if (sys_sort(path, amount, len) == 1) { 145 | printf("%s", "Oops! Something went with sorting 🦖"); 146 | } 147 | 148 | } 149 | 150 | } 151 | 152 | int sys_copy(char *path, char *dest, int amount, int len){ 153 | int source = open(path, O_RDONLY); 154 | int target = open(dest, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); // create ifne, wr only, trunc to 0, args with OCR 155 | char *tmp = malloc(len * sizeof(char)); 156 | 157 | for (int i = 0; i < amount; i++){ 158 | if(read(source, tmp, (size_t) (len + 1) * sizeof(char)) != (len + 1)) { 159 | return 1; 160 | } 161 | 162 | if(write(target, tmp, (size_t) (len + 1) * sizeof(char)) != (len + 1)) { 163 | return 1; 164 | } 165 | } 166 | close(source); 167 | close(target); 168 | free(tmp); 169 | return 0; 170 | }; 171 | 172 | int lib_copy(char *path, char *dest, int amount, int len) { 173 | FILE *source = fopen(path, "r"); 174 | FILE *target = fopen(dest, "w+"); 175 | char *tmp = malloc(len * sizeof(char)); 176 | 177 | for (int i = 0; i < amount; i++){ 178 | if(fread(tmp, sizeof(char), (size_t) (len + 1), source) != (len + 1)) { 179 | return 1; 180 | } 181 | 182 | if(fwrite(tmp, sizeof(char), (size_t) (len + 1), target) != (len + 1)) { 183 | return 1; 184 | } 185 | } 186 | fclose(source); 187 | fclose(target); 188 | free(tmp); 189 | return 0; 190 | }; 191 | 192 | void copy_wrapper(char *source, char *destination, int amount, int buffer, int mode) { 193 | if (mode == lib_mode) { 194 | if (lib_copy(source, destination, amount, buffer) == 1) { 195 | printf("%s", "Oops! Something went with copying 🦖"); 196 | } 197 | } else { 198 | if (sys_copy(source, destination, amount, buffer) == 1) { 199 | printf("%s", "Oops! Something went with copying 🦖"); 200 | } 201 | 202 | } 203 | } 204 | 205 | int main(int argc, char **argv) { 206 | if (argc < 5) { 207 | printf("%s", "There's no enough argument! : ¯\\_(ツ)_/¯"); 208 | return 1; 209 | } 210 | 211 | struct tms **tms_time = malloc(2 * sizeof(struct tms *)); 212 | clock_t real_time[6]; 213 | for (int i = 0; i < 2; i++) { 214 | tms_time[i] = (struct tms *) malloc(sizeof(struct tms *)); 215 | } 216 | 217 | printf(" Real User System\n"); 218 | 219 | real_time[0] = times(tms_time[0]); 220 | 221 | if (strcmp(argv[1], "generate") == 0) { 222 | int amount = (int) strtol(argv[3], NULL, 10); 223 | int len = (int) strtol(argv[4], NULL, 10); 224 | generate_wrapper(argv[2], amount, len); 225 | 226 | } else if (strcmp(argv[1], "sort") == 0) { 227 | if (argc < 6) { 228 | printf("%s", "There's no enough argument! : ¯\\_(ツ)_/¯"); 229 | return 1; 230 | } 231 | int amount = (int) strtol(argv[3], NULL, 10); 232 | int len = (int) strtol(argv[4], NULL, 10); 233 | if (strcmp(argv[5], "sys") == 0) { 234 | sort_wrapper(argv[2], amount, len, sys_mode); 235 | } else if (strcmp(argv[5], "lib") == 0) { 236 | sort_wrapper(argv[2], amount, len, lib_mode); 237 | } else { 238 | printf("%s", "There's no such a mode 🙄"); 239 | } 240 | } else if (strcmp(argv[1], "copy") == 0) { 241 | if (argc < 7) { 242 | printf("%s", "There's no enough argument! : ¯\\_(ツ)_/¯"); 243 | return 1; 244 | } 245 | int amount = (int) strtol(argv[4], NULL, 10); 246 | int len = (int) strtol(argv[5], NULL, 10); 247 | if (strcmp(argv[6], "sys") == 0) { 248 | copy_wrapper(argv[2], argv[3], amount, len, sys_mode); 249 | } else if (strcmp(argv[6], "lib") == 0) { 250 | copy_wrapper(argv[2], argv[3], amount, len, lib_mode); 251 | 252 | } else { 253 | printf("%s", "There's no such a mode 🙄"); 254 | } 255 | 256 | } else { 257 | printf("%s", "Are you pretty sure everything if ok?🤔");` 258 | } 259 | real_time[1] = times(tms_time[1]); 260 | printf("%lf ", calculate_time(real_time[0], real_time[1])); 261 | printf("%lf ", calculate_time(tms_time[0]->tms_utime, tms_time[1]->tms_utime)); 262 | 263 | printf("%lf ", calculate_time(tms_time[0]->tms_stime, tms_time[1]->tms_stime)); 264 | printf("\n"); 265 | return 0; 266 | } 267 | -------------------------------------------------------------------------------- /zestaw2/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -std=c11 2 | 3 | 4 | tests: 5 | $(CC) -o res main.c -O2 6 | #compiled 7 | 8 | #generate 9 | for l in 4 512 4096 8192; \ 10 | do \ 11 | for a in 3000 10000 60000 120000; \ 12 | do \ 13 | echo "creating file with $$a records of size $$l"; \ 14 | ./res generate test_file $$a $$l; \ 15 | rm test_file; \ 16 | done; \ 17 | done 18 | 19 | #copy test 20 | for l in 4 512 4096 8192; \ 21 | do \ 22 | for a in 3000 10000 60000 120000; \ 23 | do \ 24 | echo "creating file with $$a records of size $$l"; \ 25 | ./res generate test_file $$a $$l; \ 26 | for m in sys lib; \ 27 | do \ 28 | cp test_file test_file_temp; \ 29 | echo "$$m copy file with $$a records of size $$l"; \ 30 | ./res copy test_file_temp test_copy $$a $$l $$m; \ 31 | rm test_file_temp; \ 32 | rm test_copy; \ 33 | done; \ 34 | rm test_file; \ 35 | done; \ 36 | done 37 | 38 | 39 | #sort test 40 | for l in 4 512 4096 8192; \ 41 | do \ 42 | for a in 1000 3000 10000; \ 43 | do \ 44 | echo "creating file with $$a records of size $$l"; \ 45 | ./res generate test_file $$a $$l; \ 46 | for m in sys lib; \ 47 | do \ 48 | cp test_file test_file_temp; \ 49 | echo "$$m sorting file with $$a records of size $$l"; \ 50 | ./res sort test_file_temp $$a $$l $$m; \ 51 | rm test_file_temp; \ 52 | done; \ 53 | rm test_file; \ 54 | done; \ 55 | done 56 | 57 | -------------------------------------------------------------------------------- /zestaw2/zad1/osx_tests: -------------------------------------------------------------------------------- 1 | gcc -std=c11 -o res main.c -O2 2 | #compiled 3 | #generate 4 | for l in 4 512 4096 8192; \ 5 | do \ 6 | for a in 3000 10000 60000 120000; \ 7 | do \ 8 | echo "creating file with $a records of size $l"; \ 9 | ./res generate test_file $a $l; \ 10 | rm test_file; \ 11 | done; \ 12 | done 13 | creating file with 3000 records of size 4 14 | Real User System 15 | 0.000000 0.000000 0.000000 16 | creating file with 10000 records of size 4 17 | Real User System 18 | 0.000000 0.000000 0.000000 19 | creating file with 60000 records of size 4 20 | Real User System 21 | 0.030000 0.000000 0.020000 22 | creating file with 120000 records of size 4 23 | Real User System 24 | 0.060000 0.010000 0.040000 25 | creating file with 3000 records of size 512 26 | Real User System 27 | 0.120000 0.000000 0.110000 28 | creating file with 10000 records of size 512 29 | Real User System 30 | 0.390000 0.000000 0.380000 31 | creating file with 60000 records of size 512 32 | Real User System 33 | 2.400000 0.030000 2.350000 34 | creating file with 120000 records of size 512 35 | Real User System 36 | 4.660000 0.050000 4.560000 37 | creating file with 3000 records of size 4096 38 | Real User System 39 | 0.970000 0.010000 0.950000 40 | creating file with 10000 records of size 4096 41 | Real User System 42 | 3.120000 0.030000 3.060000 43 | creating file with 60000 records of size 4096 44 | Real User System 45 | 18.750000 0.190000 18.260000 46 | creating file with 120000 records of size 4096 47 | Real User System 48 | 37.450000 0.390000 36.580000 49 | creating file with 3000 records of size 8192 50 | Real User System 51 | 1.840000 0.010000 1.800000 52 | creating file with 10000 records of size 8192 53 | Real User System 54 | 6.020000 0.060000 5.930000 55 | creating file with 60000 records of size 8192 56 | Real User System 57 | 36.120000 0.360000 35.420000 58 | creating file with 120000 records of size 8192 59 | Real User System 60 | 72.200000 0.720000 70.570000 61 | #copy test 62 | for l in 4 512 4096 8192; \ 63 | do \ 64 | for a in 3000 10000 60000 120000; \ 65 | do \ 66 | echo "creating file with $a records of size $l"; \ 67 | ./res generate test_file $a $l; \ 68 | for m in sys lib; \ 69 | do \ 70 | cp test_file test_file_temp; \ 71 | echo "$m copy file with $a records of size $l"; \ 72 | ./res copy test_file_temp test_copy $a $l $m; \ 73 | rm test_file_temp; \ 74 | rm test_copy; \ 75 | done; \ 76 | rm test_file; \ 77 | done; \ 78 | done 79 | creating file with 3000 records of size 4 80 | Real User System 81 | 0.010000 0.000000 0.000000 82 | sys copy file with 3000 records of size 4 83 | Real User System 84 | 0.010000 0.000000 0.010000 85 | lib copy file with 3000 records of size 4 86 | Real User System 87 | 0.000000 0.000000 0.000000 88 | creating file with 10000 records of size 4 89 | Real User System 90 | 0.010000 0.000000 0.000000 91 | sys copy file with 10000 records of size 4 92 | Real User System 93 | 0.060000 0.000000 0.050000 94 | lib copy file with 10000 records of size 4 95 | Real User System 96 | 0.000000 0.000000 0.000000 97 | creating file with 60000 records of size 4 98 | Real User System 99 | 0.040000 0.010000 0.020000 100 | sys copy file with 60000 records of size 4 101 | Real User System 102 | 0.370000 0.010000 0.350000 103 | lib copy file with 60000 records of size 4 104 | Real User System 105 | 0.000000 0.000000 0.000000 106 | creating file with 120000 records of size 4 107 | Real User System 108 | 0.060000 0.010000 0.040000 109 | sys copy file with 120000 records of size 4 110 | Real User System 111 | 0.760000 0.020000 0.730000 112 | lib copy file with 120000 records of size 4 113 | Real User System 114 | 0.020000 0.010000 0.000000 115 | creating file with 3000 records of size 512 116 | Real User System 117 | 0.120000 0.000000 0.110000 118 | sys copy file with 3000 records of size 512 119 | Real User System 120 | 0.030000 0.000000 0.020000 121 | lib copy file with 3000 records of size 512 122 | Real User System 123 | 0.000000 0.000000 0.000000 124 | creating file with 10000 records of size 512 125 | Real User System 126 | 0.380000 0.000000 0.370000 127 | sys copy file with 10000 records of size 512 128 | Real User System 129 | 0.080000 0.000000 0.070000 130 | lib copy file with 10000 records of size 512 131 | Real User System 132 | 0.010000 0.000000 0.000000 133 | creating file with 60000 records of size 512 134 | Real User System 135 | 2.270000 0.020000 2.230000 136 | sys copy file with 60000 records of size 512 137 | Real User System 138 | 0.450000 0.010000 0.420000 139 | lib copy file with 60000 records of size 512 140 | Real User System 141 | 0.030000 0.010000 0.020000 142 | creating file with 120000 records of size 512 143 | Real User System 144 | 4.510000 0.050000 4.410000 145 | sys copy file with 120000 records of size 512 146 | Real User System 147 | 0.880000 0.020000 0.840000 148 | lib copy file with 120000 records of size 512 149 | Real User System 150 | 0.060000 0.010000 0.040000 151 | creating file with 3000 records of size 4096 152 | Real User System 153 | 0.890000 0.000000 0.880000 154 | sys copy file with 3000 records of size 4096 155 | Real User System 156 | 0.050000 0.000000 0.040000 157 | lib copy file with 3000 records of size 4096 158 | Real User System 159 | 0.010000 0.000000 0.000000 160 | creating file with 10000 records of size 4096 161 | Real User System 162 | 3.000000 0.030000 2.940000 163 | sys copy file with 10000 records of size 4096 164 | Real User System 165 | 0.160000 0.000000 0.140000 166 | lib copy file with 10000 records of size 4096 167 | Real User System 168 | 0.040000 0.000000 0.020000 169 | creating file with 60000 records of size 4096 170 | Real User System 171 | 18.480000 0.190000 18.030000 172 | sys copy file with 60000 records of size 4096 173 | Real User System 174 | 1.100000 0.010000 1.000000 175 | lib copy file with 60000 records of size 4096 176 | Real User System 177 | 0.230000 0.020000 0.140000 178 | creating file with 120000 records of size 4096 179 | Real User System 180 | 36.250000 0.370000 35.410000 181 | sys copy file with 120000 records of size 4096 182 | Real User System 183 | 1.610000 0.020000 1.460000 184 | lib copy file with 120000 records of size 4096 185 | Real User System 186 | 0.550000 0.040000 0.320000 187 | creating file with 3000 records of size 8192 188 | Real User System 189 | 1.790000 0.010000 1.760000 190 | sys copy file with 3000 records of size 8192 191 | Real User System 192 | 0.060000 0.000000 0.040000 193 | lib copy file with 3000 records of size 8192 194 | Real User System 195 | 0.020000 0.000000 0.010000 196 | creating file with 10000 records of size 8192 197 | Real User System 198 | 5.990000 0.060000 5.880000 199 | sys copy file with 10000 records of size 8192 200 | Real User System 201 | 0.190000 0.000000 0.150000 202 | lib copy file with 10000 records of size 8192 203 | Real User System 204 | 0.070000 0.000000 0.040000 205 | creating file with 60000 records of size 8192 206 | Real User System 207 | 35.870000 0.350000 35.070000 208 | sys copy file with 60000 records of size 8192 209 | Real User System 210 | 1.070000 0.010000 0.940000 211 | lib copy file with 60000 records of size 8192 212 | Real User System 213 | 0.670000 0.030000 0.340000 214 | creating file with 120000 records of size 8192 215 | Real User System 216 | 72.220000 0.720000 70.690000 217 | sys copy file with 120000 records of size 8192 218 | Real User System 219 | 2.180000 0.020000 1.770000 220 | lib copy file with 120000 records of size 8192 221 | Real User System 222 | 1.190000 0.070000 0.670000 223 | #sort test 224 | for l in 4 512 4096 8192; \ 225 | do \ 226 | for a in 1000 3000 10000; \ 227 | do \ 228 | echo "creating file with $a records of size $l"; \ 229 | ./res generate test_file $a $l; \ 230 | for m in sys lib; \ 231 | do \ 232 | cp test_file test_file_temp; \ 233 | echo "$m sorting file with $a records of size $l"; \ 234 | ./res sort test_file_temp $a $l $m; \ 235 | rm test_file_temp; \ 236 | done; \ 237 | rm test_file; \ 238 | done; \ 239 | done 240 | creating file with 1000 records of size 4 241 | Real User System 242 | 0.000000 0.000000 0.000000 243 | sys sorting file with 1000 records of size 4 244 | Real User System 245 | 0.500000 0.090000 0.400000 246 | lib sorting file with 1000 records of size 4 247 | Real User System 248 | 0.700000 0.170000 0.520000 249 | creating file with 3000 records of size 4 250 | Real User System 251 | 0.000000 0.000000 0.000000 252 | sys sorting file with 3000 records of size 4 253 | Real User System 254 | 4.240000 0.800000 3.400000 255 | lib sorting file with 3000 records of size 4 256 | Real User System 257 | 7.530000 1.600000 5.780000 258 | creating file with 10000 records of size 4 259 | Real User System 260 | 0.010000 0.000000 0.000000 261 | sys sorting file with 10000 records of size 4 262 | Real User System 263 | 52.260000 9.960000 41.290000 264 | lib sorting file with 10000 records of size 4 265 | Real User System 266 | 139.290000 17.650000 121.510000 267 | creating file with 1000 records of size 512 268 | Real User System 269 | 0.050000 0.000000 0.040000 270 | sys sorting file with 1000 records of size 512 271 | Real User System 272 | 0.530000 0.090000 0.430000 273 | lib sorting file with 1000 records of size 512 274 | Real User System 275 | 2.240000 0.190000 2.040000 276 | creating file with 3000 records of size 512 277 | Real User System 278 | 0.120000 0.000000 0.110000 279 | sys sorting file with 3000 records of size 512 280 | Real User System 281 | 4.300000 0.790000 3.500000 282 | lib sorting file with 3000 records of size 512 283 | Real User System 284 | 20.020000 1.670000 18.300000 285 | creating file with 10000 records of size 512 286 | Real User System 287 | 0.370000 0.000000 0.360000 288 | sys sorting file with 10000 records of size 512 289 | Real User System 290 | 46.750000 8.750000 37.950000 291 | lib sorting file with 10000 records of size 512 292 | Real User System 293 | 218.000000 18.050000 199.710000 294 | creating file with 1000 records of size 4096 295 | Real User System 296 | 0.300000 0.000000 0.290000 297 | sys sorting file with 1000 records of size 4096 298 | Real User System 299 | 0.700000 0.090000 0.600000 300 | lib sorting file with 1000 records of size 4096 301 | Real User System 302 | creating file with 3000 records of size 4096 303 | Real User System 304 | 0.940000 0.010000 0.920000 305 | sys sorting file with 3000 records of size 4096 306 | Real User System 307 | 6.550000 0.830000 5.700000 308 | lib sorting file with 3000 records of size 4096 309 | Real User System 310 | 21.080000 2.050000 19.000000 311 | creating file with 10000 records of size 4096 312 | Real User System 313 | 2.970000 0.030000 2.920000 314 | sys sorting file with 10000 records of size 4096 315 | Real User System 316 | 71.050000 9.030000 61.950000 317 | lib sorting file with 10000 records of size 4096 318 | Real User System 319 | 232.440000 23.090000 208.930000 320 | creating file with 1000 records of size 8192 321 | Real User System 322 | 0.600000 0.000000 0.580000 323 | sys sorting file with 1000 records of size 8192 324 | Real User System 325 | 0.920000 0.090000 0.820000 326 | lib sorting file with 1000 records of size 8192 327 | Real User System 328 | 2.660000 0.290000 2.360000 329 | creating file with 3000 records of size 8192 330 | Real User System 331 | 1.790000 0.010000 1.750000 332 | sys sorting file with 3000 records of size 8192 333 | Real User System 334 | 8.450000 0.860000 7.490000 335 | lib sorting file with 3000 records of size 8192 336 | Real User System 337 | 25.280000 2.870000 22.080000 338 | creating file with 10000 records of size 8192 339 | Real User System 340 | 6.300000 0.060000 6.180000 341 | sys sorting file with 10000 records of size 8192 342 | Real User System 343 | 105.650000 10.350000 94.620000 344 | lib sorting file with 10000 records of size 8192 345 | Real User System 346 | 260.440000 28.730000 231.250000 347 | -------------------------------------------------------------------------------- /zestaw2/zad1/ubuntu_tests.txt: -------------------------------------------------------------------------------- 1 | gcc -std=c11 -o res main.c -O2 2 | #compiled 3 | #generate 4 | for l in 4 512 4096 8192; \ 5 | do \ 6 | for a in 3000 10000 60000 120000; \ 7 | do \ 8 | echo "creating file with $a records of size $l"; \ 9 | ./res generate test_file $a $l; \ 10 | rm test_file; \ 11 | done; \ 12 | done 13 | creating file with 3000 records of size 4 14 | Real User System 15 | 0.010000 0.000000 0.000000 16 | creating file with 10000 records of size 4 17 | Real User System 18 | 0.000000 0.000000 0.000000 19 | creating file with 60000 records of size 4 20 | Real User System 21 | 0.010000 0.000000 0.000000 22 | creating file with 120000 records of size 4 23 | Real User System 24 | 0.000000 0.000000 0.000000 25 | creating file with 3000 records of size 512 26 | Real User System 27 | 0.020000 0.000000 0.000000 28 | creating file with 10000 records of size 512 29 | Real User System 30 | 0.050000 0.010000 0.040000 31 | creating file with 60000 records of size 512 32 | Real User System 33 | 0.350000 0.080000 0.260000 34 | creating file with 120000 records of size 512 35 | Real User System 36 | 0.740000 0.190000 0.540000 37 | creating file with 3000 records of size 4096 38 | Real User System 39 | 0.130000 0.040000 0.080000 40 | creating file with 10000 records of size 4096 41 | Real User System 42 | 0.450000 0.090000 0.320000 43 | creating file with 60000 records of size 4096 44 | Real User System 45 | 2.600000 0.790000 1.800000 46 | creating file with 120000 records of size 4096 47 | Real User System 48 | 4.960000 1.320000 3.630000 49 | creating file with 3000 records of size 8192 50 | Real User System 51 | 0.220000 0.060000 0.150000 52 | creating file with 10000 records of size 8192 53 | Real User System 54 | 0.800000 0.180000 0.610000 55 | creating file with 60000 records of size 8192 56 | Real User System 57 | 4.900000 1.410000 3.460000 58 | creating file with 120000 records of size 8192 59 | Real User System 60 | 9.620000 2.460000 7.150000 61 | #copy test 62 | for l in 4 512 4096 8192; \ 63 | do \ 64 | for a in 3000 10000 60000 120000; \ 65 | do \ 66 | echo "creating file with $a records of size $l"; \ 67 | ./res generate test_file $a $l; \ 68 | for m in sys lib; \ 69 | do \ 70 | cp test_file test_file_temp; \ 71 | echo "$m copy file with $a records of size $l"; \ 72 | ./res copy test_file_temp test_copy $a $l $m; \ 73 | rm test_file_temp; \ 74 | rm test_copy; \ 75 | done; \ 76 | rm test_file; \ 77 | done; \ 78 | done 79 | creating file with 3000 records of size 4 80 | Real User System 81 | 0.000000 0.000000 0.000000 82 | sys copy file with 3000 records of size 4 83 | Real User System 84 | 0.010000 0.000000 0.000000 85 | lib copy file with 3000 records of size 4 86 | Real User System 87 | 0.000000 0.000000 0.000000 88 | creating file with 10000 records of size 4 89 | Real User System 90 | 0.000000 0.000000 0.000000 91 | sys copy file with 10000 records of size 4 92 | Real User System 93 | 0.020000 0.000000 0.010000 94 | lib copy file with 10000 records of size 4 95 | Real User System 96 | 0.000000 0.000000 0.000000 97 | creating file with 60000 records of size 4 98 | Real User System 99 | 0.000000 0.000000 0.000000 100 | sys copy file with 60000 records of size 4 101 | Real User System 102 | 0.070000 0.000000 0.070000 103 | lib copy file with 60000 records of size 4 104 | Real User System 105 | 0.000000 0.000000 0.000000 106 | creating file with 120000 records of size 4 107 | Real User System 108 | 0.010000 0.000000 0.000000 109 | sys copy file with 120000 records of size 4 110 | Real User System 111 | 0.160000 0.000000 0.150000 112 | lib copy file with 120000 records of size 4 113 | Real User System 114 | 0.010000 0.000000 0.000000 115 | creating file with 3000 records of size 512 116 | Real User System 117 | 0.020000 0.000000 0.000000 118 | sys copy file with 3000 records of size 512 119 | Real User System 120 | 0.010000 0.000000 0.000000 121 | lib copy file with 3000 records of size 512 122 | Real User System 123 | 0.000000 0.000000 0.000000 124 | creating file with 10000 records of size 512 125 | Real User System 126 | 0.060000 0.020000 0.030000 127 | sys copy file with 10000 records of size 512 128 | Real User System 129 | 0.020000 0.000000 0.010000 130 | lib copy file with 10000 records of size 512 131 | Real User System 132 | 0.000000 0.000000 0.000000 133 | creating file with 60000 records of size 512 134 | Real User System 135 | 0.330000 0.130000 0.200000 136 | sys copy file with 60000 records of size 512 137 | Real User System 138 | 0.100000 0.000000 0.100000 139 | lib copy file with 60000 records of size 512 140 | Real User System 141 | 0.040000 0.000000 0.020000 142 | creating file with 120000 records of size 512 143 | Real User System 144 | 0.620000 0.210000 0.400000 145 | sys copy file with 120000 records of size 512 146 | Real User System 147 | 0.220000 0.010000 0.200000 148 | lib copy file with 120000 records of size 512 149 | Real User System 150 | 0.080000 0.020000 0.050000 151 | creating file with 3000 records of size 4096 152 | Real User System 153 | 0.140000 0.060000 0.070000 154 | sys copy file with 3000 records of size 4096 155 | Real User System 156 | 0.010000 0.000000 0.000000 157 | lib copy file with 3000 records of size 4096 158 | Real User System 159 | 0.010000 0.000000 0.010000 160 | creating file with 10000 records of size 4096 161 | Real User System 162 | 0.460000 0.120000 0.330000 163 | sys copy file with 10000 records of size 4096 164 | Real User System 165 | 0.050000 0.000000 0.040000 166 | lib copy file with 10000 records of size 4096 167 | Real User System 168 | 0.040000 0.000000 0.030000 169 | creating file with 60000 records of size 4096 170 | Real User System 171 | 2.550000 0.670000 1.880000 172 | sys copy file with 60000 records of size 4096 173 | Real User System 174 | 0.260000 0.000000 0.250000 175 | lib copy file with 60000 records of size 4096 176 | Real User System 177 | 0.240000 0.040000 0.180000 178 | creating file with 120000 records of size 4096 179 | Real User System 180 | 5.160000 1.340000 3.810000 181 | sys copy file with 120000 records of size 4096 182 | Real User System 183 | 1.480000 0.010000 0.760000 184 | lib copy file with 120000 records of size 4096 185 | Real User System 186 | 0.750000 0.090000 0.420000 187 | creating file with 3000 records of size 8192 188 | Real User System 189 | 0.240000 0.020000 0.200000 190 | sys copy file with 3000 records of size 8192 191 | Real User System 192 | 0.020000 0.000000 0.020000 193 | lib copy file with 3000 records of size 8192 194 | Real User System 195 | 0.020000 0.000000 0.010000 196 | creating file with 10000 records of size 8192 197 | Real User System 198 | 0.900000 0.260000 0.620000 199 | sys copy file with 10000 records of size 8192 200 | Real User System 201 | 0.070000 0.000000 0.060000 202 | lib copy file with 10000 records of size 8192 203 | Real User System 204 | 0.070000 0.000000 0.060000 205 | creating file with 60000 records of size 8192 206 | Real User System 207 | 4.820000 1.270000 3.530000 208 | sys copy file with 60000 records of size 8192 209 | Real User System 210 | 1.420000 0.000000 0.620000 211 | lib copy file with 60000 records of size 8192 212 | Real User System 213 | 0.800000 0.040000 0.380000 214 | creating file with 120000 records of size 8192 215 | Real User System 216 | 9.930000 2.500000 7.170000 217 | sys copy file with 120000 records of size 8192 218 | Real User System 219 | 3.630000 0.000000 0.770000 220 | lib copy file with 120000 records of size 8192 221 | Real User System 222 | 3.030000 0.120000 0.770000 223 | #sort test 224 | for l in 4 512 4096 8192; \ 225 | do \ 226 | for a in 1000 3000 10000; \ 227 | do \ 228 | echo "creating file with $a records of size $l"; \ 229 | ./res generate test_file $a $l; \ 230 | for m in sys lib; \ 231 | do \ 232 | cp test_file test_file_temp; \ 233 | echo "$m sorting file with $a records of size $l"; \ 234 | ./res sort test_file_temp $a $l $m; \ 235 | rm test_file_temp; \ 236 | done; \ 237 | rm test_file; \ 238 | done; \ 239 | done 240 | creating file with 1000 records of size 4 241 | Real User System 242 | 0.000000 0.000000 0.000000 243 | sys sorting file with 1000 records of size 4 244 | Real User System 245 | 0.230000 0.020000 0.200000 246 | lib sorting file with 1000 records of size 4 247 | Real User System 248 | 0.110000 0.050000 0.050000 249 | creating file with 3000 records of size 4 250 | Real User System 251 | 0.010000 0.000000 0.000000 252 | sys sorting file with 3000 records of size 4 253 | Real User System 254 | 1.670000 0.230000 1.400000 255 | lib sorting file with 3000 records of size 4 256 | Real User System 257 | 0.610000 0.270000 0.310000 258 | creating file with 10000 records of size 4 259 | Real User System 260 | 0.000000 0.000000 0.000000 261 | sys sorting file with 10000 records of size 4 262 | Real User System 263 | 18.400000 2.180000 15.980000 264 | lib sorting file with 10000 records of size 4 265 | Real User System 266 | 5.140000 2.510000 2.620000 267 | creating file with 1000 records of size 512 268 | Real User System 269 | 0.000000 0.000000 0.000000 270 | sys sorting file with 1000 records of size 512 271 | Real User System 272 | 0.200000 0.010000 0.180000 273 | lib sorting file with 1000 records of size 512 274 | Real User System 275 | 0.140000 0.060000 0.070000 276 | creating file with 3000 records of size 512 277 | Real User System 278 | 0.010000 0.000000 0.000000 279 | sys sorting file with 3000 records of size 512 280 | Real User System 281 | 1.760000 0.210000 1.540000 282 | lib sorting file with 3000 records of size 512 283 | Real User System 284 | 1.210000 0.530000 0.660000 285 | creating file with 10000 records of size 512 286 | Real User System 287 | 0.050000 0.020000 0.020000 288 | sys sorting file with 10000 records of size 512 289 | Real User System 290 | 22.960000 2.350000 20.440000 291 | lib sorting file with 10000 records of size 512 292 | Real User System 293 | 16.300000 6.490000 8.900000 294 | creating file with 1000 records of size 4096 295 | Real User System 296 | 0.050000 0.010000 0.020000 297 | sys sorting file with 1000 records of size 4096 298 | Real User System 299 | 0.650000 0.030000 0.600000 300 | lib sorting file with 1000 records of size 4096 301 | Real User System 302 | 0.620000 0.140000 0.470000 303 | creating file with 3000 records of size 4096 304 | Real User System 305 | 0.160000 0.030000 0.110000 306 | sys sorting file with 3000 records of size 4096 307 | Real User System 308 | 4.800000 0.230000 4.500000 309 | lib sorting file with 3000 records of size 4096 310 | Real User System 311 | 5.400000 1.250000 4.090000 312 | creating file with 10000 records of size 4096 313 | Real User System 314 | 0.500000 0.140000 0.300000 315 | sys sorting file with 10000 records of size 4096 316 | Real User System 317 | 53.810000 2.650000 49.490000 318 | lib sorting file with 10000 records of size 4096 319 | Real User System 320 | 59.460000 14.550000 44.340000 321 | creating file with 1000 records of size 8192 322 | Real User System 323 | 0.100000 0.020000 0.070000 324 | sys sorting file with 1000 records of size 8192 325 | Real User System 326 | 0.930000 0.020000 0.880000 327 | lib sorting file with 1000 records of size 8192 328 | Real User System 329 | 1.130000 0.200000 0.910000 330 | creating file with 3000 records of size 8192 331 | Real User System 332 | 0.300000 0.100000 0.180000 333 | sys sorting file with 3000 records of size 8192 334 | Real User System 335 | 7.830000 0.250000 7.530000 336 | lib sorting file with 3000 records of size 8192 337 | Real User System 338 | 9.860000 1.750000 7.970000 339 | creating file with 10000 records of size 8192 340 | Real User System 341 | 1.030000 0.220000 0.790000 342 | sys sorting file with 10000 records of size 8192 343 | Real User System 344 | 88.360000 3.130000 84.640000 345 | lib sorting file with 10000 records of size 8192 346 | Real User System 347 | 103.320000 17.060000 86.060000 348 | -------------------------------------------------------------------------------- /zestaw2/zad1/wyniki.txt: -------------------------------------------------------------------------------- 1 | OS_X sys is generally faster when it comes to great number of r/w. Otherwise lib is better 2 | ubuntu lib jest hardly always faster. When it comes to the most extreme cases sys is getting a little bit faster e.g. 3 | sys sorting file with 10000 records of size 8192 4 | Real User System 5 | 88.360000 3.130000 84.640000 6 | lib sorting file with 10000 records of size 8192 7 | Real User System 8 | 103.320000 17.060000 86.060000 9 | -------------------------------------------------------------------------------- /zestaw2/zad2/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 18/03/2018. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | const char format[] = "%Y-%m-%d %H:%M:%S"; 19 | char buffer[PATH_MAX]; 20 | time_t gdate; 21 | char *goperant; 22 | 23 | double date_compare(time_t date_1, time_t date_2) { 24 | return difftime(date_1, date_2); 25 | } 26 | 27 | void print_info(const char *path, const struct stat *file_stat) { 28 | printf(" %lld\t", file_stat->st_size); 29 | printf((file_stat->st_mode & S_IRUSR) ? "r" : "-"); 30 | printf((file_stat->st_mode & S_IWUSR) ? "w" : "-"); 31 | printf((file_stat->st_mode & S_IXUSR) ? "x" : "-"); 32 | printf((file_stat->st_mode & S_IRGRP) ? "r" : "-"); 33 | printf((file_stat->st_mode & S_IWGRP) ? "w" : "-"); 34 | printf((file_stat->st_mode & S_IXGRP) ? "x" : "-"); 35 | printf((file_stat->st_mode & S_IROTH) ? "r" : "-"); 36 | printf((file_stat->st_mode & S_IWOTH) ? "w" : "-"); 37 | printf((file_stat->st_mode & S_IXOTH) ? "x" : "-"); 38 | strftime(buffer, PATH_MAX, format, localtime(&file_stat->st_mtime)); 39 | printf(" %s\t", buffer); 40 | printf(" %s\t", path); 41 | printf("\n"); 42 | } 43 | 44 | static int nftw_display(const char *fpath, const struct stat *file_stat, int typeflag, struct FTW *ftwbuf) { 45 | struct tm mtime; 46 | 47 | (void) localtime_r(&file_stat->st_mtime, &mtime); 48 | 49 | if (typeflag != FTW_F) { 50 | return 0; 51 | } 52 | 53 | int comparison_result = date_compare(gdate, file_stat->st_mtime); 54 | if (!( 55 | (comparison_result == 0 && strcmp(goperant, "=") == 0) 56 | || (comparison_result > 0 && strcmp(goperant, "<") == 0) 57 | || (comparison_result < 0 && strcmp(goperant, ">") == 0) 58 | )) { 59 | return 0; 60 | } 61 | print_info(fpath, file_stat); 62 | return 0; 63 | } 64 | 65 | 66 | void dir_follow(char *path, char *operant, time_t date) { 67 | if (path == NULL) 68 | return; 69 | DIR *dir = opendir(path); 70 | 71 | 72 | if (dir == NULL) { 73 | printf("%s\n", "error!"); 74 | return; 75 | } 76 | 77 | struct dirent *rdir = readdir(dir); 78 | struct stat file_stat; 79 | 80 | char new_path[PATH_MAX]; 81 | 82 | while (rdir != NULL) { 83 | strcpy(new_path, path); 84 | strcat(new_path, "/"); 85 | strcat(new_path, rdir->d_name); 86 | 87 | 88 | lstat(new_path, &file_stat); // with symlinks 89 | 90 | if (strcmp(rdir->d_name, ".") == 0 || strcmp(rdir->d_name, "..") == 0) { 91 | rdir = readdir(dir); 92 | continue; 93 | } else { 94 | if (S_ISREG(file_stat.st_mode)) { 95 | if (strcmp(operant, "=") == 0 && date_compare(date, file_stat.st_mtime) == 0) { 96 | print_info(new_path, &file_stat); 97 | } else if (strcmp(operant, "<") == 0 && date_compare(date, file_stat.st_mtime) > 0) { 98 | print_info(new_path, &file_stat); 99 | } else if (strcmp(operant, ">") == 0 && date_compare(date, file_stat.st_mtime) < 0) { 100 | print_info(new_path, &file_stat); 101 | } 102 | } 103 | 104 | 105 | if (S_ISDIR(file_stat.st_mode)) { 106 | dir_follow(new_path, operant, date); 107 | } 108 | rdir = readdir(dir); 109 | } 110 | } 111 | closedir(dir); 112 | } 113 | 114 | 115 | 116 | int main(int argc, char **argv) { 117 | 118 | if (argc < 4) { 119 | printf("Bad args!"); 120 | return 1; 121 | } 122 | 123 | 124 | char *path = argv[1]; 125 | char *operant = argv[2]; 126 | char *usr_date = argv[3]; 127 | 128 | struct tm *timestamp = malloc(sizeof(struct tm)); 129 | 130 | strptime(usr_date, format, timestamp); 131 | time_t date = mktime(timestamp); 132 | 133 | 134 | DIR *dir = opendir(realpath(path, NULL)); 135 | if (dir == NULL) { 136 | printf("couldnt open the directory\n"); 137 | return 1; 138 | } 139 | 140 | printf("%s", "\n\n Naive \n\n"); 141 | 142 | 143 | dir_follow(realpath(path, NULL), operant, date); 144 | 145 | printf("\n\n\n"); 146 | gdate = date; // global args for nftw 147 | goperant = operant; 148 | printf("%s", "\n\n NFTW \n\n"); 149 | nftw(realpath(path, NULL), nftw_display, 10, FTW_PHYS); 150 | 151 | closedir(dir); 152 | 153 | return 0; 154 | } 155 | -------------------------------------------------------------------------------- /zestaw3/zad1/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 18/03/2018. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | const char format[] = "%Y-%m-%d %H:%M:%S"; 19 | char buffer[PATH_MAX]; 20 | 21 | double date_compare(time_t date_1, time_t date_2) { 22 | return difftime(date_1, date_2); 23 | } 24 | 25 | void print_info(const char *path, const struct stat *file_stat) { 26 | printf(" %lld\t", file_stat->st_size); 27 | printf((file_stat->st_mode & S_IRUSR) ? "r" : "-"); 28 | printf((file_stat->st_mode & S_IWUSR) ? "w" : "-"); 29 | printf((file_stat->st_mode & S_IXUSR) ? "x" : "-"); 30 | printf((file_stat->st_mode & S_IRGRP) ? "r" : "-"); 31 | printf((file_stat->st_mode & S_IWGRP) ? "w" : "-"); 32 | printf((file_stat->st_mode & S_IXGRP) ? "x" : "-"); 33 | printf((file_stat->st_mode & S_IROTH) ? "r" : "-"); 34 | printf((file_stat->st_mode & S_IWOTH) ? "w" : "-"); 35 | printf((file_stat->st_mode & S_IXOTH) ? "x" : "-"); 36 | strftime(buffer, PATH_MAX, format, localtime(&file_stat->st_mtime)); 37 | printf(" %s\t", buffer); 38 | printf(" %s\t", path); 39 | printf("\n"); 40 | } 41 | 42 | void dir_follow(char *path, char *operant, time_t date) { 43 | if (path == NULL) 44 | return; 45 | DIR *dir = opendir(path); 46 | 47 | 48 | if (dir == NULL) { 49 | printf("%s\n", "error!"); 50 | return; 51 | } 52 | 53 | struct dirent *rdir = readdir(dir); 54 | struct stat file_stat; 55 | 56 | char new_path[PATH_MAX]; 57 | 58 | while (rdir != NULL) { 59 | strcpy(new_path, path); 60 | strcat(new_path, "/"); 61 | strcat(new_path, rdir->d_name); 62 | 63 | 64 | lstat(new_path, &file_stat); // with symlinks 65 | 66 | if (strcmp(rdir->d_name, ".") == 0 || strcmp(rdir->d_name, "..") == 0) { 67 | rdir = readdir(dir); 68 | continue; 69 | } else { 70 | if (S_ISREG(file_stat.st_mode)) { 71 | if (strcmp(operant, "=") == 0 && date_compare(date, file_stat.st_mtime) == 0) { 72 | print_info(new_path, &file_stat); 73 | } else if (strcmp(operant, "<") == 0 && date_compare(date, file_stat.st_mtime) > 0) { 74 | print_info(new_path, &file_stat); 75 | } else if (strcmp(operant, ">") == 0 && date_compare(date, file_stat.st_mtime) < 0) { 76 | print_info(new_path, &file_stat); 77 | } 78 | } 79 | 80 | 81 | if (S_ISDIR(file_stat.st_mode)) { 82 | pid_t fproc; 83 | if ((fproc = fork()) == 0) { 84 | dir_follow(new_path, operant, date); 85 | exit(0); 86 | } 87 | } 88 | rdir = readdir(dir); 89 | } 90 | } 91 | closedir(dir); 92 | } 93 | 94 | 95 | 96 | int main(int argc, char **argv) { 97 | 98 | if (argc < 4) { 99 | printf("Bad args!"); 100 | return 1; 101 | } 102 | 103 | 104 | char *path = argv[1]; 105 | char *operant = argv[2]; 106 | char *usr_date = argv[3]; 107 | 108 | struct tm *timestamp = malloc(sizeof(struct tm)); 109 | 110 | strptime(usr_date, format, timestamp); 111 | time_t date = mktime(timestamp); 112 | 113 | 114 | DIR *dir = opendir(realpath(path, NULL)); 115 | if (dir == NULL) { 116 | printf("couldnt open the directory\n"); 117 | return 1; 118 | } 119 | 120 | dir_follow(realpath(path, NULL), operant, date); 121 | 122 | closedir(dir); 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /zestaw3/zad2/breaker.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 25/03/2018. 3 | // 4 | #include 5 | 6 | int main() { 7 | int a [5]; 8 | a[6] = 10; 9 | return -1; 10 | } -------------------------------------------------------------------------------- /zestaw3/zad2/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 22/03/2018. 3 | // 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define max_number_of_arguments 64 14 | #define max_number_of_line 256 15 | 16 | int main(int argc, char **argv) { 17 | if(argc < 2) { 18 | printf("%s", "There's no enough argument! : ¯\\_(ツ)_/¯"); 19 | return 1; 20 | } 21 | FILE* file = fopen(argv[1], "r"); 22 | if (!file) { 23 | printf("%s", "I cannot open this file 🙄"); 24 | return 1; 25 | } 26 | char temp_registry[max_number_of_line]; 27 | char *parameters[max_number_of_arguments]; 28 | int argument_number = 0; 29 | while(fgets(temp_registry, max_number_of_line, file)){ 30 | argument_number = 0; 31 | while((parameters[argument_number] = strtok(argument_number == 0 ? temp_registry : NULL, " \n\t")) != NULL){ 32 | argument_number++; 33 | if(argument_number >= max_number_of_arguments){ 34 | printf( "You gave tooo many arguments sir to 🤔:"); 35 | for (int i = 0; i < argument_number; i++) { 36 | printf("%s ", parameters[i]); 37 | } 38 | return 1; 39 | } 40 | }; 41 | pid_t pid = fork(); 42 | if(pid == 0) { 43 | execvp(parameters[0], parameters); 44 | exit(1); 45 | } 46 | int status; 47 | wait(&status); 48 | if (status) { 49 | printf( "Error while executing 🤔:"); 50 | for (int i = 0; i < argument_number; i++) { 51 | printf("%s ", parameters[i]); 52 | } 53 | return 1; 54 | } 55 | } 56 | fclose(file); 57 | return 0; 58 | } -------------------------------------------------------------------------------- /zestaw3/zad2/sample: -------------------------------------------------------------------------------- 1 | ls -l -a 2 | echo xD 3 | sleep 2 4 | ./breaker 5 | echo hi -------------------------------------------------------------------------------- /zestaw3/zad3/big_cpu.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 25/03/2018. 3 | // 4 | #include 5 | #include 6 | #include 7 | 8 | void horse_fast_rider(); 9 | 10 | void horse_faster_rider(int i) { 11 | int n = (i + 1) % 10000; 12 | if (n == 0) { 13 | printf("Pls, staph, sir!\n"); 14 | } 15 | horse_fast_rider(n); 16 | } 17 | 18 | void horse_fast_rider(int i) { 19 | int *arr = malloc(100000 * sizeof(int)); 20 | for (int j=0; j<100000; j++) { 21 | arr[j]=j; 22 | } 23 | free(arr); 24 | horse_faster_rider(i+1); 25 | } 26 | 27 | int main() { 28 | horse_fast_rider(0); 29 | } 30 | -------------------------------------------------------------------------------- /zestaw3/zad3/big_data.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 25/03/2018. 3 | // 4 | #include 5 | 6 | int main() { 7 | int *dummy_array = malloc(sizeof(int) * 1000000000); 8 | for (int i = 0; i< 1000000000; i++) { 9 | dummy_array[i] = 9; 10 | } 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /zestaw3/zad3/breaker.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 25/03/2018. 3 | // 4 | #include 5 | 6 | int main() { 7 | return 1; 8 | } -------------------------------------------------------------------------------- /zestaw3/zad3/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 22/03/2018. 3 | // 4 | 5 | #define _DEFAULT_SOURCE 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | #define max_number_of_arguments 64 17 | #define max_number_of_line 256 18 | 19 | 20 | int handle_limits(char *time, char *memory) { 21 | long int time_limit = strtol(time, NULL, 10); 22 | struct rlimit r_limit_cpu; 23 | r_limit_cpu.rlim_max = (rlim_t) time_limit; 24 | r_limit_cpu.rlim_cur = (rlim_t) time_limit; 25 | if (setrlimit(RLIMIT_CPU, &r_limit_cpu) != 0) { 26 | printf("I cannot set this limit cpu 🙅"); 27 | return 1; 28 | } 29 | 30 | long int memory_limit = strtol(memory, NULL, 10) * 1024 * 1024; 31 | struct rlimit r_limit_memory; 32 | r_limit_memory.rlim_max = (rlim_t) memory_limit; 33 | r_limit_memory.rlim_cur = (rlim_t) memory_limit; 34 | 35 | if (setrlimit(RLIMIT_AS, &r_limit_memory) != 0) { 36 | printf("I cannot set this limit memory 🙅"); 37 | return 1; 38 | } 39 | return 0; 40 | } 41 | 42 | int main(int argc, char **argv) { 43 | if (argc < 4) { 44 | printf("%s", "There's no enough argument! Dont u forgot about limits, dear? : ¯\\_(ツ)_/¯"); 45 | return 1; 46 | } 47 | FILE *file = fopen(argv[1], "r"); 48 | if (!file) { 49 | printf("%s", "I cannot open this file 🙄"); 50 | return 1; 51 | } 52 | struct rusage prev_usage; 53 | getrusage(RUSAGE_CHILDREN, &prev_usage); 54 | char temp_registry[max_number_of_line]; 55 | char *parameters[max_number_of_arguments]; 56 | int argument_number = 0; 57 | while (fgets(temp_registry, max_number_of_line, file)) { 58 | argument_number = 0; 59 | while ((parameters[argument_number] = strtok(argument_number == 0 ? temp_registry : NULL, " \n\t")) != NULL) { 60 | argument_number++; 61 | if (argument_number >= max_number_of_arguments) { 62 | printf( "You gave tooo many arguments sir to 🤔:"); 63 | for (int i = 0; i < argument_number; i++) { 64 | printf("%s ", parameters[i]); 65 | } 66 | return 1; 67 | } 68 | }; 69 | pid_t pid = fork(); 70 | if (pid == 0) { 71 | handle_limits(argv[2], argv[3]); 72 | execvp(parameters[0], parameters); 73 | exit(1); 74 | } 75 | int status; 76 | wait(&status); 77 | if (status) { 78 | printf( "Error while executing 🤔:"); 79 | for (int i = 0; i < argument_number; i++) { 80 | printf("%s ", parameters[i]); 81 | } 82 | return 1; 83 | } 84 | struct rusage usage; 85 | getrusage(RUSAGE_CHILDREN, &usage); 86 | struct timeval ru_utime; 87 | struct timeval ru_stime; 88 | timersub(&usage.ru_utime, &prev_usage.ru_utime, &ru_utime); 89 | timersub(&usage.ru_stime, &prev_usage.ru_stime, &ru_stime); 90 | prev_usage = usage; 91 | for (int i = 0; i < argument_number; i++) { 92 | printf("%s ", parameters[i]); 93 | } 94 | printf("\n"); 95 | printf("User CPU time used: %d.%d seconds, system CPU time used: %d.%d seconds\n\n", (int) ru_utime.tv_sec, 96 | (int) ru_utime.tv_usec, (int) ru_stime.tv_sec, (int) ru_stime.tv_usec); 97 | } 98 | fclose(file); 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /zestaw3/zad3/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -std=c11 2 | 3 | 4 | prepare: 5 | $(CC) -o res main.c -O2 6 | $(CC) -o big_data big_data.c 7 | $(CC) -o big_cpu big_cpu.c 8 | 9 | -------------------------------------------------------------------------------- /zestaw3/zad3/sample: -------------------------------------------------------------------------------- 1 | echo hi 2 | ./big_data 3 | echo hi -------------------------------------------------------------------------------- /zestaw4/zad1/dater.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while true; do 4 | echo `date` 5 | sleep 1 6 | done -------------------------------------------------------------------------------- /zestaw4/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int awaiting_handler = 0; 8 | 9 | void stop_signal_toggle(int sig_num) { 10 | if(awaiting_handler == 0) { 11 | printf("\nOdebrano sygnał %d \nOczekuję na CTRL+Z - kontynuacja albo CTR+C - zakonczenie programu\n", sig_num); 12 | } 13 | awaiting_handler = awaiting_handler == 1 ? 0 : 1; 14 | } 15 | 16 | void init_signal(int sig_num) { 17 | printf("\nOdebrano sygnał SIGINT - %d\n", sig_num); 18 | exit(EXIT_SUCCESS); 19 | } 20 | 21 | int main(int argc, char** argv) { 22 | 23 | struct sigaction actions; 24 | actions.sa_handler = stop_signal_toggle; 25 | actions.sa_flags = 0; 26 | time_t act_time; 27 | sigemptyset(&actions.sa_mask); 28 | 29 | 30 | while(1) { 31 | sigaction(SIGTSTP, &actions, NULL); 32 | signal(SIGINT, init_signal); 33 | 34 | if (!awaiting_handler) { 35 | char buffer[30]; 36 | act_time = time(NULL); 37 | strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(&act_time)); 38 | printf("%s\n", buffer); 39 | } 40 | sleep(1); 41 | } 42 | } -------------------------------------------------------------------------------- /zestaw4/zad1/main_2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int awaiting_handler = 0; 8 | int is_dead_process_handler = 0; 9 | pid_t pid = 0; 10 | 11 | void stop_signal_toggle(int sig_num) { 12 | if(awaiting_handler == 0) { 13 | printf("\nOdebrano sygnał %d \nOczekuję na CTRL+Z - kontynuacja albo CTR+C - zakonczenie programu\n", sig_num); 14 | } 15 | awaiting_handler = awaiting_handler == 1 ? 0 : 1; 16 | } 17 | 18 | void init_signal(int sig_num) { 19 | printf("\nOdebrano sygnał SIGINT - %d\n", sig_num); 20 | exit(EXIT_SUCCESS); 21 | } 22 | 23 | int main(int argc, char** argv) { 24 | 25 | struct sigaction actions; 26 | actions.sa_handler = stop_signal_toggle; 27 | actions.sa_flags = 0; 28 | sigemptyset(&actions.sa_mask); 29 | 30 | pid = fork(); 31 | if (pid == 0){ 32 | execl("./dater.sh", "./dater.sh", NULL); 33 | exit(EXIT_SUCCESS); 34 | } 35 | 36 | while(1){ 37 | sigaction(SIGTSTP, &actions,NULL); 38 | signal(SIGINT,init_signal); 39 | 40 | if(awaiting_handler == 0) { 41 | if(is_dead_process_handler){ 42 | is_dead_process_handler = 0; 43 | 44 | pid = fork(); 45 | if (pid == 0){ 46 | execl("./dater.sh", "./dater.sh", NULL); 47 | exit(EXIT_SUCCESS); 48 | } 49 | } 50 | } else { 51 | if (is_dead_process_handler == 0) { 52 | kill(pid, SIGKILL); 53 | is_dead_process_handler = 1; 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /zestaw4/zad2/child.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void usrHandler(int signum) { 9 | kill(getppid(), SIGRTMIN + (rand() % (SIGRTMAX - SIGRTMIN))); 10 | } 11 | 12 | int main() { 13 | signal(SIGUSR1, usrHandler); 14 | sigset_t mask; 15 | sigfillset(&mask); 16 | sigdelset(&mask, SIGUSR1); 17 | 18 | srand((unsigned int) getpid()); 19 | int sleepTime = (rand() % 11); 20 | 21 | printf("Hi, Im %d, sleeping for %d\n", getpid(), sleepTime); 22 | fflush(stdout); 23 | sleep((unsigned int) sleepTime); 24 | 25 | kill(getppid(), SIGUSR1); 26 | 27 | sigsuspend(&mask); 28 | 29 | return sleepTime; 30 | } -------------------------------------------------------------------------------- /zestaw4/zad2/main.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define FAILURE_EXIT(code, format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(code);} 12 | #define WRITE_MSG(format, ...) { char buffer[255]; sprintf(buffer, format, ##__VA_ARGS__); write(1, buffer, strlen(buffer));} 13 | 14 | void intHandler(int, siginfo_t *, void *); 15 | 16 | void usrHandler(int, siginfo_t *, void *); 17 | 18 | void chldHandler(int, siginfo_t *, void *); 19 | 20 | void rtHandler(int, siginfo_t *, void *); 21 | 22 | volatile int N; 23 | volatile int K; 24 | volatile int n; 25 | volatile int k; 26 | volatile pid_t *childrenArr; 27 | volatile pid_t *awaitingArr; 28 | 29 | 30 | int checkIfChildren(pid_t pid) { 31 | for (int i = 0; i < N; i++) 32 | if (childrenArr[i] == pid) return i; 33 | return -1; 34 | } 35 | 36 | void removeChild(pid_t pid) { 37 | for (int i = 0; i < N; i++) 38 | if (childrenArr[i] == pid) { 39 | childrenArr[i] = -1; 40 | return; 41 | } 42 | } 43 | 44 | int main(int argc, char *argv[]) { 45 | if (argc < 3) FAILURE_EXIT(1, "Wrong execution. Use ./main VAL_N VAL_K\n"); 46 | N = (int) strtol(argv[1], '\0', 10); 47 | K = (int) strtol(argv[2], '\0', 10); 48 | if (N < 1) FAILURE_EXIT(1, "Wrong N\n"); 49 | if (K < 1) FAILURE_EXIT(1, "Wrong K\n"); 50 | if (N < K) FAILURE_EXIT(1, "K can't be larger than N\n"); 51 | 52 | childrenArr = calloc((size_t) N, sizeof(pid_t)); 53 | awaitingArr = calloc((size_t) N, sizeof(pid_t)); 54 | n = k = 0; 55 | 56 | struct sigaction act; 57 | sigemptyset(&act.sa_mask); 58 | act.sa_flags = SA_SIGINFO; 59 | 60 | act.sa_sigaction = intHandler; 61 | if (sigaction(SIGINT, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGINT\n") 62 | 63 | act.sa_sigaction = usrHandler; 64 | if (sigaction(SIGUSR1, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGUSR1\n") 65 | 66 | act.sa_sigaction = chldHandler; 67 | if (sigaction(SIGCHLD, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGCHLD\n") 68 | 69 | for (int i = SIGRTMIN; i <= SIGRTMAX; i++) { 70 | act.sa_sigaction = rtHandler; 71 | if (sigaction(i, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGRTMIN+%d\n", i - SIGRTMIN); 72 | } 73 | 74 | for (int i = 0; i < N; i++) { 75 | pid_t pid = fork(); 76 | if (!pid) { 77 | execl("./child", "./child", NULL); 78 | FAILURE_EXIT(2, "Error creating child process\n"); 79 | } else { 80 | childrenArr[n++] = pid; 81 | } 82 | } 83 | 84 | while (wait(NULL)) 85 | if (errno == ECHILD) FAILURE_EXIT(2, "ERROR CHILD\n"); 86 | } 87 | 88 | void intHandler(int signum, siginfo_t *info, void *context) { 89 | WRITE_MSG("\rMother: Received SIGINT\n"); 90 | 91 | for (int i = 0; i < N; i++) 92 | if (childrenArr[i] != -1) { 93 | kill(childrenArr[i], SIGKILL); 94 | waitpid(childrenArr[i], NULL, 0); 95 | } 96 | 97 | exit(0); 98 | } 99 | 100 | void usrHandler(int signum, siginfo_t *info, void *context) { 101 | WRITE_MSG("Mother: Received SIGUSR1 form PID: %d\n", info->si_pid); 102 | 103 | if (checkIfChildren(info->si_pid) == -1)return; 104 | 105 | if (k >= K) { 106 | WRITE_MSG("Mother: Sending SIGUSR1 to Child PID: %d\n", info->si_pid); 107 | kill(info->si_pid, SIGUSR1); 108 | waitpid(info->si_pid, NULL, 0); 109 | } else { 110 | awaitingArr[k++] = info->si_pid; 111 | if (k >= K) { 112 | for (int i = 0; i < K; i++) { 113 | if (awaitingArr[i] > 0) { 114 | WRITE_MSG("Mother: Sending SIGUSR1 to Child PID: %d\n", awaitingArr[i]); 115 | kill(awaitingArr[i], SIGUSR1); 116 | waitpid(awaitingArr[i], NULL, 0); 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | void chldHandler(int signum, siginfo_t *info, void *context) { 124 | if (info->si_code == CLD_EXITED) { 125 | WRITE_MSG("Mother: Child %d has terminated, with exit status: %d\n", info->si_pid, info->si_status); 126 | } else { 127 | WRITE_MSG("Mother: Child %d has terminated by signal: %d\n", info->si_pid, info->si_status); 128 | } 129 | n--; 130 | if (n == 0) { 131 | WRITE_MSG("Mother: No more children, Terminating\n"); 132 | exit(0); 133 | } 134 | removeChild(info->si_status); 135 | } 136 | 137 | void rtHandler(int signum, siginfo_t *info, void *context) { 138 | WRITE_MSG("Mother: Received SIGRT: SIGMIN+%i, for PID: %d\n", signum - SIGRTMIN, info->si_pid); 139 | } -------------------------------------------------------------------------------- /zestaw4/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=gnu99 -Wall 3 | MAIN_SRC = main 4 | OPTIM ?= -O2 5 | 6 | all: 7 | $(CC) $(FLAGS) $(MAIN_SRC).c -o $(MAIN_SRC) 8 | $(CC) $(FLAGS) child.c -o child 9 | 10 | clean: 11 | rm $(MAIN_SRC) 12 | rm child -------------------------------------------------------------------------------- /zestaw4/zad3/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 09/04/2018. 3 | // 4 | 5 | #define _GNU_SOURCE 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define FAILURE_EXIT(code, format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(code);} 14 | #define WRITE_MSG(format, ...) { char buffer[255]; sprintf(buffer, format, ##__VA_ARGS__); write(1, buffer, strlen(buffer));} 15 | 16 | void childHandler(int, siginfo_t *, void *); 17 | 18 | void motherHandler(int, siginfo_t *, void *); 19 | 20 | void childProcess(); 21 | 22 | void motherProcess(); 23 | 24 | volatile int L; 25 | volatile int TYPE; 26 | volatile int sentToChild = 0; 27 | volatile int receivedByChild = 0; 28 | volatile int receivedFromChild = 0; 29 | volatile pid_t child; 30 | 31 | void printStats() { 32 | printf("Signals sent: %d\n", sentToChild); 33 | printf("Signals received from child: %d\n", receivedFromChild); 34 | } 35 | 36 | int main(int argc, char *argv[]) { 37 | 38 | if (argc < 3) FAILURE_EXIT(1, "Wrong execution. Use ./main VAL_L VAL_TYPE\n"); 39 | L = (int) strtol(argv[1], '\0', 10); 40 | TYPE = (int) strtol(argv[2], '\0', 10); 41 | 42 | if (L < 1) FAILURE_EXIT(1, "Wrong L Argument\n") 43 | if (TYPE < 1 || TYPE > 3) FAILURE_EXIT(1, "Wrong Type Argument\n") 44 | 45 | child = fork(); 46 | if (!child) childProcess(); 47 | else if (child > 0) motherProcess(); 48 | else FAILURE_EXIT(2, "Error while Forking\n"); 49 | 50 | printStats(); 51 | 52 | return 0; 53 | } 54 | 55 | void childHandler(int signum, siginfo_t *info, void *context) { 56 | if (signum == SIGINT) { 57 | sigset_t mask; 58 | sigfillset(&mask); 59 | sigprocmask(SIG_SETMASK, &mask, NULL); 60 | WRITE_MSG("Signals received by child: %d\n", receivedByChild); 61 | exit((unsigned) receivedByChild); 62 | } 63 | if (info->si_pid != getppid()) return; 64 | 65 | if (TYPE == 1 || TYPE == 2) { 66 | if (signum == SIGUSR1) { 67 | receivedByChild++; 68 | kill(getppid(), SIGUSR1); 69 | WRITE_MSG("Child: SIGUSR1 received and sent back\n") 70 | } else if (signum == SIGUSR2) { 71 | receivedByChild++; 72 | WRITE_MSG("Child: SIGUSR2 received Terminating\n") 73 | WRITE_MSG("Signals received by child: %d\n", receivedByChild); 74 | exit((unsigned) receivedByChild); 75 | } 76 | } else if (TYPE == 3) { 77 | if (signum == SIGRTMIN) { 78 | receivedByChild++; 79 | kill(getppid(), SIGRTMIN); 80 | WRITE_MSG("Child: SIGRTMIN received and sent back\n") 81 | } else if (signum == SIGRTMAX) { 82 | receivedByChild++; 83 | WRITE_MSG("Child: SIGRTMAX received Terminating\n") 84 | WRITE_MSG("Signals received by child: %d\n", receivedByChild); 85 | exit((unsigned) receivedByChild); 86 | } 87 | } 88 | } 89 | 90 | 91 | void motherHandler(int signum, siginfo_t *info, void *context) { 92 | if (signum == SIGINT) { 93 | WRITE_MSG("Mother: Received SIGINT\n"); 94 | kill(child, SIGUSR2); 95 | printStats(); 96 | exit(9); 97 | } 98 | if (info->si_pid != child) return; 99 | 100 | if ((TYPE == 1 || TYPE == 2) && signum == SIGUSR1) { 101 | receivedFromChild++; 102 | WRITE_MSG("Mother: Received SIGUSR1 form Child\n"); 103 | } else if (TYPE == 3 && signum == SIGRTMIN) { 104 | receivedFromChild++; 105 | WRITE_MSG("Mother: Received SIGRTMIN from Child\n"); 106 | } 107 | } 108 | 109 | void childProcess() { 110 | struct sigaction act; 111 | sigemptyset(&act.sa_mask); 112 | act.sa_flags = SA_SIGINFO; 113 | act.sa_sigaction = childHandler; 114 | 115 | if (sigaction(SIGINT, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGINT\n"); 116 | if (sigaction(SIGUSR1, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGUSR1\n"); 117 | if (sigaction(SIGUSR2, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGUSR2\n"); 118 | if (sigaction(SIGRTMIN, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGRTMIN\n"); 119 | if (sigaction(SIGRTMAX, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGRTMAX\n"); 120 | 121 | while (1) { 122 | sleep(1); 123 | } 124 | } 125 | 126 | void motherProcess() { 127 | sleep(1); 128 | 129 | struct sigaction act; 130 | sigemptyset(&act.sa_mask); 131 | act.sa_flags = SA_SIGINFO; 132 | act.sa_sigaction = motherHandler; 133 | 134 | if (sigaction(SIGINT, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGINT\n"); 135 | if (sigaction(SIGUSR1, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGUSR1\n"); 136 | if (sigaction(SIGRTMIN, &act, NULL) == -1) FAILURE_EXIT(1, "Can't catch SIGRTMIN\n"); 137 | 138 | if (TYPE == 1 || TYPE == 2) { 139 | sigset_t mask; 140 | sigfillset(&mask); 141 | sigdelset(&mask, SIGUSR1); 142 | sigdelset(&mask, SIGINT); 143 | for (; sentToChild < L; sentToChild++) { 144 | WRITE_MSG("Mother: Sending SIGUSR1\n"); 145 | kill(child, SIGUSR1); 146 | if (TYPE == 2) sigsuspend(&mask); 147 | } 148 | WRITE_MSG("Mother: Sending SIGUSR2\n"); 149 | kill(child, SIGUSR2); 150 | } else if (TYPE == 3) { 151 | for (; sentToChild < L; sentToChild++) { 152 | WRITE_MSG("Mother: Sending SIGRTMIN\n"); 153 | kill(child, SIGRTMIN); 154 | } 155 | sentToChild++; 156 | WRITE_MSG("Mother: Sending SIGRTMAX\n"); 157 | kill(child, SIGRTMAX); 158 | } 159 | 160 | int status = 0; 161 | waitpid(child, &status, 0); 162 | if (WIFEXITED(status)) 163 | receivedByChild = WEXITSTATUS(status); 164 | else FAILURE_EXIT(1, "Error with termination of Child!\n"); 165 | } -------------------------------------------------------------------------------- /zestaw5/zad1/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Michał Osadnik on 14/04/2018. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | 14 | #define max_number_of_params 64 15 | #define max_number_of_line 256 16 | #define max_number_of_commands 100 17 | 18 | 19 | char* trim_white(char *orig_str){ 20 | char* buffer = malloc(sizeof(char) * 200); 21 | char* i = orig_str; 22 | while(*i == ' ') i++; 23 | int j = 0; 24 | while(*i != 0){ 25 | while((*i != ' ') && (*i != 0)){ 26 | buffer[j++] = *i; 27 | i++; 28 | } 29 | if(*i == ' '){ 30 | while(*i == ' ') i++; 31 | if (*i != 0) 32 | buffer[j++] = ' '; 33 | } 34 | } 35 | buffer[j+1] = 0; 36 | return buffer; 37 | } 38 | char** parse_program_arguments(char *line){ 39 | int size = 0; 40 | char** args = NULL; 41 | char delimiters[3] = {' ','\n','\t'}; 42 | char* a = strtok(line, delimiters); 43 | while(a != NULL){ 44 | size++; 45 | args = realloc(args, sizeof(char*) * size); 46 | if(args == NULL){ 47 | exit(EXIT_FAILURE); 48 | } 49 | args[size-1] = a; 50 | a = strtok(NULL, delimiters); 51 | } 52 | args = realloc(args, sizeof(char*) * (size+1)); 53 | if(args == NULL){ 54 | exit(EXIT_FAILURE); 55 | } 56 | args[size] = NULL; 57 | 58 | return args; 59 | } 60 | 61 | 62 | int execute_line(char * parameters) { 63 | int command_number = 0; 64 | int pipes[2][2]; 65 | char *cmds[max_number_of_commands]; 66 | 67 | 68 | while((cmds[command_number] = strtok(command_number == 0 ? parameters : NULL, "|")) != NULL){ 69 | command_number++; 70 | }; 71 | int i; 72 | for (i = 0; i < command_number; i++) { 73 | 74 | if (i > 0) { 75 | close(pipes[i % 2][0]); 76 | close(pipes[i % 2][1]); 77 | } 78 | 79 | if(pipe(pipes[i % 2]) == -1) { 80 | printf("Error on pipe.\n"); 81 | exit(EXIT_FAILURE); 82 | } 83 | pid_t cp = fork(); 84 | if (cp == 0) { 85 | char ** exec_params = parse_program_arguments(trim_white(cmds[i])); 86 | 87 | if ( i != command_number - 1) { 88 | close(pipes[i % 2][0]); 89 | if (dup2(pipes[i % 2][1], STDOUT_FILENO) < 0) { 90 | exit(EXIT_FAILURE); 91 | }; 92 | } 93 | if (i != 0) { 94 | close(pipes[(i + 1) % 2][1]); 95 | if (dup2(pipes[(i + 1) % 2][0], STDIN_FILENO) < 0) { 96 | close(EXIT_FAILURE); 97 | } 98 | } 99 | execvp(exec_params[0], exec_params); 100 | 101 | exit(EXIT_SUCCESS); 102 | } 103 | } 104 | close(pipes[i % 2][0]); 105 | close(pipes[i % 2][1]); 106 | wait(NULL); 107 | exit(0); 108 | } 109 | 110 | 111 | int main(int argc, char **argv) { 112 | if(argc < 2) { 113 | printf("%s", "There's no enough argument! : ¯\\_(ツ)_/¯"); 114 | return 1; 115 | } 116 | FILE* file = fopen(argv[1], "r"); 117 | if (!file) { 118 | printf("%s", "I cannot open this file 🙄"); 119 | return 1; 120 | } 121 | char temp_registry[max_number_of_line]; 122 | char *parameters[max_number_of_params]; 123 | int argument_number = 0; 124 | while(fgets(temp_registry, max_number_of_line, file)){ 125 | argument_number = 0; 126 | pid_t pid = fork(); 127 | if(pid == 0) { 128 | execute_line(temp_registry); 129 | exit(EXIT_SUCCESS); 130 | } 131 | int status; 132 | wait(&status); 133 | if (status) { 134 | printf( "Error while executing 🤔:"); 135 | for (int i = 0; i < argument_number; i++) { 136 | printf("%s ", parameters[i]); 137 | } 138 | return 1; 139 | } 140 | } 141 | fclose(file); 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /zestaw5/zad1/sample: -------------------------------------------------------------------------------- 1 | ls -l | grep Apr | head -n 1 2 | -------------------------------------------------------------------------------- /zestaw5/zad2/Makefile: -------------------------------------------------------------------------------- 1 | GCC = gcc -Wall -std=c99 -ggdb 2 | M_PATH = master 3 | M_PATH2 = slave 4 | 5 | FNAME = "FF" 6 | 7 | build: 8 | $(GCC) -o $(M_PATH) master.c 9 | $(GCC) -o $(M_PATH2) slave.c 10 | 11 | run_1: 12 | ./$(M_PATH) $(FNAME) 13 | 14 | run_2: 15 | ./$(M_PATH2) $(FNAME) 10 -------------------------------------------------------------------------------- /zestaw5/zad2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static void intAction(int sigNum, siginfo_t* info, void* vp){ 8 | killpg(0, SIGINT); 9 | exit(EXIT_SUCCESS); 10 | } 11 | 12 | 13 | 14 | int childPid; 15 | int masterPid; 16 | int childPids[4096]; 17 | 18 | 19 | int main(int argc, char *argv[]) { 20 | 21 | char buffer[512]; 22 | int slaveNumber; 23 | int N; 24 | struct sigaction sigAction; 25 | 26 | 27 | if (argc != 4){ 28 | printf("Wrong main arguments!\n"); 29 | exit(EXIT_FAILURE); 30 | } 31 | 32 | sigfillset(&sigAction.sa_mask); 33 | sigAction.sa_flags = SA_SIGINFO; 34 | sigAction.sa_sigaction = &intAction; 35 | sigaction(SIGINT, &sigAction, NULL); 36 | 37 | mkfifo(argv[1], 0777); 38 | 39 | slaveNumber = (int) strtol(argv[2], NULL, 10); 40 | N = (int) strtol(argv[3], NULL, 10); 41 | 42 | for (int i = 0; i < slaveNumber; ++i) { 43 | childPids[i] = fork(); 44 | if (childPids[i] == 0){ 45 | execlp("./slave","slave", argv[1], argv[3], 0); 46 | } 47 | } 48 | 49 | masterPid = fork(); 50 | if (masterPid == 0){ 51 | execlp("./master", "master", "myFifo", 0); 52 | } 53 | 54 | for (int i = 0; i < slaveNumber; ++i) { 55 | waitpid(childPids[i], NULL, WUNTRACED); 56 | printf("%d'th slave exited\n", i); 57 | } 58 | 59 | kill(masterPid, SIGINT); 60 | killpg(0, SIGINT); 61 | 62 | waitpid(masterPid, NULL, WUNTRACED); 63 | 64 | return 0; 65 | } -------------------------------------------------------------------------------- /zestaw5/zad2/master.c: -------------------------------------------------------------------------------- 1 | #define _BSD_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define LINE_MAX 256 11 | 12 | int main(int argc, char **argv) { 13 | if (argc < 2) { 14 | exit(EXIT_FAILURE); 15 | } 16 | mkfifo(argv[1], S_IWUSR | S_IRUSR); 17 | char buffer[LINE_MAX]; 18 | 19 | FILE *pipe = fopen(argv[1], "r"); 20 | while (fgets(buffer, LINE_MAX, pipe) != NULL) { 21 | write(1, buffer, strlen(buffer)); 22 | } 23 | fclose(pipe); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /zestaw5/zad2/slave.c: -------------------------------------------------------------------------------- 1 | #define _BSD_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define LINE_MAX 256 9 | 10 | int main(int argc, char** argv) { 11 | if (argc < 3) { 12 | exit(EXIT_FAILURE); 13 | } 14 | int pipe = open(argv[1], O_WRONLY); 15 | 16 | char buffer1[LINE_MAX]; 17 | char buffer2[LINE_MAX]; 18 | 19 | int it = (int) strtol(argv[2], NULL, 10); 20 | for (int i = 0; i < it; i++) { 21 | FILE *date = popen("date", "r"); 22 | fgets(buffer1, LINE_MAX, date); 23 | int pid = getpid(); 24 | sprintf(buffer2, "Slave: %d - %s", pid, buffer1); 25 | write(pipe, buffer2, strlen(buffer2)); 26 | sleep(1); 27 | } 28 | close(pipe); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /zestaw6/zad1/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -std=gnu99 -static -Wall -Wextra -Isrc -rdynamic 3 | 4 | .PHONY: clean 5 | 6 | all: client server 7 | 8 | client: client.c 9 | $(CC) $< -o $@ $(CFLAGS) 10 | 11 | server: server.c 12 | $(CC) $< -o $@ $(CFLAGS) 13 | 14 | clean: 15 | rm {client,server} 2> /dev/null 16 | -------------------------------------------------------------------------------- /zestaw6/zad1/client.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "communication.h" 16 | 17 | #define FAILURE_EXIT(format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(-1); } 18 | 19 | void register_client(key_t privateKey); 20 | void request_mirror(Message *msg); 21 | void request_calc(Message *msg); 22 | void request_time(Message *msg); 23 | void request_end(Message *msg); 24 | int create_queue(char*, int); 25 | void close_queue(); 26 | void int_handler(int); 27 | 28 | int sessionID = -2; 29 | int queue_descriptor = -1; 30 | int privateID = -1; 31 | 32 | // MAIN //////////////////////////////////////////////////////////////////////// 33 | 34 | int main() { 35 | if(atexit(close_queue) == -1) 36 | FAILURE_EXIT("Registering client's atexit failed"); 37 | if(signal(SIGINT, int_handler) == SIG_ERR) 38 | FAILURE_EXIT("Registering INT failed"); 39 | 40 | char* path = getenv("HOME"); 41 | if (path == NULL) 42 | FAILURE_EXIT("Getting $HOME failed"); 43 | 44 | queue_descriptor = create_queue(path, PROJECT_ID); 45 | 46 | key_t privateKey = ftok(path, getpid()); 47 | if (privateKey == -1) 48 | FAILURE_EXIT("Generation of private key failed"); 49 | 50 | privateID = msgget(privateKey, IPC_CREAT | IPC_EXCL | 0666); 51 | if (privateID == -1) 52 | FAILURE_EXIT("Creation of private queue failed"); 53 | 54 | register_client(privateKey); 55 | 56 | char cmd[20]; 57 | Message msg; 58 | while(1) { 59 | msg.sender_pid = getpid(); 60 | printf("client: enter your request: "); 61 | if (fgets(cmd, 20, stdin) == NULL){ 62 | printf("client: error reading your command\n"); 63 | continue; 64 | } 65 | int n = strlen(cmd); 66 | if (cmd[n-1] == '\n') cmd[n-1] = 0; 67 | 68 | 69 | if (strcmp(cmd, "mirror") == 0) { 70 | request_mirror(&msg); 71 | } else if (strcmp(cmd, "calc") == 0) { 72 | request_calc(&msg); 73 | } else if (strcmp(cmd, "time") == 0) { 74 | request_time(&msg); 75 | } else if (strcmp(cmd, "end") == 0) { 76 | request_end(&msg); 77 | } else if (strcmp(cmd, "quit") == 0) { 78 | exit(0); 79 | } else { 80 | printf("client: incorrect command\n"); 81 | } 82 | } 83 | } 84 | 85 | void register_client(key_t privateKey) { 86 | Message msg; 87 | msg.mtype = LOGIN; 88 | msg.sender_pid = getpid(); 89 | sprintf(msg.message_text, "%d", privateKey); 90 | 91 | if (msgsnd(queue_descriptor, &msg, MSG_SIZE, 0) == -1) 92 | FAILURE_EXIT("client: LOGIN request failed\n"); 93 | if (msgrcv(privateID, &msg, MSG_SIZE, 0, 0) == -1) 94 | FAILURE_EXIT("client: catching LOGIN response failed\n"); 95 | if (sscanf(msg.message_text, "%d", &sessionID) < 1) 96 | FAILURE_EXIT("client: scanning LOGIN response failed\n"); 97 | if (sessionID < 0) 98 | FAILURE_EXIT("client: server cannot have more clients\n"); 99 | 100 | printf("client: client registered. Session no: %d\n", sessionID); 101 | } 102 | 103 | // HANDLERS //////////////////////////////////////////////////////////////////// 104 | 105 | void request_mirror(Message *msg) { 106 | msg->mtype = MIRROR; 107 | printf("Enter string of characters to Mirror: "); 108 | if (fgets(msg->message_text, MAX_CONT_SIZE, stdin) == 0) { 109 | printf("client: too many characters\n"); 110 | return; 111 | } 112 | if (msgsnd(queue_descriptor, msg, MSG_SIZE, 0) == -1) 113 | FAILURE_EXIT("client: MIRROR request failed"); 114 | if (msgrcv(privateID, msg, MSG_SIZE, 0, 0) == -1) 115 | FAILURE_EXIT("client: catching MIRROR response failed"); 116 | printf("%s", msg->message_text); 117 | } 118 | 119 | void request_calc(Message *msg) { 120 | msg->mtype = CALC; 121 | printf("Enter expression to calculate: "); 122 | if (fgets(msg->message_text, MAX_CONT_SIZE, stdin) == 0) { 123 | printf("client: too many characters\n"); 124 | return; 125 | } 126 | if(msgsnd(queue_descriptor, msg, MSG_SIZE, 0) == -1) 127 | FAILURE_EXIT("client: CALC request failed"); 128 | if(msgrcv(privateID, msg, MSG_SIZE, 0, 0) == -1) 129 | FAILURE_EXIT("client: catching CALC response failed"); 130 | printf("%s", msg->message_text); 131 | } 132 | 133 | void request_time(Message *msg) { 134 | msg->mtype = TIME; 135 | 136 | if(msgsnd(queue_descriptor, msg, MSG_SIZE, 0) == -1) 137 | FAILURE_EXIT("client: TIME request failed"); 138 | if(msgrcv(privateID, msg, MSG_SIZE, 0, 0) == -1) 139 | FAILURE_EXIT("client: catching TIME response failed"); 140 | printf("%s\n", msg->message_text); 141 | } 142 | 143 | void request_end(Message *msg) { 144 | msg->mtype = END; 145 | 146 | if(msgsnd(queue_descriptor, msg, MSG_SIZE, 0) == -1) 147 | FAILURE_EXIT("client: END request failed"); 148 | } 149 | 150 | // HELPERS ///////////////////////////////////////////////////////////////////// 151 | 152 | int create_queue(char *path, int ID) { 153 | int key = ftok(path, ID); 154 | if(key == -1) FAILURE_EXIT("Generation of key failed"); 155 | 156 | int QueueID = msgget(key, 0); 157 | if (QueueID == -1) FAILURE_EXIT("Opening queue failed"); 158 | 159 | return QueueID; 160 | } 161 | 162 | void close_queue() { 163 | if (privateID > -1) { 164 | if (msgctl(privateID, IPC_RMID, NULL) == -1){ 165 | printf("There was some error deleting clients's queue\n"); 166 | } 167 | else { 168 | printf("Client's queue deleted successfully\n"); 169 | } 170 | } 171 | } 172 | 173 | void int_handler(int _) { exit(2); } -------------------------------------------------------------------------------- /zestaw6/zad1/communication.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMUNICATION_H 2 | #define COMMUNICATION_H 3 | 4 | #define MAX_CLIENTS 10 5 | #define PROJECT_ID 0x099 6 | #define MAX_CONT_SIZE 4096 7 | 8 | typedef enum mtype { 9 | LOGIN = 1, MIRROR = 2, CALC = 3, TIME = 4, END = 5, INIT = 6 10 | } mtype; 11 | 12 | typedef struct Message { 13 | long mtype; 14 | pid_t sender_pid; 15 | char message_text[MAX_CONT_SIZE]; 16 | } Message; 17 | 18 | // msgsz does not contain mtype 19 | const size_t MSG_SIZE = sizeof(Message) - sizeof(long); 20 | 21 | #endif -------------------------------------------------------------------------------- /zestaw6/zad1/server.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "communication.h" 16 | 17 | #define FAILURE_EXIT(format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(-1); } 18 | 19 | void handle_public_queue(struct Message *msg); 20 | void do_login(struct Message *msg); 21 | void do_mirror(struct Message *msg); 22 | void do_calc(struct Message *msg); 23 | void do_time(struct Message *msg); 24 | void do_end(struct Message *msg); 25 | int find_queue_id(pid_t sender_pid); 26 | int create_message(struct Message *msg); 27 | char* convert_time(const time_t *mtime); 28 | void close_queue(); 29 | void int_handler(int); 30 | 31 | int queue_descriptor = -2; 32 | int active = 1; 33 | int clients_data[MAX_CLIENTS][2]; 34 | int client_count = 0; 35 | 36 | // MAIN //////////////////////////////////////////////////////////////////////// 37 | 38 | int main() { 39 | if (atexit(close_queue) == -1) 40 | FAILURE_EXIT("server: egistering server's atexit failed\n"); 41 | 42 | if (signal(SIGINT, int_handler) == SIG_ERR) 43 | FAILURE_EXIT("server: registering INT failed\n"); 44 | 45 | struct msqid_ds current_state; 46 | 47 | char* path = getenv("HOME"); 48 | if(path == NULL) 49 | FAILURE_EXIT("server: getting environmental variable 'HOME' failed\n"); 50 | 51 | key_t publicKey = ftok(path, PROJECT_ID); 52 | if(publicKey == -1) 53 | FAILURE_EXIT("server: generation of publicKey failed\n"); 54 | 55 | queue_descriptor = msgget(publicKey, IPC_CREAT | IPC_EXCL | 0666); 56 | if(queue_descriptor == -1) 57 | FAILURE_EXIT("server: creation of public queue failed\n"); 58 | 59 | Message buffer; 60 | while(1) { 61 | if (active == 0) { 62 | if (msgctl(queue_descriptor, IPC_STAT, ¤t_state) == -1) 63 | FAILURE_EXIT("server: getting current state of public queue failed\n"); 64 | if (current_state.msg_qnum == 0) break; 65 | } 66 | 67 | if (msgrcv(queue_descriptor, &buffer, MSG_SIZE, 0, 0) < 0) 68 | FAILURE_EXIT("server: receiving message failed\n"); 69 | handle_public_queue(&buffer); 70 | } 71 | return 0; 72 | } 73 | 74 | void handle_public_queue(struct Message *msg) { 75 | if (msg == NULL) return; 76 | switch(msg->mtype){ 77 | case LOGIN: 78 | do_login(msg); 79 | break; 80 | case MIRROR: 81 | do_mirror(msg); 82 | break; 83 | case CALC: 84 | do_calc(msg); 85 | break; 86 | case TIME: 87 | do_time(msg); 88 | break; 89 | case END: 90 | do_end(msg); 91 | break; 92 | default: 93 | break; 94 | } 95 | } 96 | 97 | // HANDLERS //////////////////////////////////////////////////////////////////// 98 | 99 | void do_login(struct Message *msg) { 100 | key_t client_queue_key; 101 | if (sscanf(msg->message_text, "%d", &client_queue_key) < 0) 102 | FAILURE_EXIT("server: reading client_queue_key failed\n"); 103 | 104 | int client_queue_id = msgget(client_queue_key, 0); 105 | if (client_queue_id == -1) 106 | FAILURE_EXIT("server: reading client_queue_id failed\n"); 107 | 108 | int client_pid = msg->sender_pid; 109 | msg->mtype = INIT; 110 | msg->sender_pid = getpid(); 111 | 112 | if (client_count > MAX_CLIENTS - 1) { 113 | printf("server: maximum number of clients reached\n"); 114 | sprintf(msg->message_text, "%d", -1); 115 | } else { 116 | clients_data[client_count][0] = client_pid; 117 | clients_data[client_count++][1] = client_queue_id; 118 | sprintf(msg->message_text, "%d", client_count - 1); 119 | } 120 | 121 | if (msgsnd(client_queue_id, msg, MSG_SIZE, 0) == -1) 122 | FAILURE_EXIT("server: LOGIN response failed\n"); 123 | } 124 | 125 | void do_mirror(Message *msg) { 126 | int client_queue_id = create_message(msg); 127 | if(client_queue_id == -1) return; 128 | 129 | int message_length = (int) strlen(msg->message_text); 130 | if (msg->message_text[message_length-1] == '\n') message_length--; 131 | 132 | for (int i=0; i < message_length / 2; i++) { 133 | char buff = msg->message_text[i]; 134 | msg->message_text[i] = msg->message_text[message_length - i - 1]; 135 | msg->message_text[message_length - i - 1] = buff; 136 | } 137 | 138 | if(msgsnd(client_queue_id, msg, MSG_SIZE, 0) == -1) 139 | FAILURE_EXIT("server: MIRROR response failed\n"); 140 | } 141 | 142 | void do_calc(Message *msg) { 143 | int client_queue_id = create_message(msg); 144 | if(client_queue_id == -1) return; 145 | 146 | char cmd[4096]; 147 | sprintf(cmd, "echo '%s' | bc", msg->message_text); 148 | FILE* calc = popen(cmd, "r"); 149 | fgets(msg->message_text, MAX_CONT_SIZE, calc); 150 | pclose(calc); 151 | 152 | if (msgsnd(client_queue_id, msg, MSG_SIZE, 0) == -1) 153 | FAILURE_EXIT("server: CALC response failed\n"); 154 | } 155 | 156 | 157 | void do_time(struct Message *msg) { 158 | int client_queue_id = create_message(msg); 159 | if(client_queue_id == -1) return; 160 | 161 | time_t timer; 162 | time(&timer); 163 | char* timeStr = convert_time(&timer); 164 | 165 | sprintf(msg->message_text, "%s", timeStr); 166 | free(timeStr); 167 | 168 | if(msgsnd(client_queue_id, msg, MSG_SIZE, 0) == -1) 169 | FAILURE_EXIT("server: TIME response failed\n"); 170 | } 171 | 172 | void do_end(struct Message *_) { active = 0; } 173 | 174 | // HELPERS ///////////////////////////////////////////////////////////////////// 175 | 176 | int create_message(struct Message *msg) { 177 | int client_queue_id = find_queue_id(msg->sender_pid); 178 | if (client_queue_id == -1){ 179 | printf("server: client not found\n"); 180 | return -1; 181 | } 182 | 183 | msg->mtype = msg->sender_pid; 184 | msg->sender_pid = getpid(); 185 | 186 | return client_queue_id; 187 | } 188 | 189 | int find_queue_id(pid_t sender_pid) { 190 | for (int i=0; i < MAX_CLIENTS; ++i) { 191 | if(clients_data[i][0] == sender_pid) 192 | return clients_data[i][1]; 193 | } 194 | return -1; 195 | } 196 | 197 | char* convert_time(const time_t *mtime) { 198 | char* buff = malloc(sizeof(char) * 30); 199 | struct tm * timeinfo; 200 | timeinfo = localtime (mtime); 201 | strftime(buff, 20, "%b %d %H:%M", timeinfo); 202 | return buff; 203 | } 204 | 205 | void close_queue() { 206 | if (queue_descriptor > -1) { 207 | int tmp = msgctl(queue_descriptor, IPC_RMID, NULL); 208 | if (tmp == -1) { 209 | printf("server: there was some error deleting server's queue\n"); 210 | } 211 | printf("server: queue deleted successfully\n"); 212 | } 213 | } 214 | 215 | void int_handler(int _) { exit(2); } 216 | -------------------------------------------------------------------------------- /zestaw6/zad2/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -std=gnu99 -static -Wall -Wextra -Isrc -rdynamic -lrt 3 | 4 | .PHONY: clean 5 | 6 | all: client server 7 | 8 | client: client.c 9 | $(CC) $< -o $@ $(CFLAGS) 10 | 11 | server: server.c 12 | $(CC) $< -o $@ $(CFLAGS) 13 | 14 | clean: 15 | rm {client,server} 2> /dev/null 16 | -------------------------------------------------------------------------------- /zestaw6/zad2/client.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "communication.h" 16 | 17 | #define FAILURE_EXIT(format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(-1); } 18 | 19 | void register_client(); 20 | void request_mirror(struct Message *msg); 21 | void request_calc(struct Message *msg); 22 | void request_time(struct Message *msg); 23 | void request_end(struct Message *msg); 24 | void request_quit(struct Message *msg); 25 | void close_queue(); 26 | void int_handler(int); 27 | 28 | int sessionID = -2; 29 | mqd_t queue_descriptor = -1; 30 | mqd_t privateID = -1; 31 | char myPath[20]; 32 | 33 | // MAIN //////////////////////////////////////////////////////////////////////// 34 | 35 | int main() { 36 | if (atexit(close_queue) == -1) 37 | FAILURE_EXIT("client: registering client's atexit failed\n"); 38 | if (signal(SIGINT, int_handler) == SIG_ERR) 39 | FAILURE_EXIT("client: registering INT failed!"); 40 | 41 | sprintf(myPath, "/%d", getpid()); 42 | 43 | queue_descriptor = mq_open(server_path, O_WRONLY); 44 | if (queue_descriptor == -1) FAILURE_EXIT("Opening public queue failed\n"); 45 | 46 | struct mq_attr posixAttr; 47 | posixAttr.mq_maxmsg = MAX_MESSAGE_QUEUE_SIZE; 48 | posixAttr.mq_msgsize = MESSAGE_SIZE; 49 | 50 | privateID = mq_open(myPath, O_RDONLY | O_CREAT | O_EXCL, 0666, &posixAttr); 51 | if (privateID == -1) FAILURE_EXIT("client: creation of private queue failed\n"); 52 | 53 | register_client(); 54 | 55 | char cmd[20]; 56 | Message msg; 57 | while(1) { 58 | msg.sender_pid = getpid(); 59 | printf("Enter your request: "); 60 | if (fgets(cmd, 20, stdin) == NULL) { 61 | printf("client: error reading your command\n"); 62 | continue; 63 | } 64 | int n = strlen(cmd); 65 | if (cmd[n-1] == '\n') cmd[n-1] = 0; 66 | 67 | 68 | if (strcmp(cmd, "mirror") == 0) { 69 | request_mirror(&msg); 70 | } else if (strcmp(cmd, "calc") == 0) { 71 | request_calc(&msg); 72 | } else if (strcmp(cmd, "time") == 0) { 73 | request_time(&msg); 74 | } else if (strcmp(cmd, "end") == 0) { 75 | request_end(&msg); 76 | } else if (strcmp(cmd, "quit") == 0) { 77 | exit(0); 78 | } else { 79 | printf("client: wrong command\n"); 80 | } 81 | } 82 | } 83 | 84 | void register_client() { 85 | Message msg; 86 | msg.mtype = LOGIN; 87 | msg.sender_pid = getpid(); 88 | 89 | if (mq_send(queue_descriptor, (char*) &msg, MESSAGE_SIZE, 1) == -1) 90 | FAILURE_EXIT("client: login request failed\n"); 91 | if (mq_receive(privateID,(char*) &msg, MESSAGE_SIZE, NULL) == -1) 92 | FAILURE_EXIT("client: catching LOGIN response failed\n"); 93 | if (sscanf(msg.message_text, "%d", &sessionID) < 1) 94 | FAILURE_EXIT("client: scanning LOGIN response failed\n"); 95 | if (sessionID < 0) 96 | FAILURE_EXIT("client: server cannot have more clients\n"); 97 | 98 | printf("client: client registered! My session nr is %d\n", sessionID); 99 | } 100 | 101 | // HANDLERS //////////////////////////////////////////////////////////////////// 102 | 103 | void request_mirror(struct Message *msg){ 104 | msg->mtype = MIRROR; 105 | printf("client: enter string of characters to mirror: "); 106 | if (fgets(msg->message_text, MAX_CONT_SIZE, stdin) == NULL) { 107 | printf("client: too many characters\n"); 108 | return; 109 | } 110 | 111 | if (mq_send(queue_descriptor, (char*) msg, MESSAGE_SIZE, 1) == -1) 112 | FAILURE_EXIT("client: MIRROR request failed\n"); 113 | if (mq_receive(privateID,(char*) msg, MESSAGE_SIZE, NULL) == -1) 114 | FAILURE_EXIT("client: catching MIRROR response failed\n"); 115 | printf("%s", msg->message_text); 116 | } 117 | 118 | void request_calc(struct Message *msg) { 119 | msg->mtype = CALC; 120 | printf("Enter expression to calculate: "); 121 | if (fgets(msg->message_text, MAX_CONT_SIZE, stdin) == NULL) { 122 | printf("client: too many characters\n"); 123 | return; 124 | } 125 | if (mq_send(queue_descriptor, (char*) msg, MESSAGE_SIZE, 1) == -1) 126 | FAILURE_EXIT("client: CALC request failed\n"); 127 | if (mq_receive(privateID,(char*) msg, MESSAGE_SIZE, NULL) == -1) 128 | FAILURE_EXIT("client: catching CALC response failed\n"); 129 | printf("%s", msg->message_text); 130 | } 131 | 132 | void request_time(struct Message *msg){ 133 | msg->mtype = TIME; 134 | 135 | if (mq_send(queue_descriptor, (char*) msg, MESSAGE_SIZE, 1) == -1) 136 | FAILURE_EXIT("client: TIME request failed\n"); 137 | if (mq_receive(privateID,(char*) msg, MESSAGE_SIZE, NULL) == -1) 138 | FAILURE_EXIT("client: catching TIME response failed\n"); 139 | printf("%s\n", msg->message_text); 140 | } 141 | 142 | void request_end(struct Message *msg) { 143 | msg->mtype = END; 144 | 145 | if (mq_send(queue_descriptor, (char*) msg, MESSAGE_SIZE, 1) == -1) 146 | FAILURE_EXIT("client: END request failed\n"); 147 | } 148 | 149 | void request_quit(struct Message *msg) { 150 | msg->mtype = QUIT; 151 | 152 | if (mq_send(queue_descriptor, (char*) msg, MESSAGE_SIZE, 1) == -1) 153 | printf("client: END request failed - server may have already been closed\n"); 154 | fflush(stdout); 155 | } 156 | 157 | // HELPERS ///////////////////////////////////////////////////////////////////// 158 | 159 | void close_queue() { 160 | if (privateID > -1) { 161 | if (sessionID >= 0) { 162 | printf("\nBefore quitting, i will try to send QUIT request to public queue!\n"); 163 | Message msg; 164 | msg.sender_pid = getpid(); 165 | request_quit(&msg); 166 | } 167 | 168 | if (mq_close(queue_descriptor) == -1) { 169 | printf("client: there was some error closing servers's queue!\n"); 170 | } else { 171 | printf("client: servers's queue closed successfully!\n"); 172 | } 173 | 174 | if (mq_close(privateID) == -1) { 175 | printf("client: there was some error closing client's queue!\n"); 176 | } else { 177 | printf("client: queue closed successfully!\n"); 178 | } 179 | 180 | if (mq_unlink(myPath) == -1) { 181 | printf("client: there was some error deleting client's queue!\n"); 182 | } else { 183 | printf("client: queue deleted successfully!\n"); 184 | } 185 | } else { 186 | printf("client: there was no need of deleting queue!\n"); 187 | } 188 | } 189 | 190 | void int_handler(int _) { exit(2); } 191 | -------------------------------------------------------------------------------- /zestaw6/zad2/communication.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMUNICATION_H 2 | #define COMMUNICATION_H 3 | 4 | #define MAX_CLIENTS 10 5 | #define PROJECT_ID 0x099 6 | #define MAX_CONT_SIZE 4096 7 | #define MESSAGE_SIZE sizeof(Message) 8 | #define MAX_MESSAGE_QUEUE_SIZE 9 9 | 10 | typedef enum mtype { 11 | LOGIN = 1, MIRROR = 2, CALC = 3, TIME = 4, END = 5, INIT = 6, QUIT = 7 12 | } mtype; 13 | 14 | typedef struct Message { 15 | long mtype; 16 | pid_t sender_pid; 17 | char message_text[MAX_CONT_SIZE]; 18 | } Message; 19 | 20 | const char server_path[] = "/server"; 21 | 22 | #endif -------------------------------------------------------------------------------- /zestaw6/zad2/server.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "communication.h" 16 | 17 | #define FAILURE_EXIT(format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(-1); } 18 | 19 | void handle_public_queue(struct Message *msg); 20 | void do_login(struct Message *msg); 21 | void do_mirror(struct Message *msg); 22 | void do_calc(struct Message *msg); 23 | void do_time(struct Message *msg); 24 | void do_end(struct Message *msg); 25 | void do_quit(struct Message *msg); 26 | int find_queue_id(pid_t sender_pid); 27 | int prepare_msg(struct Message *msg); 28 | char* convert_time(const time_t *mtime); 29 | void close_queue(); 30 | void int_handler(int); 31 | 32 | int active = 1; 33 | int clients_data[MAX_CLIENTS][2]; 34 | int client_count = 0; 35 | mqd_t queue_descriptor = -1; 36 | 37 | // MAIN //////////////////////////////////////////////////////////////////////// 38 | 39 | int main() { 40 | if (atexit(close_queue) == -1) 41 | FAILURE_EXIT("server: registering server's atexit failed\n"); 42 | if (signal(SIGINT, int_handler) == SIG_ERR) 43 | FAILURE_EXIT("server: registering INT failed\n"); 44 | 45 | struct mq_attr current_state; 46 | struct mq_attr posix_attr; 47 | posix_attr.mq_maxmsg = MAX_MESSAGE_QUEUE_SIZE; 48 | posix_attr.mq_msgsize = MESSAGE_SIZE; 49 | 50 | queue_descriptor = mq_open(server_path, O_RDONLY | O_CREAT | O_EXCL, 0666, &posix_attr); 51 | 52 | if (queue_descriptor == -1) 53 | FAILURE_EXIT("server: creation of public queue failed\n"); 54 | 55 | Message buffer; 56 | while(1) { 57 | if(active == 0) { 58 | if (mq_getattr(queue_descriptor, ¤t_state) == -1) 59 | FAILURE_EXIT("server: couldnt read public queue parameters\n"); 60 | if (current_state.mq_curmsgs == 0) exit(0); 61 | } 62 | 63 | if (mq_receive(queue_descriptor,(char*) &buffer, MESSAGE_SIZE, NULL) == -1) 64 | FAILURE_EXIT("server: receiving message by server failed\n"); 65 | handle_public_queue(&buffer); 66 | } 67 | } 68 | 69 | void handle_public_queue(struct Message *msg) { 70 | if (msg == NULL) return; 71 | switch(msg->mtype) { 72 | case LOGIN: 73 | do_login(msg); 74 | break; 75 | case MIRROR: 76 | do_mirror(msg); 77 | break; 78 | case CALC: 79 | do_calc(msg); 80 | break; 81 | case TIME: 82 | do_time(msg); 83 | break; 84 | case END: 85 | do_end(msg); 86 | break; 87 | case QUIT: 88 | do_quit(msg); 89 | break; 90 | default: 91 | break; 92 | } 93 | } 94 | 95 | // HANDLERS //////////////////////////////////////////////////////////////////// 96 | 97 | void do_login(struct Message *msg) { 98 | int clientPID = msg->sender_pid; 99 | char clientPath[15]; 100 | sprintf(clientPath, "/%d", clientPID); 101 | 102 | int client_queue_id = mq_open(clientPath, O_WRONLY); 103 | if (client_queue_id == -1) FAILURE_EXIT("server: reading client_queue_id failed\n"); 104 | 105 | msg->mtype = INIT; 106 | msg->sender_pid = getpid(); 107 | 108 | if (client_count > MAX_CLIENTS - 1) { 109 | printf("server: maximum amount of clients reached\n"); 110 | sprintf(msg->message_text, "%d", -1); 111 | if (mq_send(client_queue_id, (char*) msg, MESSAGE_SIZE, 1) == -1) 112 | FAILURE_EXIT("server: login response failed\n"); 113 | if (mq_close(client_queue_id) == -1) 114 | FAILURE_EXIT("server: closing client's queue failed\n"); 115 | } else { 116 | clients_data[client_count][0] = clientPID; 117 | clients_data[client_count++][1] = client_queue_id; 118 | sprintf(msg->message_text, "%d", client_count-1); 119 | if (mq_send(client_queue_id, (char*) msg, MESSAGE_SIZE, 1) == -1) 120 | FAILURE_EXIT("server: login response failed\n"); 121 | } 122 | } 123 | 124 | void do_mirror(struct Message *msg) { 125 | int client_queue_id = prepare_msg(msg); 126 | if (client_queue_id == -1) return; 127 | 128 | int msgLen = (int) strlen(msg->message_text); 129 | if (msg->message_text[msgLen-1] == '\n') msgLen--; 130 | 131 | int i; for (i = 0; i < msgLen / 2; ++i) { 132 | char buff = msg->message_text[i]; 133 | msg->message_text[i] = msg->message_text[msgLen - i - 1]; 134 | msg->message_text[msgLen - i - 1] = buff; 135 | } 136 | 137 | if (mq_send(client_queue_id, (char*) msg, MESSAGE_SIZE, 1) == -1) 138 | FAILURE_EXIT("server: MIRROR response failed\n"); 139 | } 140 | 141 | void do_calc(struct Message *msg) { 142 | int client_queue_id = prepare_msg(msg); 143 | if (client_queue_id == -1) return; 144 | 145 | char cmd[4108]; 146 | sprintf(cmd, "echo '%s' | bc", msg->message_text); 147 | FILE* calc = popen(cmd, "r"); 148 | fgets(msg->message_text, MAX_CONT_SIZE, calc); 149 | pclose(calc); 150 | 151 | if (mq_send(client_queue_id, (char*) msg, MESSAGE_SIZE, 1) == -1) 152 | FAILURE_EXIT("server: CALC response failed\n"); 153 | } 154 | 155 | void do_time(struct Message *msg) { 156 | int client_queue_id = prepare_msg(msg); 157 | if (client_queue_id == -1) return; 158 | 159 | time_t timer; 160 | time(&timer); 161 | char* timeStr = convert_time(&timer); 162 | 163 | sprintf(msg->message_text, "%s", timeStr); 164 | free(timeStr); 165 | 166 | if (mq_send(client_queue_id, (char*) msg, MESSAGE_SIZE, 1) == -1) 167 | FAILURE_EXIT("server: TIME response failed"); 168 | } 169 | 170 | void do_end(struct Message *_) { active = 0; } 171 | 172 | void do_quit(struct Message *msg) { 173 | int i; for (i = 0; isender_pid) break; 175 | } 176 | if(i == client_count) { 177 | printf("server: client not found\n"); 178 | return; 179 | } 180 | if (mq_close(clients_data[i][1]) == -1) 181 | FAILURE_EXIT("server: closing clients queue in QUIT response failed\n"); 182 | for (; i + 1 < client_count; ++i) { 183 | clients_data[i][0] = clients_data[i + 1][0]; 184 | clients_data[i][1] = clients_data[i + 1][1]; 185 | } 186 | client_count--; 187 | printf("server: cleared data of removed client\n"); 188 | } 189 | 190 | // HELPERS ///////////////////////////////////////////////////////////////////// 191 | 192 | int prepare_msg(struct Message *msg) { 193 | int client_queue_id = find_queue_id(msg->sender_pid); 194 | if (client_queue_id == -1) { 195 | printf("server: client not found\n"); 196 | return -1; 197 | } 198 | 199 | msg->mtype = msg->sender_pid; 200 | msg->sender_pid = getpid(); 201 | 202 | return client_queue_id; 203 | } 204 | 205 | int find_queue_id(pid_t sender_pid) { 206 | int i; for (i = 0; i < client_count; ++i) 207 | if (clients_data[i][0] == sender_pid) 208 | return clients_data[i][1]; 209 | return -1; 210 | } 211 | 212 | void close_queue() { 213 | int i; for (i = 0; i < client_count; ++i) { 214 | if (mq_close(clients_data[i][1]) == -1) { 215 | printf("server: error closing %d client queue\n", i); 216 | } 217 | if (kill(clients_data[i][0], SIGINT) == -1) { 218 | printf("server: error killing %d client\n", i); 219 | } 220 | } 221 | if (queue_descriptor > -1) { 222 | if(mq_close(queue_descriptor) == -1) { 223 | printf("server: error closing public queue\n"); 224 | } else { 225 | printf("server: queue closed\n"); 226 | } 227 | 228 | if (mq_unlink(server_path) == -1) { 229 | printf("server: error deleting public queue\n"); 230 | } else { 231 | printf("server: queue deleted successfully\n"); 232 | } 233 | } else { 234 | printf("server: there was no need of deleting queue\n"); 235 | } 236 | } 237 | 238 | char* convert_time(const time_t *mtime) { 239 | char* buff = malloc(sizeof(char) * 30); 240 | struct tm * timeinfo; 241 | timeinfo = localtime (mtime); 242 | strftime(buff, 20, "%b %d %H:%M", timeinfo); 243 | return buff; 244 | } 245 | 246 | void int_handler(int _) { 247 | active = 0; 248 | exit(2); 249 | } 250 | 251 | -------------------------------------------------------------------------------- /zestaw7/zad1/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -std=gnu99 3 | 4 | .PHONY: clean 5 | 6 | all: handler_of_clients barber 7 | 8 | handler_of_clients: handler_of_clients.c 9 | $(CC) $< -o $@ $(CFLAGS) 10 | 11 | barber: barber.c 12 | $(CC) $< -o $@ $(CFLAGS) 13 | 14 | clean: 15 | rm {handler_of_clients,barber} 2> /dev/null 16 | -------------------------------------------------------------------------------- /zestaw7/zad1/barber.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "shared_utils.h" 12 | 13 | int id_of_shared_memory; 14 | int sem_id; 15 | 16 | void handle_signal(int _) { 17 | printf("Closing barbershop\n"); 18 | exit(0); 19 | } 20 | 21 | void invite_client_to_the_chair() { 22 | pid_t client_pid = barbershop->fifo_queue_of_clients[0]; 23 | barbershop->current_client = client_pid; 24 | printf("%lo barber: invited client %i\n", current_time(), client_pid); 25 | } 26 | 27 | void shave() { 28 | printf("%lo barber: started shaving client %i\n", 29 | current_time(), 30 | barbershop->current_client); 31 | 32 | printf("%lo barber: finished shaving client %i\n", 33 | current_time(), 34 | barbershop->current_client); 35 | 36 | barbershop->current_client = 0; 37 | } 38 | 39 | void clean_memory() { 40 | shmdt(barbershop); 41 | if(sem_id != 0) { 42 | semctl(sem_id, 0, IPC_RMID); 43 | } 44 | if(id_of_shared_memory != 0) { 45 | shmctl(id_of_shared_memory, IPC_RMID, NULL); 46 | } 47 | } 48 | 49 | void initialize_barbershop(int argc, char **argv) { 50 | signal(SIGTERM, handle_signal); 51 | signal(SIGINT, handle_signal); 52 | atexit(clean_memory); 53 | 54 | if (argc < 2) FAIL("Not enough arguments provided\n") 55 | 56 | int number_of_seats_in_the_barbershop = (int) strtol(argv[1], 0, 10); 57 | if (number_of_seats_in_the_barbershop > BARBER_MAX_QUEUE_SIZE) 58 | FAIL("Provided room size was too big\n") 59 | 60 | key_t id_of_the_project = ftok(PROJECT_PATH, PROJECT_ID); 61 | if (id_of_the_project == -1) 62 | FAIL("Couldn't obtain a project key\n") 63 | 64 | id_of_shared_memory = shmget( 65 | id_of_the_project, 66 | sizeof(struct Barber_info), 67 | S_IRWXU | IPC_CREAT 68 | ); 69 | 70 | if (id_of_shared_memory == -1) 71 | FAIL("Couldn't create shared memory\n") 72 | 73 | barbershop = shmat(id_of_shared_memory, 0, 0); 74 | if (barbershop == (void*) -1) 75 | FAIL("Couldn't access shared memory\n") 76 | 77 | sem_id = semget(id_of_the_project, 1, IPC_CREAT | S_IRWXU); 78 | 79 | if (sem_id == -1) 80 | FAIL("Couldn't create semaphore\n") 81 | 82 | semctl(sem_id, 0, SETVAL, 0); 83 | 84 | barbershop->status_of_barber = SLEEPING_INACTIVE; 85 | barbershop->waiting_room_size = number_of_seats_in_the_barbershop; 86 | barbershop->client_count = 0; 87 | barbershop->current_client = 0; 88 | 89 | for (int i = 0; i < BARBER_MAX_QUEUE_SIZE; ++i) barbershop->fifo_queue_of_clients[i] = 0; 90 | } 91 | 92 | 93 | int main(int argc, char** argv) { 94 | initialize_barbershop(argc, argv); 95 | 96 | release_sem(sem_id); 97 | 98 | while(1) { 99 | take_sem(sem_id); 100 | 101 | switch (barbershop->status_of_barber) { 102 | case IDLE: 103 | if (is_queue_empty()) { 104 | printf("%lo barber: barber fell asleep\n", current_time()); 105 | barbershop->status_of_barber = SLEEPING_INACTIVE; 106 | } else { 107 | invite_client_to_the_chair(); 108 | barbershop->status_of_barber = READY_FOR_SHAVING; 109 | } 110 | break; 111 | case AWAKEN_BY_CLIENT: 112 | printf("%lo barber: woke up\n", current_time()); 113 | barbershop->status_of_barber = READY_FOR_SHAVING; 114 | break; 115 | case SHAVING_CLIENT: 116 | shave(); 117 | barbershop->status_of_barber = READY_FOR_SHAVING; 118 | break; 119 | default: 120 | break; 121 | } 122 | 123 | release_sem(sem_id); 124 | } 125 | } -------------------------------------------------------------------------------- /zestaw7/zad1/handler_of_clients.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "shared_utils.h" 13 | 14 | 15 | enum Client_status status; 16 | int id_of_shared_memory; 17 | int sem_id; 18 | 19 | void initialize_clients() { 20 | key_t id_of_project = ftok(PROJECT_PATH, PROJECT_ID); 21 | if (id_of_project == -1) 22 | FAIL("Error while getting key\n") 23 | 24 | id_of_shared_memory = shmget(id_of_project, sizeof(struct Barber_info), 0); 25 | if (id_of_shared_memory == -1) 26 | FAIL("Couldn't create shared memory\n") 27 | 28 | barbershop = shmat(id_of_shared_memory, 0, 0); 29 | if (barbershop == (void*) -1) 30 | FAIL("Couldn't access shared memory\n") 31 | 32 | sem_id = semget(id_of_project, 0, 0); 33 | if (sem_id == -1) 34 | FAIL("Couldn't create semaphore\n") 35 | } 36 | 37 | void take_barbers_chair() { 38 | pid_t client_pid = getpid(); 39 | 40 | if (status == INVITED) { 41 | pop_queue(); 42 | } else if (status == JUST_ARRIVED) { 43 | while (1) { 44 | release_sem(sem_id); 45 | take_sem(sem_id); 46 | if (barbershop->status_of_barber == READY_FOR_SHAVING) break; 47 | } 48 | status = INVITED; 49 | } 50 | barbershop->current_client = client_pid; 51 | printf("%lo: #%i: took place in the chair\n", current_time(), client_pid); 52 | } 53 | 54 | void trigger_barbers_client(int number_of_shaves) { 55 | pid_t current_clients_pid = getpid(); 56 | int cuts_already_done = 0; 57 | 58 | while (cuts_already_done < number_of_shaves) { 59 | status = JUST_ARRIVED; 60 | 61 | take_sem(sem_id); 62 | 63 | if (barbershop->status_of_barber == SLEEPING_INACTIVE) { 64 | printf("%lo #%i: woke up the barber\n", current_time(), current_clients_pid); 65 | barbershop->status_of_barber = AWAKEN_BY_CLIENT; 66 | take_barbers_chair(); 67 | barbershop->status_of_barber = SHAVING_CLIENT; 68 | } else if (!queue_full()) { 69 | get_in_queue(current_clients_pid); 70 | printf("%lo #%i: entering the fifo_queue_of_clients\n", current_time(), current_clients_pid); 71 | } else { 72 | printf("%lo #%i: could not find place in the fifo_queue_of_clients\n", current_time(), current_clients_pid); 73 | release_sem(sem_id); 74 | return; 75 | } 76 | 77 | release_sem(sem_id); 78 | 79 | while(status != INVITED) { 80 | take_sem(sem_id); 81 | if (barbershop->current_client == current_clients_pid) { 82 | status = INVITED; 83 | take_barbers_chair(); 84 | barbershop->status_of_barber = SHAVING_CLIENT; 85 | } 86 | release_sem(sem_id); 87 | } 88 | 89 | while(status != SHAVED) { 90 | take_sem(sem_id); 91 | if (barbershop->current_client != current_clients_pid) { 92 | status = SHAVED; 93 | printf("%lo #%i: shaved\n", current_time(), current_clients_pid); 94 | barbershop->status_of_barber = IDLE; 95 | cuts_already_done++; 96 | } 97 | release_sem(sem_id); 98 | } 99 | } 100 | printf("%lo #%i: left barbershop after %i cuts_already_done\n", current_time(), current_clients_pid, number_of_shaves); 101 | } 102 | 103 | 104 | int main(int argc, char** argv) { 105 | if (argc < 3) FAIL("Not enough arguments provided\n") 106 | int number_of_clients_to_be_spawned = (int) strtol(argv[1], 0, 10); 107 | int number_of_shaves_to_be_done = (int) strtol(argv[2], 0, 10); 108 | initialize_clients(); 109 | 110 | for (int i = 0; i < number_of_clients_to_be_spawned; i++) { 111 | if (!fork()) { 112 | trigger_barbers_client(number_of_shaves_to_be_done); 113 | exit(0); 114 | } 115 | } 116 | while (wait(0)) if (errno != ECHILD) break; 117 | } 118 | -------------------------------------------------------------------------------- /zestaw7/zad1/shared_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #define RED_COLOR "\e[1;31m" 5 | #define RESET_COLOR "\e[0m" 6 | 7 | #define FAIL(format, ...) { \ 8 | printf(RED_COLOR format RESET_COLOR, ##__VA_ARGS__); \ 9 | exit(-1); } 10 | 11 | 12 | #define PROJECT_PATH getenv("HOME") 13 | #define PROJECT_ID 0xDEAD 14 | 15 | #define BARBER_MAX_QUEUE_SIZE 64 16 | 17 | 18 | enum Barber_status { 19 | SLEEPING_INACTIVE, 20 | AWAKEN_BY_CLIENT, 21 | READY_FOR_SHAVING, 22 | IDLE, 23 | SHAVING_CLIENT 24 | }; 25 | 26 | enum Client_status { 27 | JUST_ARRIVED, 28 | INVITED, 29 | SHAVED 30 | }; 31 | 32 | struct Barber_info { 33 | enum Barber_status status_of_barber; 34 | int client_count; 35 | int waiting_room_size; 36 | pid_t current_client; 37 | pid_t fifo_queue_of_clients[BARBER_MAX_QUEUE_SIZE]; 38 | } *barbershop; 39 | 40 | 41 | long current_time() { 42 | struct timespec time; 43 | clock_gettime(CLOCK_MONOTONIC, &time); 44 | return time.tv_nsec / 1000; 45 | } 46 | 47 | void take_sem(int semaphore_id) { 48 | struct sembuf semaphore_request; 49 | semaphore_request.sem_num = 0; 50 | semaphore_request.sem_op = -1; 51 | semaphore_request.sem_flg = 0; 52 | 53 | if (semop(semaphore_id, &semaphore_request, 1)) // 1 goes for one operation 54 | FAIL("Could not update semaphore\n"); 55 | } 56 | 57 | void release_sem(int semaphore_id) { 58 | struct sembuf semaphore_request; 59 | semaphore_request.sem_num = 0; 60 | semaphore_request.sem_op = 1; 61 | semaphore_request.sem_flg = 0; 62 | 63 | if (semop(semaphore_id, &semaphore_request, 1)) // 1 goes for one operation 64 | FAIL("Could not update semaphore\n"); 65 | } 66 | 67 | int queue_full() { 68 | if (barbershop->client_count < barbershop->waiting_room_size) return 0; 69 | return 1; 70 | } 71 | 72 | int is_queue_empty() { 73 | if (barbershop->client_count == 0) return 1; 74 | return 0; 75 | } 76 | 77 | void get_in_queue(pid_t pid) { 78 | barbershop->fifo_queue_of_clients[barbershop->client_count] = pid; 79 | barbershop->client_count += 1; 80 | } 81 | 82 | void pop_queue() { 83 | for (int i = 0; i < barbershop->client_count - 1; ++i) { 84 | barbershop->fifo_queue_of_clients[i] = barbershop->fifo_queue_of_clients[i + 1]; 85 | } 86 | 87 | barbershop->fifo_queue_of_clients[barbershop->client_count - 1] = 0; 88 | barbershop->client_count --; 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /zestaw7/zad2/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-Wall -std=gnu99 -lpthread -lrt 3 | 4 | .PHONY: clean 5 | 6 | all: handler_of_clients barber 7 | 8 | handler_of_clients: handler_of_clients.c 9 | $(CC) $< -o $@ $(CFLAGS) 10 | 11 | barber: barber.c 12 | $(CC) $< -o $@ $(CFLAGS) 13 | 14 | clean: 15 | rm {handler_of_clients,barber} 2> /dev/null 16 | -------------------------------------------------------------------------------- /zestaw7/zad2/barber.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "shared_utils.h" 16 | 17 | int shared_memory_fd; 18 | sem_t* semaphore; 19 | 20 | void handle_signal(int _) { 21 | printf("Closing barbershop\n"); 22 | exit(0); 23 | } 24 | 25 | void invite_client_to_the_chair() { 26 | pid_t client_pid = barbershop->fifo_queue_of_clients[0]; 27 | barbershop->current_client = client_pid; 28 | printf("%lo barber: invited client %i\n", current_time(), client_pid); 29 | } 30 | 31 | void shave() { 32 | printf("%lo barber: started shaving client %i\n", 33 | current_time(), 34 | barbershop->current_client); 35 | 36 | printf("%lo barber: finished shaving client %i\n", 37 | current_time(), 38 | barbershop->current_client); 39 | 40 | barbershop->current_client = 0; 41 | } 42 | 43 | void clean_memory() { 44 | sem_close(semaphore); 45 | if (semaphore != 0) sem_unlink(PROJECT_PATH); 46 | munmap(barbershop, sizeof(barbershop)); 47 | if (shared_memory_fd != 0) shm_unlink(PROJECT_PATH); 48 | } 49 | 50 | void initialize_barbershop(int argc, char **argv) { 51 | // Handle signals and atexit() callback 52 | signal(SIGTERM, handle_signal); 53 | signal(SIGINT, handle_signal); 54 | atexit(clean_memory); 55 | 56 | // Control count of arguments 57 | if (argc < 2) FAIL("Not enough arguments provided\n") 58 | 59 | // Handle room size argument 60 | int waiting_room_size = (int) strtol(argv[1], 0, 10); 61 | if (waiting_room_size > BARBER_MAX_QUEUE_SIZE) 62 | FAIL("Provided room size was too big\n") 63 | 64 | // Create shared memory 65 | shared_memory_fd = shm_open( 66 | PROJECT_PATH, 67 | O_RDWR | O_CREAT | O_EXCL, 68 | S_IRWXU | S_IRWXG 69 | ); 70 | 71 | if (shared_memory_fd == -1) 72 | FAIL("Couldn't create shared memory\n") 73 | 74 | // Truncate file 75 | int error = ftruncate(shared_memory_fd, sizeof(*barbershop)); 76 | 77 | if (error == -1) 78 | FAIL("Failed truncating file\n"); 79 | 80 | // Access shared memory 81 | barbershop = mmap( 82 | NULL, // address 83 | sizeof(*barbershop), // length 84 | PROT_READ | PROT_WRITE, // prot (memory segment security) 85 | MAP_SHARED, // flags 86 | shared_memory_fd, // file descriptor 87 | 0 // offset 88 | ); 89 | 90 | if (barbershop == (void*) -1) 91 | FAIL("Couldn't access shared memory\n") 92 | 93 | semaphore = sem_open( 94 | PROJECT_PATH, // path 95 | O_WRONLY | O_CREAT | O_EXCL, // flags 96 | S_IRWXU | S_IRWXG, // mode 97 | 0 // value 98 | ); 99 | 100 | if (semaphore == (void*) -1) 101 | FAIL("Couldn't create semaphore\n") 102 | 103 | // Initialize the barbershop 104 | barbershop->status_of_barber = SLEEPING_INACTIVE; 105 | barbershop->waiting_room_size = waiting_room_size; 106 | barbershop->client_count = 0; 107 | barbershop->current_client = 0; 108 | 109 | // Initialize empty clients fifo_queue_of_clients 110 | for (int i = 0; i < BARBER_MAX_QUEUE_SIZE; ++i) barbershop->fifo_queue_of_clients[i] = 0; 111 | } 112 | 113 | int main(int argc, char** argv) { 114 | initialize_barbershop(argc, argv); 115 | 116 | release_sem(semaphore); 117 | 118 | while(1) { 119 | take_sem(semaphore); 120 | 121 | switch (barbershop->status_of_barber) { 122 | case IDLE: 123 | if (is_queue_empty()) { 124 | printf("%lo barber: barber fell asleep\n", current_time()); 125 | barbershop->status_of_barber = SLEEPING_INACTIVE; 126 | } else { 127 | // Invite client from fifo_queue_of_clients and then go to ready state 128 | // (which will make the barber serve the customer) 129 | invite_client_to_the_chair(); 130 | barbershop->status_of_barber = READY_FOR_SHAVING; 131 | } 132 | break; 133 | case AWAKEN_BY_CLIENT: 134 | printf("%lo barber: woke up\n", current_time()); 135 | barbershop->status_of_barber = READY_FOR_SHAVING; 136 | break; 137 | case SHAVING_CLIENT: 138 | shave(); 139 | barbershop->status_of_barber = READY_FOR_SHAVING; 140 | break; 141 | default: 142 | break; 143 | } 144 | 145 | release_sem(semaphore); 146 | } 147 | } -------------------------------------------------------------------------------- /zestaw7/zad2/handler_of_clients.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "shared_utils.h" 18 | 19 | 20 | enum Client_status status; 21 | int shared_memory_fd; 22 | sem_t* semaphore; 23 | 24 | 25 | void initialize_clients() { 26 | shared_memory_fd = shm_open(PROJECT_PATH, O_RDWR, S_IRWXU | S_IRWXG); 27 | 28 | if (shared_memory_fd == -1) 29 | FAIL("Couldn't create shared memory\n") 30 | 31 | 32 | barbershop = mmap(NULL, 33 | sizeof(*barbershop), 34 | PROT_READ | PROT_WRITE, 35 | MAP_SHARED, 36 | shared_memory_fd, 37 | 0); 38 | 39 | if (barbershop == (void*) -1) 40 | FAIL("Couldn't access shared memory\n") 41 | 42 | semaphore = sem_open(PROJECT_PATH, O_WRONLY); 43 | 44 | if (semaphore == (void*) -1) 45 | FAIL("Couldn't create semaphore\n") 46 | } 47 | 48 | void take_barbers_chair() { 49 | pid_t client_pid = getpid(); 50 | 51 | if (status == INVITED) { 52 | pop_queue(); 53 | } else if (status == JUST_ARRIVED) { 54 | while (1) { 55 | release_sem(semaphore); 56 | take_sem(semaphore); 57 | if (barbershop->status_of_barber == READY_FOR_SHAVING) break; 58 | } 59 | status = INVITED; 60 | } 61 | barbershop->current_client = client_pid; 62 | printf("%lo: #%i: took place in the chair\n", current_time(), client_pid); 63 | } 64 | 65 | void trigger_barbers_client(int number_of_shaves) { 66 | pid_t current_client_pid = getpid(); 67 | int cuts_already_done = 0; 68 | 69 | while (cuts_already_done < number_of_shaves) { 70 | status = JUST_ARRIVED; 71 | 72 | take_sem(semaphore); 73 | 74 | if (barbershop->status_of_barber == SLEEPING_INACTIVE) { 75 | printf("%lo #%i: woke up the barber\n", current_time(), current_client_pid); 76 | barbershop->status_of_barber = AWAKEN_BY_CLIENT; 77 | take_barbers_chair(); 78 | barbershop->status_of_barber = SHAVING_CLIENT; 79 | } else if (!queue_full()) { 80 | get_in_queue(current_client_pid); 81 | printf("%lo #%i: entering the fifo_queue_of_clients\n", current_time(), current_client_pid); 82 | } else { 83 | printf("%lo #%i: could not find place in the fifo_queue_of_clients\n", current_time(), current_client_pid); 84 | release_sem(semaphore); 85 | return; 86 | } 87 | 88 | release_sem(semaphore); 89 | 90 | while(status < INVITED) { 91 | take_sem(semaphore); 92 | if (barbershop->current_client == current_client_pid) { 93 | status = INVITED; 94 | take_barbers_chair(); 95 | barbershop->status_of_barber = SHAVING_CLIENT; 96 | } 97 | release_sem(semaphore); 98 | } 99 | 100 | while(status < SHAVED) { 101 | take_sem(semaphore); 102 | if (barbershop->current_client != current_client_pid) { 103 | status = SHAVED; 104 | printf("%lo #%i: shaved\n", current_time(), current_client_pid); 105 | barbershop->status_of_barber = IDLE; 106 | cuts_already_done++; 107 | } 108 | release_sem(semaphore); 109 | } 110 | } 111 | printf("%lo #%i: left barbershop after %i cuts_already_done\n", current_time(), current_client_pid, number_of_shaves); 112 | } 113 | 114 | int main(int argc, char** argv) { 115 | if (argc < 3) FAIL("Not enough arguments provided\n") 116 | int number_of_clients_to_be_spawned = (int) strtol(argv[1], 0, 10); 117 | int number_of_shaves_to_be_done = (int) strtol(argv[2], 0, 10); 118 | initialize_clients(); 119 | 120 | for (int i = 0; i < number_of_clients_to_be_spawned; i++) { 121 | if (!fork()) { 122 | trigger_barbers_client(number_of_shaves_to_be_done); 123 | exit(0); 124 | } 125 | } 126 | while (wait(0)) if (errno != ECHILD) break; 127 | } 128 | -------------------------------------------------------------------------------- /zestaw7/zad2/shared_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include 5 | #include 6 | 7 | 8 | #define RED_COLOR "\e[1;31m" 9 | #define RESET_COLOR "\e[0m" 10 | 11 | #define FAIL(format, ...) { \ 12 | printf(RED_COLOR format RESET_COLOR, ##__VA_ARGS__); \ 13 | exit(-1); } 14 | 15 | 16 | #define PROJECT_PATH "/xC000FFEE" 17 | 18 | #define BARBER_MAX_QUEUE_SIZE 64 19 | 20 | enum Barber_status { 21 | SLEEPING_INACTIVE, 22 | AWAKEN_BY_CLIENT, 23 | READY_FOR_SHAVING, 24 | IDLE, 25 | SHAVING_CLIENT 26 | }; 27 | 28 | enum Client_status { 29 | JUST_ARRIVED, 30 | INVITED, 31 | SHAVED 32 | }; 33 | 34 | struct Barber_info { 35 | enum Barber_status status_of_barber; 36 | int client_count; 37 | int waiting_room_size; 38 | pid_t current_client; 39 | pid_t fifo_queue_of_clients[BARBER_MAX_QUEUE_SIZE]; 40 | } *barbershop; 41 | 42 | 43 | long current_time() { 44 | struct timespec buffer; 45 | clock_gettime(CLOCK_MONOTONIC, &buffer); 46 | return buffer.tv_nsec / 1000; 47 | } 48 | 49 | 50 | void take_sem(sem_t *semaphore) { 51 | int error = sem_wait(semaphore); 52 | if (error == -1) FAIL("Semaphore error: %s", strerror(errno)) 53 | } 54 | 55 | void release_sem(sem_t *semaphore) { 56 | int error = sem_post(semaphore); 57 | if (error == -1) FAIL("Semaphore error: %s", strerror(errno)) 58 | } 59 | 60 | 61 | int queue_full() { 62 | if (barbershop->client_count < barbershop->waiting_room_size) return 0; 63 | return 1; 64 | } 65 | 66 | int is_queue_empty() { 67 | if (barbershop->client_count == 0) return 1; 68 | return 0; 69 | } 70 | 71 | void get_in_queue(pid_t pid) { 72 | barbershop->fifo_queue_of_clients[barbershop->client_count] = pid; 73 | barbershop->client_count += 1; 74 | } 75 | 76 | void pop_queue() { 77 | for (int i = 0; i < barbershop->client_count - 1; ++i) { 78 | barbershop->fifo_queue_of_clients[i] = barbershop->fifo_queue_of_clients[i + 1]; 79 | } 80 | 81 | barbershop->fifo_queue_of_clients[barbershop->client_count - 1] = 0; 82 | barbershop->client_count -= 1; 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /zestaw8/edge_detection.txt: -------------------------------------------------------------------------------- 1 | 3 2 | -1 -1 -1 3 | -1 8 -1 4 | -1 -1 -1 5 | -------------------------------------------------------------------------------- /zestaw8/elephant.txt: -------------------------------------------------------------------------------- 1 | 32 2 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 4 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 5 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 6 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 7 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 9 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 10 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 11 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 12 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 13 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 14 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 15 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 16 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 17 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 18 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 19 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 20 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 21 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 8 8 8 8 8 8 8 8 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 22 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 23 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 24 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 25 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 26 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 27 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 28 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 29 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 30 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 31 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 32 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 33 | -------------------------------------------------------------------------------- /zestaw8/jablko.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osdnk/sysopy/c134795c64a1e9a84b6c30e99f224a4694a47ac0/zestaw8/jablko.jpeg -------------------------------------------------------------------------------- /zestaw8/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define FAIL(format, ...) { \ 11 | printf(RED_COLOR format RESET_COLOR, ##__VA_ARGS__); \ 12 | exit(-1); } 13 | #define RED_COLOR "\e[1;31m" 14 | #define RESET_COLOR "\e[0m" 15 | 16 | 17 | const int buff_size = 512; 18 | 19 | typedef struct thread_info { 20 | int b; 21 | int e; 22 | } thread_info; 23 | 24 | void save_picture(int w, int h, int **out_pict_matrix, FILE *fp) { 25 | char buff[1024]; 26 | fprintf(fp, "P2\n"); 27 | fprintf(fp, "%d %d\n", w, h); 28 | fprintf(fp, "%d\n", 255); 29 | for (int i = 0; i < h; i++) { 30 | for (int j = 0; j < w; j++) { 31 | if (j < w - 1) { 32 | sprintf(buff, "%d ", out_pict_matrix[i][j]); 33 | } else { 34 | sprintf(buff, "%d\n", out_pict_matrix[i][j]); 35 | } 36 | fputs(buff, fp); 37 | } 38 | } 39 | } 40 | 41 | 42 | 43 | clock_t sub_time(clock_t start, clock_t end) { 44 | return (end - start) / sysconf(_SC_CLK_TCK); 45 | } 46 | 47 | void add_results_to_file(clock_t *r_time, struct tms *ttime, int number_of_threads) { 48 | FILE *fp = fopen("results", "a"); 49 | fprintf(fp, "\n\nNumber of number_of_threads: %d\n", number_of_threads); 50 | fprintf(fp, "Real: %.2lf s ", (double)sub_time(r_time[0], r_time[1])); 51 | fprintf(fp, "User: %.2lf s ", 52 | (double)sub_time(ttime[0].tms_utime, ttime[1].tms_utime)); 53 | fprintf(fp, "System: %.2lf s\n", 54 | (double)sub_time(ttime[0].tms_stime, ttime[1].tms_stime)); 55 | fprintf(fp, "\n\n"); 56 | fclose(fp); 57 | } 58 | 59 | 60 | int single_pixel(int x, int y, int w, int h, int c, int **I, 61 | double **K) { 62 | double px = 0; 63 | for (int j = 0; j < c; j++) { 64 | int b = (int) round(fmax(0, y - ceil((double) c / 2) + j)); 65 | b = b < h ? b : h - 1; 66 | for (int i = 0; i < c; i++) { 67 | int a = (int) round(fmax(0, x - ceil((double) c / 2) + i)); 68 | a = a < w ? a : w - 1; 69 | double v = I[b][a] * K[j][i]; 70 | px += v; 71 | } 72 | } 73 | px = px < 0 ? 0 : px; 74 | return (int) round(px); 75 | } 76 | 77 | 78 | 79 | 80 | int main(int argc, char **argv) { 81 | if (argc < 5) FAIL("Improper number of arguments\n"); 82 | FILE *file_in = fopen(argv[2], "r+"); 83 | if (file_in == NULL) FAIL("failed in"); 84 | FILE *file_filter = fopen(argv[3], "r+"); 85 | if (file_filter == NULL) FAIL("failed to filter"); 86 | FILE *file_out = fopen(argv[4], "w+"); 87 | if (file_out == NULL) FAIL("failed out"); 88 | 89 | char buff[buff_size]; 90 | 91 | clock_t r_time[2] = {0, 0}; 92 | struct tms tms_time[2]; 93 | 94 | int number_of_threads = (int) strtol(argv[1], NULL, 10); 95 | 96 | fgets(buff, buff_size, file_in); 97 | 98 | fgets(buff, buff_size, file_in); 99 | 100 | char *dimens; 101 | 102 | dimens = strdup(buff); 103 | int w = (int) strtol(strsep(&dimens, " \t"), NULL, 10); 104 | 105 | int h = (int) strtol(strsep(&dimens, " \t"), NULL, 10); 106 | 107 | 108 | 109 | int **picture = calloc((size_t) h, sizeof(int *)); 110 | for (int i = 0; i < h; i++) { 111 | picture[i] = calloc((size_t) w, sizeof(int)); 112 | } 113 | 114 | int **result_picture = calloc((size_t) h, sizeof(int *)); 115 | for (int i = 0; i < h; i++) { 116 | result_picture[i] = calloc((size_t) w, sizeof(int)); 117 | } 118 | 119 | fgets(buff, buff_size, file_in); 120 | 121 | int iter_column = 0; 122 | int iter_row = 0; 123 | while (fgets(buff, buff_size, file_in) != NULL) { 124 | for (char *word = strtok(buff, " \n\t\r"); word != NULL; 125 | word = strtok(NULL, " \t\n\r")) { 126 | picture[iter_row][iter_column] = (int)strtol(word, NULL, 10); 127 | iter_column++; 128 | if (iter_column == w) { 129 | iter_row++; 130 | iter_column = 0; 131 | } 132 | } 133 | } 134 | 135 | fclose(file_in); 136 | 137 | 138 | fgets(buff, buff_size, file_filter); 139 | 140 | int filter_size = (int) strtol(buff, NULL, 10); 141 | 142 | 143 | double** filter = calloc((size_t) filter_size, sizeof(double *)); 144 | for (int i = 0; i < filter_size; i++) { 145 | filter[i] = calloc((size_t) w, sizeof(int)); 146 | } 147 | 148 | 149 | 150 | for (int i = 0; i < filter_size; i++) { 151 | filter[i] = calloc((size_t) filter_size, sizeof(double)); 152 | iter_column++; 153 | if (iter_column == filter_size) { 154 | iter_row++; 155 | iter_column = 0; 156 | } 157 | } 158 | 159 | iter_column = 0; 160 | iter_row = 0; 161 | while (fgets(buff, buff_size, file_filter) != NULL) { 162 | for (char *word = strtok(buff, " \n\t\r"); word != NULL; 163 | word = strtok(NULL, " \t\n\r")) { 164 | filter[iter_row][iter_column] = strtod(word, NULL); 165 | iter_column++; 166 | if (iter_column == filter_size) { 167 | iter_row++; 168 | iter_column = 0; 169 | } 170 | 171 | } 172 | } 173 | 174 | pthread_t *thread = calloc((size_t) number_of_threads, sizeof(pthread_t)); 175 | struct thread_info **threads_info = malloc(number_of_threads * sizeof( struct thread_info *)); 176 | 177 | r_time[0] = times(&tms_time[0]); 178 | 179 | for (int i = 0; i < number_of_threads; i++) { 180 | threads_info[i] = malloc(sizeof(struct thread_info)); 181 | threads_info[i]->b = (i * w / number_of_threads); 182 | threads_info[i]->e = ((i + 1) * w / number_of_threads); 183 | } 184 | 185 | void *single_thread(void *infos) { 186 | struct thread_info *thread_infos = (struct thread_info *) infos; 187 | for (int y = 0; y b; x < thread_infos->e; x++) { 189 | result_picture[y][x] = single_pixel(x, y, w, h, filter_size, 190 | picture, filter); 191 | } 192 | 193 | return (void *) 0; 194 | 195 | } 196 | 197 | 198 | 199 | for (int i = 0; i < number_of_threads; i++) { 200 | pthread_create(&thread[i], NULL, single_thread, (void *) threads_info[i]); 201 | } 202 | 203 | for (int i = 0; i < number_of_threads; i++) { 204 | pthread_join(thread[i], NULL); 205 | free(threads_info[i]); 206 | } 207 | 208 | free(threads_info); 209 | 210 | r_time[1] = times(&tms_time[1]); 211 | 212 | save_picture(w, h, result_picture, file_out); 213 | add_results_to_file(r_time, tms_time, number_of_threads); 214 | 215 | for (int i = 0; i < h; i++) { 216 | free(picture[i]); 217 | } 218 | free(picture); 219 | 220 | fclose(file_out); 221 | for (int i = 0; i < h; i++) { 222 | free(result_picture[i]); 223 | } 224 | free(result_picture); 225 | 226 | fclose(file_filter); 227 | for (int i = 0; i < filter_size; i++) { 228 | free(filter[i]); 229 | } 230 | free(filter); 231 | } 232 | 233 | -------------------------------------------------------------------------------- /zestaw8/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -g -O0 -std=c11 -static -Wall -Isrc -rdynamic -fomit-frame-pointer 3 | all: compile test 4 | 5 | compile: 6 | $(CC) $(CFLAGS) main.c -o main -lm -Wl,--whole-archive -lpthread -Wl,--no-whole-archive 7 | 8 | test: 9 | # valgrind -v --track-origins=yes --keep-stacktraces=alloc-and-free 10 | ./main 1 "./jablko.pgm" "./edge_detection.txt" "./jablko_1.pgm" 11 | ./main 2 "./jablko.pgm" "./edge_detection.txt" "./jablko_2.pgm" 12 | ./main 4 "./jablko.pgm" "./edge_detection.txt" "./jablko_4.pgm" 13 | ./main 8 "./jablko.pgm" "./edge_detection.txt" "./jablko_8.pgm" 14 | 15 | ./main 1 "./melon.pgm" "./edge_detection.txt" "./melon_1.pgm" 16 | ./main 2 "./melon.pgm" "./edge_detection.txt" "./melon_2.pgm" 17 | ./main 4 "./melon.pgm" "./edge_detection.txt" "./melon_4.pgm" 18 | ./main 8 "./melon.pgm" "./edge_detection.txt" "./melon_8.pgm" 19 | 20 | ./main 1 "./melon.pgm" "./elephant.txt" "./elephant_1.pgm" 21 | ./main 2 "./melon.pgm" "./elephant.txt" "./elephant_2.pgm" 22 | ./main 4 "./melon.pgm" "./elephant.txt" "./elephant_4.pgm" 23 | ./main 8 "./melon.pgm" "./elephant.txt" "./elephant_8.pgm" 24 | 25 | 26 | 27 | clean: $(patsubst %.c, %.clean, $(wildcard *.c)) 28 | 29 | %.clean: 30 | rm -f $(@:.clean=) 31 | -------------------------------------------------------------------------------- /zestaw8/melon.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osdnk/sysopy/c134795c64a1e9a84b6c30e99f224a4694a47ac0/zestaw8/melon.jpeg -------------------------------------------------------------------------------- /zestaw8/time_res.txt: -------------------------------------------------------------------------------- 1 | threads: 1 2 | Real: 0.04 s User: 0.03 s System: 0.00 s 3 | 4 | 5 | threads: 2 6 | Real: 0.01 s User: 0.02 s System: 0.00 s 7 | 8 | 9 | threads: 4 10 | Real: 0.02 s User: 0.04 s System: 0.00 s 11 | 12 | 13 | threads: 8 14 | Real: 0.01 s User: 0.04 s System: 0.00 s 15 | 16 | 17 | threads: 1 18 | Real: 0.04 s User: 0.04 s System: 0.00 s 19 | 20 | 21 | threads: 2 22 | Real: 0.02 s User: 0.03 s System: 0.00 s 23 | 24 | 25 | threads: 4 26 | Real: 0.02 s User: 0.04 s System: 0.00 s 27 | 28 | 29 | threads: 8 30 | Real: 0.01 s User: 0.05 s System: 0.00 s 31 | 32 | 33 | threads: 1 34 | Real: 0.10 s User: 0.10 s System: 0.00 s 35 | 36 | 37 | threads: 2 38 | Real: 0.05 s User: 0.10 s System: 0.00 s 39 | 40 | 41 | threads: 4 42 | Real: 0.05 s User: 0.16 s System: 0.00 s 43 | 44 | 45 | threads: 8 46 | Real: 0.05 s User: 0.15 s System: 0.00 s 47 | 48 | 49 | threads: 1 50 | Real: 2.46 s User: 2.46 s System: 0.00 s 51 | 52 | 53 | threads: 2 54 | Real: 1.27 s User: 2.53 s System: 0.00 s 55 | 56 | 57 | threads: 4 58 | Real: 1.07 s User: 4.15 s System: 0.00 s 59 | 60 | 61 | threads: 8 62 | Real: 1.07 s User: 4.16 s System: 0.00 s 63 | 64 | 65 | threads: 1 66 | Real: 8.22 s User: 8.19 s System: 0.02 s 67 | 68 | 69 | threads: 2 70 | Real: 4.24 s User: 8.45 s System: 0.00 s 71 | 72 | 73 | threads: 4 74 | Real: 3.78 s User: 13.89 s System: 0.01 s 75 | 76 | 77 | threads: 8 78 | Real: 3.73 s User: 13.85 s System: 0.05 s 79 | 80 | 81 | threads: 1 82 | Real: 0.04 s User: 0.04 s System: 0.00 s 83 | 84 | 85 | threads: 2 86 | Real: 0.02 s User: 0.03 s System: 0.00 s 87 | 88 | 89 | threads: 4 90 | Real: 0.01 s User: 0.05 s System: 0.00 s 91 | 92 | 93 | threads: 8 94 | Real: 0.01 s User: 0.04 s System: 0.00 s 95 | 96 | 97 | threads: 1 98 | Real: 0.09 s User: 0.10 s System: 0.00 s 99 | 100 | 101 | threads: 2 102 | Real: 0.06 s User: 0.11 s System: 0.00 s 103 | 104 | 105 | threads: 4 106 | Real: 0.04 s User: 0.16 s System: 0.00 s 107 | 108 | 109 | threads: 8 110 | Real: 0.05 s User: 0.15 s System: 0.00 s 111 | 112 | 113 | threads: 1 114 | Real: 8.31 s User: 8.30 s System: 0.00 s 115 | 116 | 117 | threads: 2 118 | Real: 4.24 s User: 8.45 s System: 0.00 s 119 | 120 | 121 | threads: 4 122 | Real: 3.77 s User: 13.28 s System: 0.43 s 123 | 124 | 125 | threads: 8 126 | Real: 3.74 s User: 13.79 s System: 0.05 s 127 | 128 | 129 | -------------------------------------------------------------------------------- /zestaw9/zad1/config: -------------------------------------------------------------------------------- 1 | 15 2 | 10 3 | 20 4 | Pan_Tadeusz.txt 5 | 594 6 | 0 7 | 0 8 | 0 -------------------------------------------------------------------------------- /zestaw9/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FAILURE_EXIT(code, format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(code);} 10 | 11 | char **buffer; 12 | pthread_mutex_t *b_mutex; 13 | pthread_cond_t w_cond; 14 | pthread_cond_t r_cond; 15 | int P, K, N, L, nk, search, verbose; 16 | FILE *file; 17 | char file_name[FILENAME_MAX]; 18 | int production_index = 0, consumption_index = 0; 19 | int finished = 0; 20 | pthread_t *p_threads; 21 | pthread_t *k_threads; 22 | 23 | void sig_hanlder(int signo) { 24 | fprintf(stderr, "Received signal %s, Canceling threads\n", signo == SIGALRM ? "SIGALRM" : "SIGINT"); 25 | for (int p = 0; p < P; p++) 26 | pthread_cancel(p_threads[p]); 27 | for (int k = 0; k < K; k++) 28 | pthread_cancel(k_threads[k]); 29 | exit(EXIT_SUCCESS); 30 | } 31 | 32 | void configurate(char *config_path) { 33 | FILE *config; 34 | if ((config = fopen(config_path, "r")) == NULL) FAILURE_EXIT(2, "Opening config file failed"); 35 | fscanf(config, "%d %d %d %s %d %d %d %d", &P, &K, &N, file_name, &L, &search, &verbose, &nk); 36 | printf("CONFIGURATION\nP: %d\nK: %d\nN: %d\nFile Name: %s\nL: %d\nSearch Mode: %d\nVerbose: %d\nnk: %d\n", P, K, N, 37 | file_name, L, search, verbose, nk); 38 | fclose(config); 39 | } 40 | 41 | void __init__() { 42 | signal(SIGINT, sig_hanlder); 43 | if (nk > 0) signal(SIGALRM, sig_hanlder); 44 | 45 | if ((file = fopen(file_name, "r")) == NULL) FAILURE_EXIT(2, "Opening file failed"); 46 | 47 | buffer = calloc((size_t) N, sizeof(char *)); 48 | 49 | b_mutex = malloc((N + 2) * sizeof(pthread_mutex_t)); 50 | for (int i = 0; i < N + 2; ++i) 51 | pthread_mutex_init(&b_mutex[i], NULL); 52 | 53 | pthread_cond_init(&w_cond, NULL); 54 | pthread_cond_init(&r_cond, NULL); 55 | 56 | p_threads = malloc(P * sizeof(pthread_t)); 57 | k_threads = malloc(K * sizeof(pthread_t)); 58 | } 59 | 60 | void __del__() { 61 | if (file) fclose(file); 62 | 63 | for (int i = 0; i < N; ++i) 64 | if (buffer[i]) free(buffer[i]); 65 | free(buffer); 66 | 67 | for (int j = 0; j < N + 2; ++j) 68 | pthread_mutex_destroy(&b_mutex[j]); 69 | free(b_mutex); 70 | 71 | pthread_cond_destroy(&w_cond); 72 | pthread_cond_destroy(&r_cond); 73 | } 74 | 75 | int length_search(int line_length){ 76 | return search == (line_length > L ? 1 : line_length < L ? -1 : 0); 77 | } 78 | 79 | void *producer(void *pVoid) { 80 | int index; 81 | char line[LINE_MAX]; 82 | while (fgets(line, LINE_MAX, file) != NULL) { 83 | if(verbose) fprintf(stderr, "Producer[%ld]: taking file line\n", pthread_self()); 84 | pthread_mutex_lock(&b_mutex[N]); 85 | 86 | while (buffer[production_index] != NULL) 87 | pthread_cond_wait(&w_cond, &b_mutex[N]); 88 | 89 | index = production_index; 90 | if(verbose) fprintf(stderr, "Producer[%ld]: taking buffer index (%d)\n", pthread_self(), index); 91 | production_index = (production_index + 1) % N; 92 | 93 | 94 | pthread_mutex_lock(&b_mutex[index]); 95 | 96 | buffer[index] = malloc((strlen(line) + 1) * sizeof(char)); 97 | strcpy(buffer[index], line); 98 | if(verbose) fprintf(stderr, "Producer[%ld]: line copied to buffer at index (%d)\n", pthread_self(), index); 99 | 100 | pthread_cond_broadcast(&r_cond); 101 | pthread_mutex_unlock(&b_mutex[index]); 102 | pthread_mutex_unlock(&b_mutex[N]); 103 | } 104 | if(verbose) fprintf(stderr, "Producer[%ld]: Finished\n", pthread_self()); 105 | return NULL; 106 | } 107 | 108 | void *consumer(void *pVoid) { 109 | char *line; 110 | int index; 111 | while (1) { 112 | pthread_mutex_lock(&b_mutex[N + 1]); 113 | 114 | while (buffer[consumption_index] == NULL) { 115 | if (finished) { 116 | pthread_mutex_unlock(&b_mutex[N + 1]); 117 | if(verbose) fprintf(stderr, "Consumer[%ld]: Finished \n", pthread_self()); 118 | return NULL; 119 | } 120 | pthread_cond_wait(&r_cond, &b_mutex[N + 1]); 121 | } 122 | 123 | index = consumption_index; 124 | if(verbose) fprintf(stderr, "Consumer[%ld]: taking buffer index (%d)\n", pthread_self(), index); 125 | consumption_index = (consumption_index + 1) % N; 126 | 127 | pthread_mutex_lock(&b_mutex[index]); 128 | pthread_mutex_unlock(&b_mutex[N + 1]); 129 | 130 | line = buffer[index]; 131 | buffer[index] = NULL; 132 | if(verbose) fprintf(stderr, "Consumer[%ld]: taking line from buffer at index (%d)\n", pthread_self(), index); 133 | 134 | pthread_cond_broadcast(&w_cond); 135 | pthread_mutex_unlock(&b_mutex[index]); 136 | 137 | if(length_search((int) strlen(line))){ 138 | if(verbose) fprintf(stderr, "Consumer[%ld]: found line with length %d %c %d\n", 139 | pthread_self(), (int) strlen(line), search == 1 ? '>' : search == -1 ? '<' : '=', L); 140 | fprintf(stderr, "Consumer[%ld]: Index(%d), %s", pthread_self(), index, line); 141 | } 142 | free(line); 143 | usleep(10); 144 | } 145 | } 146 | 147 | void start_threads() { 148 | for (int p = 0; p < P; ++p) 149 | pthread_create(&p_threads[p], NULL, producer, NULL); 150 | for (int k = 0; k < K; ++k) 151 | pthread_create(&k_threads[k], NULL, consumer, NULL); 152 | if (nk > 0) alarm(nk); 153 | } 154 | 155 | void join_threads(){ 156 | for (int p = 0; p < P; ++p) 157 | pthread_join(p_threads[p], NULL); 158 | finished = 1; 159 | pthread_cond_broadcast(&r_cond); 160 | for (int k = 0; k < K; ++k) 161 | pthread_join(k_threads[k], NULL); 162 | } 163 | 164 | int main(int argc, char **argv) { 165 | if (argc < 2) FAILURE_EXIT(2, "./main "); 166 | 167 | configurate(argv[1]); 168 | 169 | __init__(); 170 | 171 | start_threads(); 172 | 173 | join_threads(); 174 | 175 | __del__(); 176 | 177 | return 0; 178 | } -------------------------------------------------------------------------------- /zestaw9/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -g -O2 -std=gnu99 -Wall -lpthread 3 | 4 | all: $(patsubst %.c, %.out, $(wildcard *.c)) 5 | 6 | %.out: %.c Makefile 7 | $(CC) $(CFLAGS) $< -o $(@:.out=) 8 | 9 | clean: $(patsubst %.c, %.clean, $(wildcard *.c)) 10 | 11 | %.clean: 12 | rm -f $(@:.clean=) 13 | -------------------------------------------------------------------------------- /zestaw9/zad2/config: -------------------------------------------------------------------------------- 1 | 15 2 | 10 3 | 20 4 | Pan_Tadeusz.txt 5 | 594 6 | 0 7 | 0 8 | 0 -------------------------------------------------------------------------------- /zestaw9/zad2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define FAILURE_EXIT(code, format, ...) { fprintf(stderr, format, ##__VA_ARGS__); exit(code);} 11 | 12 | char **buffer; 13 | sem_t *b_sem; 14 | int P, K, N, L, nk, search, verbose; 15 | FILE *file; 16 | char file_name[FILENAME_MAX]; 17 | int production_index = 0, consumption_index = 0; 18 | int finished = 0; 19 | pthread_t *p_threads; 20 | pthread_t *k_threads; 21 | 22 | void sig_hanlder(int signo) { 23 | fprintf(stderr, "Received signal %s, Canceling threads\n", signo == SIGALRM ? "SIGALRM" : "SIGINT"); 24 | for (int p = 0; p < P; p++) 25 | pthread_cancel(p_threads[p]); 26 | for (int k = 0; k < K; k++) 27 | pthread_cancel(k_threads[k]); 28 | exit(EXIT_SUCCESS); 29 | } 30 | 31 | void configurate(char *config_path) { 32 | FILE *config; 33 | if ((config = fopen(config_path, "r")) == NULL) FAILURE_EXIT(2, "Opening config file failed"); 34 | fscanf(config, "%d %d %d %s %d %d %d %d", &P, &K, &N, file_name, &L, &search, &verbose, &nk); 35 | printf("CONFIGURATION\nP: %d\nK: %d\nN: %d\nFile Name: %s\nL: %d\nSearch Mode: %d\nVerbose: %d\nnk: %d\n", P, K, N, 36 | file_name, L, search, verbose, nk); 37 | fclose(config); 38 | } 39 | 40 | void __init__() { 41 | signal(SIGINT, sig_hanlder); 42 | if (nk > 0) signal(SIGALRM, sig_hanlder); 43 | 44 | if ((file = fopen(file_name, "r")) == NULL) FAILURE_EXIT(2, "Opening file failed"); 45 | 46 | buffer = calloc((size_t) N, sizeof(char *)); 47 | 48 | b_sem = malloc((N + 3) * sizeof(sem_t)); 49 | for (int i = 0; i < N + 2; ++i) 50 | sem_init(&b_sem[i], 0, 1); 51 | sem_init(&b_sem[N+2], 0, (unsigned int) N); 52 | 53 | p_threads = malloc(P * sizeof(pthread_t)); 54 | k_threads = malloc(K * sizeof(pthread_t)); 55 | } 56 | 57 | void __del__() { 58 | if (file) fclose(file); 59 | 60 | for (int i = 0; i < N; ++i) 61 | if (buffer[i]) free(buffer[i]); 62 | free(buffer); 63 | 64 | for (int j = 0; j < N + 4; ++j) 65 | sem_destroy(&b_sem[j]); 66 | free(b_sem); 67 | } 68 | 69 | int length_search(int line_length){ 70 | return search == (line_length > L ? 1 : line_length < L ? -1 : 0); 71 | } 72 | 73 | void *producer(void *pVoid) { 74 | int index; 75 | char line[LINE_MAX]; 76 | while (fgets(line, LINE_MAX, file) != NULL) { 77 | if(verbose) fprintf(stderr, "Producer[%ld]: taking file line\n", pthread_self()); 78 | sem_wait(&b_sem[N]); 79 | 80 | sem_wait(&b_sem[N+2]); 81 | 82 | index = production_index; 83 | if(verbose) fprintf(stderr, "Producer[%ld]: taking buffer index (%d)\n", pthread_self(), index); 84 | production_index = (production_index + 1) % N; 85 | 86 | 87 | sem_wait(&b_sem[index]); 88 | sem_post(&b_sem[N]); 89 | 90 | buffer[index] = malloc((strlen(line) + 1) * sizeof(char)); 91 | strcpy(buffer[index], line); 92 | if(verbose) fprintf(stderr, "Producer[%ld]: line copied to buffer at index (%d)\n", pthread_self(), index); 93 | 94 | sem_post(&b_sem[index]); 95 | } 96 | if(verbose) fprintf(stderr, "Producer[%ld]: Finished\n", pthread_self()); 97 | return NULL; 98 | } 99 | 100 | void *consumer(void *pVoid) { 101 | char *line; 102 | int index; 103 | while (1) { 104 | sem_wait(&b_sem[N+1]); 105 | while (buffer[consumption_index] == NULL) { 106 | sem_post(&b_sem[N+1]); 107 | if(finished){ 108 | if(verbose) fprintf(stderr, "Consumer[%ld]: Finished \n", pthread_self()); 109 | return NULL; 110 | } 111 | sem_wait(&b_sem[N+1]); 112 | } 113 | 114 | index = consumption_index; 115 | if(verbose) fprintf(stderr, "Consumer[%ld]: taking buffer index (%d)\n", pthread_self(), index); 116 | consumption_index = (consumption_index + 1) % N; 117 | 118 | sem_wait(&b_sem[index]); 119 | 120 | line = buffer[index]; 121 | buffer[index] = NULL; 122 | if(verbose) fprintf(stderr, "Consumer[%ld]: taking line from buffer at index (%d)\n", pthread_self(), index); 123 | 124 | sem_post(&b_sem[N+2]); 125 | sem_post(&b_sem[N + 1]); 126 | sem_post(&b_sem[index]); 127 | 128 | if(length_search((int) strlen(line))){ 129 | if(verbose) fprintf(stderr, "Consumer[%ld]: found line with length %d %c %d\n", 130 | pthread_self(), (int) strlen(line), search == 1 ? '>' : search == -1 ? '<' : '=', L); 131 | fprintf(stderr, "Consumer[%ld]: Index(%d), %s", pthread_self(), index, line); 132 | } 133 | free(line); 134 | } 135 | } 136 | 137 | void start_threads() { 138 | for (int p = 0; p < P; ++p) 139 | pthread_create(&p_threads[p], NULL, producer, NULL); 140 | for (int k = 0; k < K; ++k) 141 | pthread_create(&k_threads[k], NULL, consumer, NULL); 142 | if (nk > 0) alarm(nk); 143 | } 144 | 145 | void join_threads(){ 146 | for (int p = 0; p < P; ++p) 147 | pthread_join(p_threads[p], NULL); 148 | finished = 1; 149 | for (int k = 0; k < K; ++k) 150 | pthread_join(k_threads[k], NULL); 151 | } 152 | 153 | int main(int argc, char **argv) { 154 | if (argc < 2) FAILURE_EXIT(2, "./main "); 155 | 156 | configurate(argv[1]); 157 | 158 | __init__(); 159 | 160 | start_threads(); 161 | 162 | join_threads(); 163 | 164 | __del__(); 165 | 166 | return 0; 167 | } -------------------------------------------------------------------------------- /zestaw9/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -g -O2 -std=gnu99 -Wall -lpthread 3 | 4 | all: $(patsubst %.c, %.out, $(wildcard *.c)) 5 | 6 | %.out: %.c Makefile 7 | $(CC) $(CFLAGS) $< -o $(@:.out=) 8 | 9 | clean: $(patsubst %.c, %.clean, $(wildcard *.c)) 10 | 11 | %.clean: 12 | rm -f $(@:.clean=) 13 | --------------------------------------------------------------------------------