diff --git a/CMakeLists.txt b/CMakeLists.txt index 9950096..b0208c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,4 +13,5 @@ function(define_lab lab_name) message("${lab_name} defined.") endfunction() -define_lab(lab2) \ No newline at end of file +define_lab(lab2) +define_lab(lab3) \ No newline at end of file diff --git a/README.md b/README.md index a54aa66..8d84ac4 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ## Список - [Лабораторная работа 2](lab2/README.md) +- [Лабораторная работа 3](lab3/README.md) ## Запуск diff --git a/lab3/.execme b/lab3/.execme new file mode 100755 index 0000000..83f1e9c --- /dev/null +++ b/lab3/.execme @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -euo pipefail +IFS=$'\n\t' + +echo "Task 4,3" + +mem_allocs=(1 16 128 512) +for i in "${mem_allocs[@]}" ; do + echo "Running with $i Mb allocation..." + "$1/lab3_memory-user.c_run" "$i" & + JOB_PID=$! + sleep 3 + + echo "pmap -X $JOB_PID command:" + pmap -X $JOB_PID + echo + + echo "Before termination:" + echo "free -m command:" + free -m + echo + + kill $JOB_PID + sleep 3 + echo "After termination:" + free -m + echo "------------------" +done diff --git a/lab3/CMakeLists.txt b/lab3/CMakeLists.txt new file mode 100644 index 0000000..3cbfa94 --- /dev/null +++ b/lab3/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.16) +set(CMAKE_C_STANDARD 11) + +# Lab name +set(LAB_NAME "lab3") + +# Lab tasks +list(APPEND SOURCE_FILES + memory-user.c + ) +list(APPEND NON_COMPILABLE_SRC + .execme + ) + +### Here goes the template + +project("${LAB_NAME}" C) + +add_custom_target("${LAB_NAME}") + +foreach (file IN LISTS SOURCE_FILES) + add_executable("${LAB_NAME}_${file}_run" "${file}") + add_dependencies("${LAB_NAME}" "${LAB_NAME}_${file}_run") +endforeach () + +foreach (file IN LISTS NON_COMPILABLE_SRC) + add_custom_command( + TARGET "${LAB_NAME}" POST_BUILD + DEPENDS "${file}" + COMMAND ${CMAKE_COMMAND} -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/${file}" + "${CMAKE_CURRENT_BINARY_DIR}/${file}" + ) +endforeach () \ No newline at end of file diff --git a/lab3/README.md b/lab3/README.md new file mode 100644 index 0000000..3a2fbe1 --- /dev/null +++ b/lab3/README.md @@ -0,0 +1,27 @@ +# Лабораторная работа №3 + +Были рассмотрены аллокации памяти размером 1, 16, 128 и 512 Мб. + +Для выполнения заданий 4 и 3 был использован скрипт для оболочки bash, запускаемый точно так же, как и остальные +лабораторные: `./run_lab.sh lab3` из директории со всеми работами. + +Он запускает программу [memory-user.c](memory-user.c) из первого задания с заданным объёмом памяти на выделение. +Через 3 секунды запускается `pmap` для исследования распределения памяти, затем `free`. После этого исполняется +`kill`, memory-user завершает работу. Запускаются те же `pmap` и `free` для сравнения. + +Задержка 3 секунды после вызова `kill` необходима для того, чтобы система успела освободить память. При выделении +2048 Мб память успевает высвобождаться лишь наполовину. + +Ниже можно увидеть вывод скрипта для разных объёмов выделенной памяти: + +**1 Mb:** +![1Mb](alloc_1mb.png) + +**16 Mb:** +![16Mb](alloc_16mb.png) + +**128 Mb:** +![128Mb](alloc_128mb.png) + +**512 Mb:** +![512Mb](alloc_512mb.png) \ No newline at end of file diff --git a/lab3/alloc_128mb.png b/lab3/alloc_128mb.png new file mode 100644 index 0000000..8d72f8b Binary files /dev/null and b/lab3/alloc_128mb.png differ diff --git a/lab3/alloc_16mb.png b/lab3/alloc_16mb.png new file mode 100644 index 0000000..15c67f7 Binary files /dev/null and b/lab3/alloc_16mb.png differ diff --git a/lab3/alloc_1mb.png b/lab3/alloc_1mb.png new file mode 100644 index 0000000..305cec5 Binary files /dev/null and b/lab3/alloc_1mb.png differ diff --git a/lab3/alloc_512mb.png b/lab3/alloc_512mb.png new file mode 100644 index 0000000..3e66b98 Binary files /dev/null and b/lab3/alloc_512mb.png differ diff --git a/lab3/memory-user.c b/lab3/memory-user.c new file mode 100644 index 0000000..1740a03 --- /dev/null +++ b/lab3/memory-user.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + printf("Current PID: %d\n", getpid()); + + const unsigned long mb_size = 1 << 20; // NOLINT: pow(2, 20) won't even touch the significant bit + unsigned long alloc_size = 0; + + if (argc > 1) { + alloc_size = atoi(argv[1]); // NOLINT: educational purpose only + } else { + scanf("%ld", &alloc_size); // NOLINT: educational purpose only + } + + alloc_size *= mb_size; + + int *array = malloc(alloc_size); + printf("Allocated %ldMb at %p\n", alloc_size / mb_size, array); + + srand(alloc_size); + unsigned long arr_size = alloc_size / sizeof(*array); + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "EndlessLoop" + // Intentional endless loop + while (1) { + for (int i = 0; i < arr_size; ++i) { + array[i] = rand(); // NOLINT: randomness of rand() is unimportant in this case + } + } +#pragma clang diagnostic pop + return 0; +} \ No newline at end of file diff --git a/scripts/run_all.sh b/scripts/run_all.sh index cee40ce..d471aff 100755 --- a/scripts/run_all.sh +++ b/scripts/run_all.sh @@ -5,6 +5,21 @@ IFS=$'\n\t' echo -e "\nTesting script started...\n" +if [ -f "$1/.execme" ]; then + echo "Found .execme file!" + if [ -x "$1/.execme" ]; then + echo "Executing..." + "$1/.execme" "$1" + exit $? + else + echo ".execme couldn't be executed!" + echo "Run chmod +x \"$1/.execme\" ." + exit 1 + fi +fi + +echo "Using default exec all policy..." + while IFS= read -r -d '' FILE do echo "Executing $FILE..."