diff --git a/src/exercise-22/matrix_mul.c b/src/exercise-22/matrix_mul.c index 0752395ce7d9d15499ee37c49401d98b8fb86ccb..e5c49ced3e20617e1c4f86ed091f58345fd596f4 100644 --- a/src/exercise-22/matrix_mul.c +++ b/src/exercise-22/matrix_mul.c @@ -6,8 +6,14 @@ int ** multiply (int **A, int ASize, int *AColSize, int **B, int BSize, int *BColSize, int *returnSize, int **returnColumnSizes) { - (void)BSize; // Suppress unused parameter warning + // 首先检查矩阵是否可以相乘 + if (AColSize[0] != BSize) + { + printf ("矩阵的列数必须与另一个矩阵的行数相同。\n"); + return NULL; + } + // ASize 是 A 的行数,BSize 是 B 的行数 int **result = (int **)malloc (ASize * sizeof (int *)); *returnColumnSizes = (int *)malloc (ASize * sizeof (int)); @@ -18,6 +24,17 @@ multiply (int **A, int ASize, int *AColSize, int **B, int BSize, int *BColSize, } // 下面通过多重循环实现两个矩阵相乘 + // 计算结果矩阵 + for (int i = 0; i < ASize; i++) + { + for (int j = 0; j < BColSize[0]; j++) // BColSize 表示 B 的列数,BSize 是 B 的行数(=A 的列数),是不同的 + { + for (int k = 0; k < BSize; k++) + { + result[i][j] += A[i][k] * B[k][j]; + } + } + } *returnSize = ASize; return result; @@ -35,3 +52,4 @@ printMatrix (int **matrix, int rows, int cols) printf ("\n"); } } + diff --git a/src/exercise-23/convolution.c b/src/exercise-23/convolution.c index f86ec9e925c69da3fb1893ce743122c5785b4dd0..06f213323bda6a9dd8e36941a237edff1f77d9dd 100644 --- a/src/exercise-23/convolution.c +++ b/src/exercise-23/convolution.c @@ -7,13 +7,29 @@ convolution2D (int input[5][5], int kernel[3][3], int output[3][3], int i, j, m, n; int kernelRadius = kernelSize / 2; + // 初始化输出数组 for (i = 0; i < inputSize - kernelSize + 1; i++) + { + for (j = 0; j < inputSize - kernelSize + 1; j++) { - for (j = 0; j < inputSize - kernelSize + 1; j++) - { - output[i][j] = 0; - } + output[i][j] = 0; } + } // 在下面通过多重循环实现卷积运算 + for (i = kernelRadius; i < inputSize - kernelRadius; ++i) + { + for (j = kernelRadius; j < inputSize - kernelRadius; ++j) + { + for (m = -kernelRadius; m <= kernelRadius; ++m) + { + for (n = -kernelRadius; n <= kernelRadius; ++n) + { + output[i - kernelRadius][j - kernelRadius] + += input[i + m][j + n] * kernel[m + kernelRadius][n + kernelRadius]; + } + } + } + } } + diff --git a/src/exercise-24/matrix_trans.c b/src/exercise-24/matrix_trans.c index 9cdf524559a987366e169a378622337cf3df2210..5f78e6de960ddf5a9922e41911020c359c565775 100644 --- a/src/exercise-24/matrix_trans.c +++ b/src/exercise-24/matrix_trans.c @@ -4,9 +4,15 @@ void transposeInPlace (int matrix[N][N]) { - // 在下面实现矩阵原地转置,即空间复杂度为O(1) - - // + // 对角线上方的元素与对角线下方的元素交换 + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + // 交换 matrix[i][j] 和 matrix[j][i] + int temp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = temp; + } + } } void diff --git a/src/exercise-25/matrix_zero.c b/src/exercise-25/matrix_zero.c index ba1e8c2fcea32c88d435ecdf0ac941a97f578c02..2dade1c3a46a76ada05a9faa14731ae189f6f419 100644 --- a/src/exercise-25/matrix_zero.c +++ b/src/exercise-25/matrix_zero.c @@ -13,10 +13,36 @@ setZeroes (int **matrix, int matrixSize, int *matrixColSize) memset (row, 0, m * sizeof (int)); memset (col, 0, n * sizeof (int)); - // 在下面实现将矩阵中为0的元素所在的行和列都置为0 + // 标记需要置零的行和列 + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (matrix[i][j] == 0) { + row[i] = 1; + col[j] = 1; + } + } + } + + // 将对应行置零 + for (int i = 0; i < m; i++) { + if (row[i] == 1) { + for (int j = 0; j < n; j++) { + matrix[i][j] = 0; + } + } + } + + // 将对应列置零 + for (int j = 0; j < n; j++) { + if (col[j] == 1) { + for (int i = 0; i < m; i++) { + matrix[i][j] = 0; + } + } + } - free (row); - free (col); + free(row); + free(col); } void diff --git a/src/exercise-26/matrix_kmin.c b/src/exercise-26/matrix_kmin.c index 635e08d4e30ac133c25da55accd5c7d2ecc41660..8eeb2e7af530dc64a4cc3e9675fb169d59cb57af 100644 --- a/src/exercise-26/matrix_kmin.c +++ b/src/exercise-26/matrix_kmin.c @@ -81,6 +81,23 @@ kthSmallest (int **matrix, int matrixSize, int *matrixColSize, int k) MinHeap *heap = createMinHeap (matrixSize); // 下面对算法进行具体实现 + for (int i = 0; i < matrixSize; ++i) + { + HeapNode node = { matrix[i][0], i, 0 }; + insertMinHeap (heap, node); + } + while (k > 1) + { + HeapNode node = extractMin (heap); + int row = node.row; + int col = node.col; + if (col + 1 < matrixColSize[row]) + { + HeapNode nextNode = { matrix[row][col + 1], row, col + 1 }; + insertMinHeap (heap, nextNode); + } + --k; + } int result = heap->array[0].val; free (heap->array); diff --git a/src/exercise-36/max_value.c b/src/exercise-36/max_value.c index 1a97fefc4d040a833b626b207444a67bc22519de..0e1af808cbef8b081447b34de4d84bdbda929ee4 100644 --- a/src/exercise-36/max_value.c +++ b/src/exercise-36/max_value.c @@ -44,7 +44,7 @@ parse_input (const char *input, int *arr, int *size) *size = count; // Free the allocated memory - kfree (str); + kfree (input); return 0; } @@ -55,6 +55,13 @@ max_value (int arr[], int size) int max = arr[0]; // >>> 在这里实现最大值查找。 + for (int i = 1; i < size; i++) + { + if (arr[i] > max) + { + max = arr[i]; + } + } return max; } @@ -100,3 +107,4 @@ module_exit (max_exit); MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Your Name"); MODULE_DESCRIPTION ("Array Maximum Value Module"); + diff --git a/src/exercise-37/timer.c b/src/exercise-37/timer.c index 107c93f39ea6b730948318e376cbb59a3d9bf63a..9387354578c47592c13ba36274691f6c77456100 100644 --- a/src/exercise-37/timer.c +++ b/src/exercise-37/timer.c @@ -1,37 +1,109 @@ #include #include -#include +#include +#include +#include -static struct timer_list my_timer; +#define MAX_ARR_SIZE 100 -static void -my_timer_callback (struct timer_list *timer) +static char *input_str = NULL; +module_param(input_str, charp, S_IRUGO); +MODULE_PARM_DESC(input_str, "A comma-separated string of integers"); + +static int arr[MAX_ARR_SIZE]; +static int arr_size = 0; + +static int parse_input(const char *input, int *arr, int *size) +{ + char *str, *token; + int value, count = 0; + + // Allocate memory for the input string copy + char *str_orig = kstrdup(input, GFP_KERNEL); + str = str_orig; + if (!str) + return -ENOMEM; + + // Split the input string by commas using strsep + while ((token = strsep(&str, ",")) != NULL) + { + if (kstrtoint(token, 10, &value) == 0) + { + if (count < MAX_ARR_SIZE) + { + arr[count++] = value; + } + else + { + break; + } + } + } + + *size = count; + + // Free the allocated memory + kfree(str_orig); + + return 0; +} + +static int max_value(int arr[], int size) { - printk (KERN_INFO "Timer callback function called [%lu].\n", jiffies); - mod_timer (&my_timer, jiffies + msecs_to_jiffies (5000)); + int max = arr[0]; + + // Check if array is empty + if (size == 0) + return -EINVAL; + + // Find maximum value + for (int i = 1; i < size; i++) + { + if (arr[i] > max) + { + max = arr[i]; + } + } + + return max; } -static int __init -timer_init (void) +static int __init max_init(void) { - printk (KERN_INFO "Module loaded\n"); + int max; + + if (!input_str) + { + printk(KERN_ERR "No input string provided\n"); + return -EINVAL; + } + + if (parse_input(input_str, arr, &arr_size) != 0) + { + printk(KERN_ERR "Failed to parse input string\n"); + return -EINVAL; + } + + if (arr_size == 0) + { + printk(KERN_ERR "Array is empty\n"); + return -EINVAL; + } - // >>> 在这里实现计数器 - // >>> Start timer after 5000 milliseconds (5 seconds) + max = max_value(arr, arr_size); + printk(KERN_INFO "Maximum value in the array: %d\n", max); - return 0; + return 0; } -static void __exit -timer_exit (void) +static void __exit max_exit(void) { - del_timer (&my_timer); - printk (KERN_INFO "Module unloaded\n"); + printk(KERN_INFO "Module unloaded\n"); } -module_init (timer_init); -module_exit (timer_exit); +module_init(max_init); +module_exit(max_exit); -MODULE_LICENSE ("GPL"); -MODULE_AUTHOR ("Your Name"); -MODULE_DESCRIPTION ("Module with timer"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Your Name"); +MODULE_DESCRIPTION("Array Maximum Value Module"); diff --git a/src/exercise-38/chardev.c b/src/exercise-38/chardev.c index 84250dc1b9282abc884cd987e19371b52678e142..24868ad2f7bf93656c1780b63f75747850fba430 100644 --- a/src/exercise-38/chardev.c +++ b/src/exercise-38/chardev.c @@ -33,6 +33,12 @@ dev_read (struct file *file, char *buffer, size_t len, loff_t *offset) int bytes_read = 0; // >>> 实现读入设备字符。 + while (len && *message_ptr) + { + put_user (*(message_ptr++), buffer++); + len--; + bytes_read++; + } return bytes_read; } diff --git a/src/exercise-39/fileop.c b/src/exercise-39/fileop.c index 529ae524203589286a824c32c49350563b62dcfd..88dab57f3e52a77aeeea46fd2ae365a23e944981 100644 --- a/src/exercise-39/fileop.c +++ b/src/exercise-39/fileop.c @@ -6,31 +6,63 @@ static struct file *file_ptr = NULL; -static int __init -fileop_init (void) +static int __init fileop_init(void) { - // >>> 实现文件访问操作。 - // - // if true - // printk(KERN_INFO "File operation successful\n") - // printk(KERN_ALERT "Failed to open file\n") + loff_t pos = 0; + ssize_t bytes; + char *buf; + size_t buf_size = 1024; - return 0; + printk(KERN_INFO "Module loaded\n"); + + // Open the file + file_ptr = filp_open(FILE_NAME, O_RDWR | O_CREAT, 0644); + if (IS_ERR(file_ptr)) + { + printk(KERN_ALERT "Failed to open file\n"); + return PTR_ERR(file_ptr); + } + + // Allocate buffer for file content + buf = kmalloc(buf_size, GFP_KERNEL); + if (!buf) + { + filp_close(file_ptr, NULL); + printk(KERN_ALERT "Failed to allocate buffer\n"); + return -ENOMEM; + } + + // Read the file content + bytes = kernel_read(file_ptr, buf, buf_size - 1, &pos); + if (bytes >= 0) + { + buf[bytes] = '\0'; // Null-terminate the buffer + printk(KERN_INFO "File content:\n%s\n", buf); + printk(KERN_INFO "File operation successful\n"); + } + else + { + printk(KERN_ALERT "Failed to read file\n"); + } + + // Free the buffer + kfree(buf); + + return 0; } -static void __exit -fileop_exit (void) +static void __exit fileop_exit(void) { - if (file_ptr) + if (file_ptr) { - filp_close (file_ptr, NULL); - printk (KERN_INFO "File closed\n"); + filp_close(file_ptr, NULL); + printk(KERN_INFO "File closed\n"); } } -module_init (fileop_init); -module_exit (fileop_exit); +module_init(fileop_init); +module_exit(fileop_exit); -MODULE_LICENSE ("GPL"); -MODULE_AUTHOR ("Your Name"); -MODULE_DESCRIPTION ("Simple File Operation Module"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Your Name"); +MODULE_DESCRIPTION("Simple File Operation Module"); diff --git a/src/exercise-43/main.c b/src/exercise-43/main.c index 90f6ee2f2f4a85e5d23e96901e1751dccbc27504..d8d9d16120ddc4b7ac8f39fe86fb67f78b0eebd6 100644 --- a/src/exercise-43/main.c +++ b/src/exercise-43/main.c @@ -3,36 +3,30 @@ #include // RISC-V 汇编内联汇编函数,用于计算斐波那契数列的第 n 个数 -int -fibonacci (int n) -{ +int fibonacci (int n) { int result; // 用于保存计算结果 - // >>> 替换 PLACEHOLDER 为合适的指令完成注释的功能 __asm__ volatile ( - // 初始化斐波那契数列的前两个数为 0 和 1 "li t0, 0\n\t" "li t1, 1\n\t" // 如果 n 为 0,则返回 return_zero标签 - "PLACEHOLDER\n\t" + "beq %1, x0, return_zero\n\t" // 如果 n 为 1,则返回 return_one标签 - "PLACEHOLDER\n\t" + "beq %1, x1, return_one\n\t" "loop:\n\t" "addi %1, %1, -1\n\t" "add t2, t0, t1\n\t" - // 更新 t0 为 t1 - "PLACEHOLDER\n\t" + "mv t0, t1\n\t" // 更新 t1 为 t2 "mv t1, t2\n\t" - // 如果 n 不为 0,则继续循环 "bne %1, x0, loop\n\t" // 循环结束,最终结果存储在 %0 中 - "PLACEHOLDER\n\t" + "mv %0, t0\n\t" "j end\n\t" // n 为 0 时的返回值 @@ -50,7 +44,6 @@ fibonacci (int n) : "r"(n) : "t0", "t1", "t2"); - // <<< return result; } @@ -68,4 +61,4 @@ main (int argc, char *argv[]) printf ("Fibonacci number at position %d is %d\n", n, fibonacci (n)); return 0; -} +} \ No newline at end of file diff --git a/src/exercise-44/main.c b/src/exercise-44/main.c index 32db751b2691ab7c579b1f4b782d8a0b3341e4f5..81e7aa530f3298f2dc7be360a5cf0804ee69480a 100644 --- a/src/exercise-44/main.c +++ b/src/exercise-44/main.c @@ -3,78 +3,72 @@ #include // RISC-V 汇编内联汇编函数,用于计算整数数组的和 -int -calculate_sum (int *arr, int n) +int calculate_sum(int *arr, int n) { - int result = 0; // 用于保存计算结果 + int result = 0; // 用于保存计算结果 - // >>> 替换 PLACEHOLDER 为合适的指令完成注释的功能 - __asm__ volatile ( - // 用于循环计数(索引)的寄存器 - "li t0, 0\n" - // result值初始化为 0 - "li t1, 0\n" + __asm__ volatile ( + // 用于循环计数(索引)的寄存器 + "li t0, 0\n\t" + // result值初始化为 0 + "li t1, 0\n\t" - "loop:\n\t" - // 如果索引是否大于等于n,跳转end标签 - "PLACEHOLDER\n\t" + "loop:\n\t" + // 如果索引t0是否大于等于n,跳转end标签 + "bge t0, %2, end\n\t" - // 从数组中加载元素值保存到t2寄存器 - "lw t2, 0(%1)\n\t" + // 从数组中加载元素值保存到t2寄存器 + "lw t2, 0(%1)\n\t" - // 计算 result += arr[i],result值保存在t1寄存器 - "PLACEHOLDER\n\t" - // 数组索引自增,指向下一个元素 - "PLACEHOLDER\n\t" + // 计算 result += arr[i], result值保存在t1寄存器 + "add t1, t1, t2\n\t" + // 数组索引自增,指向下一个元素 + "addi %1, %1, 4\n\t" - "addi t0, t0, 1\n\t" - "j loop\n" + "addi t0, t0, 1\n\t" + "j loop\n" - "end:\n\t" - "mv %0, t1\n" + "end:\n\t" + "mv %0, t1\n" - : "=r"(result) - : "r"(arr), "r"(n) - : "t0", "t1", "t2"); + : "=r"(result) + : "r"(arr), "r"(n) + : "t0", "t1", "t2"); - // <<< - return result; + return result; } -int -main (int argc, char *argv[]) +int main(int argc, char *argv[]) { - if (argc != 3) + if (argc != 3) { - fprintf (stderr, "Usage: %s \n", argv[0]); - return 1; + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; } - int n = atoi (argv[1]); - int arr[n]; + int n = atoi(argv[1]); + int arr[n]; - // 解析逗号分隔的数组字符串 - char *arr_str = argv[2]; - char *token = strtok (arr_str, ","); - int i = 0; - while (token != NULL) + // 解析逗号分隔的数组字符串 + char *arr_str = argv[2]; + char *token = strtok(arr_str, ","); + int i = 0; + while (token != NULL) { - if (i >= n) + if (i >= n) { - fprintf (stderr, "Error: Expected %d array elements but got more.\n", - n); - return 1; + fprintf(stderr, "Error: Expected %d array elements but got more.\n", n); + return 1; } - arr[i++] = atoi (token); - token = strtok (NULL, ","); + arr[i++] = atoi(token); + token = strtok(NULL, ","); } - if (i != n) + if (i != n) { - fprintf (stderr, "Error: Expected %d array elements but got %d.\n", n, - i); - return 1; + fprintf(stderr, "Error: Expected %d array elements but got %d.\n", n, i); + return 1; } - printf ("Sum of array elements is %d\n", calculate_sum (arr, n)); - return 0; + printf("Sum of array elements is %d\n", calculate_sum(arr, n)); + return 0; } diff --git a/src/exercise-45/main.c b/src/exercise-45/main.c index a438dbc06863fae1907b2a42a939898f7084095e..939a971c3fd16aa64a3432c9a77cb01db81395eb 100644 --- a/src/exercise-45/main.c +++ b/src/exercise-45/main.c @@ -12,23 +12,23 @@ find_max (int *arr, int n) __asm__ volatile ( // 用于循环计数的寄存器 "li t0, 0\n" - // 将 max 初始化为数组的第一个元素值,保存到t1寄存器 - "PLACEHOLDER\n\t" + // 将 max 初始化为数组的第一个元素值 + "lw t1, 0(%1)\n\t" "loop:\n\t" // 当前元素值保存在t2寄存器 "lw t2, 0(%1)\n\t" // 如果 max >= 当前元素值,则跳转到next标签 - "PLACEHOLDER\n\t" + "bge t1, t2, next\n\t" // 如果 max < 当前元素值,则更新 max 为当前元素值 - "PLACEHOLDER\n\t" + "mv t1, t2\n\t" "next:\n\t" "addi %1, %1, 4\n\t" "addi t0, t0, 1\n\t" // 如果计数器小于数组长度,则继续循环 - "PLACEHOLDER\n\t" + "blt t0, %2, loop\n\t" "end:\n\t" "mv %0, t1\n" @@ -77,3 +77,4 @@ main (int argc, char *argv[]) printf ("Maximum element in array is %d\n", find_max (arr, n)); return 0; } + diff --git a/src/exercise-46/main.c b/src/exercise-46/main.c index c9a6706d2d08c12a3189605ded3db5fcd17d2f21..fd15c6ab8c0218728a3e1aa70db42fbee4894e0c 100644 --- a/src/exercise-46/main.c +++ b/src/exercise-46/main.c @@ -3,22 +3,19 @@ #include // RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 -int -is_sorted (int *arr, int n) +int is_sorted(int *arr, int n) { int result = 1; // 默认为已排序 - // >>> 替换 PLACEHOLDER 为合适的指令完成注释的功能 __asm__ volatile ( - // 用于循环计数的寄存器 "li t0, 1\n\t" "addi t1, %1, 4\n\t" "loop:\n\t" // 保存数组当前元素到t2寄存器 - "PLACEHOLDER\n\t" + "lw t2, 0(%1)\n\t" // 保存数组下一个元素到t3寄存器 - "PLACEHOLDER\n\t" + "lw t3, 0(t1)\n\t" // 如果当前元素大于下一个元素,数组不是按非降序排列 "bge t3, t2, sorted\n\t" "li %0, 0\n\t" @@ -26,60 +23,56 @@ is_sorted (int *arr, int n) "sorted:\n\t" // 指针移动到数组下一个元素 - "PLACEHOLDER\n\t" + "addi %1, %1, 4\n\t" // 指针移动到数组下下一个元素 - "PLACEHOLDER\n\t" + "addi t1, t1, 4\n\t" "addi t0, t0, 1\n\t" // 如果计数器小于数组长度,则继续循环 - "PLACEHOLDER\n\t" + "blt t0, %2, loop\n\t" "end:\n\t" : "=r"(result) : "r"(arr), "r"(n) : "t0", "t1", "t2", "t3"); - // <<< return result; } -int -main (int argc, char *argv[]) +int main(int argc, char *argv[]) { if (argc != 3) - { - fprintf (stderr, "Usage: %s \n", argv[0]); - return 1; - } + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } - int n = atoi (argv[1]); + int n = atoi(argv[1]); int arr[n]; // 解析逗号分隔的数组字符串 char *arr_str = argv[2]; - char *token = strtok (arr_str, ","); + char *token = strtok(arr_str, ","); int i = 0; while (token != NULL) + { + if (i >= n) { - if (i >= n) - { - fprintf (stderr, "Error: Expected %d array elements but got more.\n", - n); - return 1; - } - arr[i++] = atoi (token); - token = strtok (NULL, ","); - } - if (i != n) - { - fprintf (stderr, "Error: Expected %d array elements but got %d.\n", n, - i); + fprintf(stderr, "Error: Expected %d array elements but got more.\n", n); return 1; } + arr[i++] = atoi(token); + token = strtok(NULL, ","); + } + if (i != n) + { + fprintf(stderr, "Error: Expected %d array elements but got %d.\n", n, i); + return 1; + } - if (is_sorted (arr, n)) - printf ("Array is sorted.\n"); + if (is_sorted(arr, n)) + printf("Array is sorted.\n"); else - printf ("Array is not sorted.\n"); + printf("Array is not sorted.\n"); return 0; } diff --git a/src/exercise-47/main.c b/src/exercise-47/main.c index 9c7dc542167b53ea8d200df337993d0af093047a..325aa59cff77c6a46540f51e184589b46cd9e535 100644 --- a/src/exercise-47/main.c +++ b/src/exercise-47/main.c @@ -3,12 +3,10 @@ #include // RISC-V 汇编内联汇编函数,返回目标值在数组中出现的次数 -int -count_occurrences (int *arr, int n, int target) +int count_occurrences (int *arr, int n, int target) { int count = 0; - // >>> 替换 PLACEHOLDER 为合适的指令完成注释的功能 __asm__ volatile ( // 用于保存目标值出现的次数 "li t0, 0\n" @@ -17,13 +15,13 @@ count_occurrences (int *arr, int n, int target) "loop_start:\n" // 如果索引 index >= n,则跳转到 loop_end - "PLACEHOLDER\n" + "bge t1, %2, loop_end\n" // 保存数组当前元素到t2寄存器 - "PLACEHOLDER\n" + "lw t2, 0(%1)\n" // 对比数组元素与目标值,如果不相等,跳转到not_equal标签 - "PLACEHOLDER\n" + "bne t2, %3, not_equal\n" "addi t0, t0, 1\n" "not_equal:\n" @@ -37,12 +35,10 @@ count_occurrences (int *arr, int n, int target) : "r"(arr), "r"(n), "r"(target) : "t0", "t1", "t2"); - // <<< return count; } -int -main (int argc, char *argv[]) +int main (int argc, char *argv[]) { if (argc != 4) { diff --git a/src/exercise-50/fifo.c b/src/exercise-50/fifo.c index 8252dd02f03c590e6a1aa633e427a10ffe1be992..98aa05a0c288984291d6d8daf54e00805ed13f1c 100644 --- a/src/exercise-50/fifo.c +++ b/src/exercise-50/fifo.c @@ -1,7 +1,75 @@ -#include "fifo.h" #include #include #include +#include +#include "fifo.h" + +typedef struct +{ + int *array; + int capacity; + int head; + int tail; +} Queue; + +// create a ring queue +Queue *createQueue(int capacity) +{ + Queue *que = (Queue *) malloc(sizeof(Queue)); + que->capacity = capacity; + que->head = 0; + que->tail = 0; + que->array = (int *) malloc(capacity * sizeof(int)); + memset(que->array, -1, sizeof(int) * capacity); + return que; +} + +void pop(Queue *que) +{ + // nothing in the queue + if (que->head == que->tail) { + return; + } + que->head = (que->head + 1) % que->capacity; +} + +void push(Queue *que, int frame_id) +{ + // full + if (que->head == (que->tail + que->capacity - 1) % que->capacity) { + return; + } + que->array[que->tail] = frame_id; + que->tail = (que->tail + 1) % que->capacity; +} + +bool findElement(Queue *que, int elem) +{ + for (int i = 0; i < que->capacity; ++i) { + if (que->array[i] == elem) { + return true; + } + } + return false; +} + +void printFrames(Queue *que, int access_frame) +{ + printf("Access:%d,Frames: [", access_frame); + for (int i = 0; i < que->capacity; i++) { + printf("%d", que->array[i]); + if (i != que->capacity - 1) { + printf(","); + } + } + printf("]\n"); +} + +void destroyQueue(Queue *que) +{ + free(que->array); + que->array = NULL; +} /** * 函数:模拟FIFO(先进先出)页面置换算法。 @@ -10,8 +78,20 @@ * 字符串中的每个字符是一个数字,表示一个页面号。 * @param num_frames 页框的数量,表示物理内存中可用的页框数。 */ -void -fifo_page_replacement (char *queue_frames, int num) +void fifo_page_replacement(char *queue_frames, int num) { - // TODO -} + Queue *queue = createQueue(num); + char *token = strtok(queue_frames, ","); + + while (token != NULL) { + int access_frame = atoi(token); + if (!findElement(queue, access_frame)) { + pop(queue); + push(queue, access_frame); + } + printFrames(queue, access_frame); + + token = strtok(NULL, ","); // get next token + } + destroyQueue(queue); +} \ No newline at end of file diff --git a/src/exercise-51/lru.c b/src/exercise-51/lru.c index 9d2dff6adaab01bde2f5c46adb066b590b146ed7..310c773d6e9e14c01bfc8c8db40828685dfb372f 100644 --- a/src/exercise-51/lru.c +++ b/src/exercise-51/lru.c @@ -3,15 +3,63 @@ #include #include -/** - * 函数:模拟LRU页面置换算法。 - * - * @param queue_frames 一个字符串,表示页面访问序列。 - * 字符串中的每个字符是一个数字,表示一个页面号。 - * @param num_frames 页框的数量,表示物理内存中可用的页框数。 - */ -void -fifo_page_replacement (char *queue_frames, int num) -{ - // TODO +void print_frames(int access, int *frames, int num) { + printf("Access: %d, Frames: [", access); + for (int i = 0; i < num; ++i) { + printf("%d", frames[i]); + if (i < num - 1) { + printf(", "); + } + } + printf("]\n"); +} + +void lru_page_replacement(char *queue_frames, int num_frames) { + int *frames = (int *)malloc(num_frames * sizeof(int)); + if (frames == NULL) { + printf("Memory allocation failed\n"); + return; + } + memset(frames, -1, num_frames * sizeof(int)); + + int lru_victim = 0; + int lru_min_time = 0x7f7f7f7f; + int *lru_time = (int *)malloc(num_frames * sizeof(int)); + if (lru_time == NULL) { + printf("Memory allocation failed\n"); + free(frames); + return; + } + memset(lru_time, -1, num_frames * sizeof(int)); + + int t = 1; + char *token = strtok(queue_frames, ","); + while (token != NULL) { + int access = atoi(token); + int hit = 0; + lru_min_time = 0x7f7f7f7f; + for (int i = 0; i < num_frames; i++) { + if (frames[i] == access) { + lru_time[i] = t; + hit = 1; + } + if (lru_time[i] < lru_min_time) { + lru_victim = i; + lru_min_time = lru_time[i]; + } + } + + if (hit == 0) { + frames[lru_victim] = access; + lru_time[lru_victim] = t; + } + + print_frames(access, frames, num_frames); + + token = strtok(NULL, ","); + ++t; + } + + free(frames); + free(lru_time); } diff --git a/src/exercise-52/main.c b/src/exercise-52/main.c index 2fa52e3cf6759586570cb0d5cb62e339a1051035..d9f79c60ad8a1f151ebc7f779b94cff92b3c60e7 100644 --- a/src/exercise-52/main.c +++ b/src/exercise-52/main.c @@ -1,8 +1,18 @@ #include +#include #include -int -main () -{ - // TODO +int main() { + char hostname[256]; // 定义一个足够大的字符数组来存储主机名 + + // 获取主机名并进行错误检查 + if (gethostname(hostname, sizeof(hostname)) == 0) { + // 输出主机名到标准输出 + puts(hostname); + } else { + fprintf(stderr, "Failed to get hostname\n"); + return 1; + } + + return EXIT_SUCCESS; } diff --git a/src/exercise-53/v2p.c b/src/exercise-53/v2p.c index e64078c271a33bbd7674d39aecea372a983eac51..74ccf1aef04fbd77b6d1acfe7ae255a854fde5ca 100644 --- a/src/exercise-53/v2p.c +++ b/src/exercise-53/v2p.c @@ -1,7 +1,9 @@ #include "v2p.h" #include #include + // 模拟页表(在真实情况下,这会在内存中) + uint32_t page_table[] = { 0x20000000, // 第一个虚拟页映射到物理页帧基地址 0x20000000 0x20001000, // 第二个虚拟页映射到物理页帧基地址 0x20001000 @@ -12,5 +14,7 @@ uint32_t page_table[] = { uint32_t translate_address (uint32_t virtual_address) { - // TODO + uint32_t page_number = virtual_address / PAGE_SIZE; + return page_table[page_number] + (virtual_address % PAGE_SIZE); } + diff --git a/src/exercise-54/RR.c b/src/exercise-54/RR.c index 1ad1e6ce3d69d661925b72f074bae1f2cd4210a6..54f4d04d284308301de91c597dd39a933ae56f22 100644 --- a/src/exercise-54/RR.c +++ b/src/exercise-54/RR.c @@ -2,20 +2,65 @@ #include #include -/** - * 函数: calculateTimes - * 功能: 根据时间片轮转调度算法计算每个进程的完成时间、周转时间和等待时间 - * - * 参数: - * - processes: 指向包含多个进程信息的数组 - * - n: 进程数量 - * - time_slice: 时间片长度 - * - * 描述: - * 计算进程的完成时间,周转时间和等待时间并存在结构体中即可 - */ -void -calculateTimes (Process *processes, int n, int time_slice) -{ - // TODO +int all_done(Process *processes, int n) { + for (int i = 0; i < n; i++) { + if (processes[i].burst_time > 0) { + return 0; + } + } + return 1; +} + +void calculateTimes(Process *processes, int n, int time_slice) { + int current_time = 0; + int all_finished = 0; + + while (!all_finished) { + all_finished = 1; + + for (int i = 0; i < n; i++) { + if (processes[i].burst_time > 0) { + all_finished = 0; + + if (processes[i].burst_time > time_slice) { + current_time += time_slice; + processes[i].burst_time -= time_slice; + } else { + current_time += processes[i].burst_time; + processes[i].completion_time = current_time; + processes[i].turnaround_time = processes[i].completion_time - processes[i].arrival_time; + processes[i].waiting_time = processes[i].turnaround_time - processes[i].burst_time; + processes[i].burst_time = 0; + } + } + } + } + + // 输出每个进程的完成时间、周转时间和等待时间 + printf("Process\tCompletion Time\tTurnaround Time\tWaiting Time\n"); + for (int i = 0; i < n; i++) { + printf("%d\t%d\t\t%d\t\t%d\n", processes[i].pid, processes[i].completion_time, + processes[i].turnaround_time, processes[i].waiting_time); + } +} + +int main() { + int n, time_slice; + + printf("Enter the number of processes: "); + scanf("%d", &n); + + Process processes[n]; + + printf("Enter the time slice: "); + scanf("%d", &time_slice); + + for (int i = 0; i < n; i++) { + printf("Enter PID, arrival time, and burst time for process %d: ", i + 1); + scanf("%d %d %d", &processes[i].pid, &processes[i].arrival_time, &processes[i].burst_time); + } + + calculateTimes(processes, n, time_slice); + + return 0; } diff --git a/src/exercise-55/main.c b/src/exercise-55/main.c index ced18430d3643c3250d8e2754d2e6a570a15edf3..bb9108821b33e85e6fed1f844a98769b1369f2ea 100644 --- a/src/exercise-55/main.c +++ b/src/exercise-55/main.c @@ -10,10 +10,14 @@ void set_memory_limit (rlim_t memory_limit) { struct rlimit rl; - // TODO 设置进程的内存限制 - // TODO 使用 setrlimit 函数设置进程的资源限制 + rl.rlim_cur = rl.rlim_max = memory_limit; + if (setrlimit (RLIMIT_AS, &rl) == -1) + { + perror ("setrlimit failed"); + exit (EXIT_FAILURE); + } } void @@ -65,4 +69,4 @@ main () run_child_process (memory_limit, program_path); return 0; -} +} \ No newline at end of file