From e41bd0767b95f6bea0b7b439ca9f1390e9dfffa3 Mon Sep 17 00:00:00 2001 From: Ruby_Facetious_a005 <1621059562@qq.com> Date: Sun, 16 Jun 2024 05:12:36 +0000 Subject: [PATCH 1/4] test Signed-off-by: Ruby_Facetious_a005 <1621059562@qq.com> --- src/exercise-22/matrix_mul.c | 20 ++++++- src/exercise-23/convolution.c | 16 +++++ src/exercise-24/matrix_trans.c | 12 +++- src/exercise-25/matrix_zero.c | 32 +++++++++- src/exercise-26/matrix_kmin.c | 17 ++++++ src/exercise-36/max_value.c | 11 +++- src/exercise-37/timer.c | 105 ++++++++++++++++++++++++++++----- src/exercise-38/chardev.c | 6 ++ src/exercise-39/fileop.c | 54 +++++++++++++++-- src/exercise-43/main.c | 19 ++---- src/exercise-44/main.c | 96 ++++++++++++++---------------- src/exercise-45/main.c | 11 ++-- src/exercise-46/main.c | 13 +--- src/exercise-47/main.c | 67 ++++++++++----------- src/exercise-50/fifo.c | 90 ++++++++++++++++++++++++++-- src/exercise-51/lru.c | 63 ++++++++++++++++---- src/exercise-52/main.c | 18 ++++-- src/exercise-53/v2p.c | 12 +++- src/exercise-54/RR.c | 58 ++++++++++++++---- src/exercise-55/main.c | 10 +++- 20 files changed, 551 insertions(+), 179 deletions(-) diff --git a/src/exercise-22/matrix_mul.c b/src/exercise-22/matrix_mul.c index 0752395..e5c49ce 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 f86ec9e..863bb61 100644 --- a/src/exercise-23/convolution.c +++ b/src/exercise-23/convolution.c @@ -16,4 +16,20 @@ convolution2D (int input[5][5], int kernel[3][3], int output[3][3], } // 在下面通过多重循环实现卷积运算 + // 计算卷积 + for (i = 0; i < inputSize - kernelSize + 1; i++) + { + for (j = 0; j < inputSize - kernelSize + 1; j++) + { + // 对于每个输出元素,应用卷积核 + for (m = 0; m < kernelSize; m++) + { + for (n = 0; n < kernelSize; n++) + { + output[i][j] += input[i + m][j + n] * kernel[m][n]; + } + } + } + } } +} \ No newline at end of file diff --git a/src/exercise-24/matrix_trans.c b/src/exercise-24/matrix_trans.c index 9cdf524..5f78e6d 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 ba1e8c2..2dade1c 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 635e08d..8eeb2e7 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 1a97fef..824dffc 100644 --- a/src/exercise-36/max_value.c +++ b/src/exercise-36/max_value.c @@ -1,4 +1,4 @@ -#include +include #include #include #include @@ -55,10 +55,18 @@ max_value (int arr[], int size) int max = arr[0]; // >>> 在这里实现最大值查找。 + for (i = 1; i < size; i++) + { + if (arr[i] > max) + { + max = arr[i]; + } + } return max; } + static int __init max_init (void) { @@ -100,3 +108,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 107c93f..1869651 100644 --- a/src/exercise-37/timer.c +++ b/src/exercise-37/timer.c @@ -1,37 +1,110 @@ -#include +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) { - printk (KERN_INFO "Timer callback function called [%lu].\n", jiffies); - mod_timer (&my_timer, jiffies + msecs_to_jiffies (5000)); + char *str, *token; + char *saveptr; + int value, count = 0; + + // Allocate memory for the input string copy + str = kstrdup (input, GFP_KERNEL); + 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); + + return 0; } +static int +max_value (int arr[], int size) +{ + int max = arr[0]; + + // >>> 在这里实现最大值查找。 + for (i = 1; i < size; i++) + { + if (arr[i] > max) + { + max = arr[i]; + } + } + + return max; +} + + static int __init -timer_init (void) +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; } static void __exit -timer_exit (void) +max_exit (void) { - del_timer (&my_timer); 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_DESCRIPTION ("Array Maximum Value Module"); diff --git a/src/exercise-38/chardev.c b/src/exercise-38/chardev.c index 84250dc..24868ad 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 529ae52..c8a787d 100644 --- a/src/exercise-39/fileop.c +++ b/src/exercise-39/fileop.c @@ -9,11 +9,55 @@ static struct file *file_ptr = NULL; static int __init fileop_init (void) { - // >>> 实现文件访问操作。 - // - // if true - // printk(KERN_INFO "File operation successful\n") - // printk(KERN_ALERT "Failed to open file\n") + mm_segment_t old_fs; + loff_t pos = 0; + ssize_t bytes; + char *buf; + size_t buf_size = 1024; + + printk(KERN_INFO "Module loaded\n"); + + // Set the address limit to kernel space + old_fs = get_fs(); + set_fs(KERNEL_DS); + + // Open the file + file_ptr = filp_open(FILE_NAME, O_RDONLY, 0); + if (IS_ERR(file_ptr)) + { + printk(KERN_ALERT "Failed to open file\n"); + set_fs(old_fs); + 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"); + set_fs(old_fs); + 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); + + // Restore the address limit + set_fs(old_fs); return 0; } diff --git a/src/exercise-43/main.c b/src/exercise-43/main.c index 90f6ee2..d8d9d16 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 32db751..81e7aa5 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 a438dbc..939a971 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 c9a6706..fc8673e 100644 --- a/src/exercise-46/main.c +++ b/src/exercise-46/main.c @@ -3,35 +3,27 @@ #include // RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 -int -is_sorted (int *arr, int n) +// RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 +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" - // 保存数组下一个元素到t3寄存器 "PLACEHOLDER\n\t" - // 如果当前元素大于下一个元素,数组不是按非降序排列 "bge t3, t2, sorted\n\t" "li %0, 0\n\t" "j end\n\t" "sorted:\n\t" - // 指针移动到数组下一个元素 "PLACEHOLDER\n\t" - // 指针移动到数组下下一个元素 "PLACEHOLDER\n\t" "addi t0, t0, 1\n\t" - // 如果计数器小于数组长度,则继续循环 "PLACEHOLDER\n\t" "end:\n\t" @@ -39,7 +31,6 @@ is_sorted (int *arr, int n) : "r"(arr), "r"(n) : "t0", "t1", "t2", "t3"); - // <<< return result; } diff --git a/src/exercise-47/main.c b/src/exercise-47/main.c index 9c7dc54..81e1ccd 100644 --- a/src/exercise-47/main.c +++ b/src/exercise-47/main.c @@ -2,51 +2,53 @@ #include #include -// RISC-V 汇编内联汇编函数,返回目标值在数组中出现的次数 +// RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 int -count_occurrences (int *arr, int n, int target) +is_sorted (int *arr, int n) { - int count = 0; + int result = 1; // 默认为已排序 // >>> 替换 PLACEHOLDER 为合适的指令完成注释的功能 __asm__ volatile ( - // 用于保存目标值出现的次数 - "li t0, 0\n" - // 用于循环计数(索引)的寄存器 - "li t1, 0\n" - - "loop_start:\n" - // 如果索引 index >= n,则跳转到 loop_end - "PLACEHOLDER\n" + // 用于循环计数的寄存器 + "li t0, 1\n\t" + "addi t1, %1, 4\n\t" + "loop:\n\t" // 保存数组当前元素到t2寄存器 - "PLACEHOLDER\n" + "lw t2, 0(%1)\n\t" + // 保存数组下一个元素到t3寄存器 + "lw t3, 0(t1)\n\t" + // 如果当前元素大于下一个元素,数组不是按非降序排列 + "bge t3, t2, sorted\n\t" + "li %0, 0\n\t" + "j end\n\t" - // 对比数组元素与目标值,如果不相等,跳转到not_equal标签 - "PLACEHOLDER\n" - "addi t0, t0, 1\n" + "sorted:\n\t" + // 指针移动到数组下一个元素 + "addi %1, %1, 4\n\t" + // 指针移动到数组下下一个元素 + "addi t1, t1, 4\n\t" - "not_equal:\n" - "addi t1, t1, 1\n" - "addi %1, %1, 4\n" - "j loop_start\n" + "addi t0, t0, 1\n\t" + // 如果计数器小于数组长度,则继续循环 + "blt t0, %2, loop\n\t" - "loop_end:\n" - "mv %0, t0\n" - : "=r"(count) - : "r"(arr), "r"(n), "r"(target) - : "t0", "t1", "t2"); + "end:\n\t" + : "=r"(result) + : "r"(arr), "r"(n) + : "t0", "t1", "t2", "t3"); // <<< - return count; + return result; } int main (int argc, char *argv[]) { - if (argc != 4) + if (argc != 3) { - fprintf (stderr, "Usage: %s \n", argv[0]); + fprintf (stderr, "Usage: %s \n", argv[0]); return 1; } @@ -75,10 +77,9 @@ main (int argc, char *argv[]) return 1; } - int target = atoi (argv[3]); - - int occurrences = count_occurrences (arr, n, target); - printf ("Occurrences of target:%d\n", occurrences); - + if (is_sorted (arr, n)) + printf ("Array is sorted.\n"); + else + printf ("Array is not sorted.\n"); return 0; -} +} \ No newline at end of file diff --git a/src/exercise-50/fifo.c b/src/exercise-50/fifo.c index 8252dd0..98aa05a 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 9d2dff6..6e07ac2 100644 --- a/src/exercise-51/lru.c +++ b/src/exercise-51/lru.c @@ -3,15 +3,56 @@ #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"); +} + +// LRU页面置换算法 +void lru_page_replacement(char *queue_frames, int num_frames) { + int *frames = (int *)malloc(num_frames * sizeof(int)); // 分配页框数组 + memset(frames, -1, num_frames * sizeof(int)); // 初始化页框数组为 -1 + + int lru_victim = 0; // 最近最少使用的页面索引 + int lru_min_time = 0; // 最近最少使用的页面的时间 + int *lru_time = (int *)malloc(num_frames * sizeof(int)); // 分配时间数组 + memset(lru_time, -1, num_frames * sizeof(int)); // 初始化时间数组为 -1 + + int t = 1; // 时间计数器 + char *token = strtok(queue_frames, ","); // 解析页面访问序列 + while (token != NULL) { + int access = atoi(token); + int hit = 0; + lru_min_time = t + 1; + 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 2fa52e3..d9f79c6 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 e64078c..2019e63 100644 --- a/src/exercise-53/v2p.c +++ b/src/exercise-53/v2p.c @@ -1,6 +1,7 @@ #include "v2p.h" #include #include + // 模拟页表(在真实情况下,这会在内存中) uint32_t page_table[] = { 0x20000000, // 第一个虚拟页映射到物理页帧基地址 0x20000000 @@ -9,8 +10,17 @@ uint32_t page_table[] = { 0x20003000 // 第四个虚拟页映射到物理页帧基地址 0x20003000 }; +#define PAGE_SIZE 0x1000 // 假设每个页大小为4KB,即2^12 + uint32_t translate_address (uint32_t virtual_address) { - // TODO + // 获取虚拟页号 + uint32_t page_num = virtual_address / PAGE_SIZE; + + // 获取页内偏移量 + uint32_t offset = virtual_address % PAGE_SIZE; + + // 返回物理地址 + return page_table[page_num] + offset; } diff --git a/src/exercise-54/RR.c b/src/exercise-54/RR.c index 1ad1e6c..f2896a7 100644 --- a/src/exercise-54/RR.c +++ b/src/exercise-54/RR.c @@ -2,20 +2,52 @@ #include #include -/** - * 函数: calculateTimes - * 功能: 根据时间片轮转调度算法计算每个进程的完成时间、周转时间和等待时间 - * - * 参数: - * - processes: 指向包含多个进程信息的数组 - * - n: 进程数量 - * - time_slice: 时间片长度 - * - * 描述: - * 计算进程的完成时间,周转时间和等待时间并存在结构体中即可 - */ void calculateTimes (Process *processes, int n, int time_slice) { - // TODO + int remaining_time[n]; // 用于跟踪每个进程的剩余执行时间 + + // 初始化剩余执行时间和其他计算结果为0 + for (int i = 0; i < n; i++) { + remaining_time[i] = processes[i].burst_time; + processes[i].completion_time = 0; + processes[i].turnaround_time = 0; + processes[i].waiting_time = 0; + } + + int current_time = 0; // 当前时间 + + // 循环执行调度 + while (1) { + int all_finished = 1; // 所有进程是否完成的标志 + + for (int i = 0; i < n; i++) { + if (remaining_time[i] > 0) { + all_finished = 0; // 还有进程未完成 + + if (remaining_time[i] > time_slice) { + // 执行一个时间片的工作量 + current_time += time_slice; + remaining_time[i] -= time_slice; + } else { + // 执行剩余的工作量 + current_time += remaining_time[i]; + 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; + remaining_time[i] = 0; // 进程完成 + } + } + } + + if (all_finished) // 所有进程都已经完成 + break; + } + + // 输出每个进程的完成时间、周转时间和等待时间 + 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); + } } diff --git a/src/exercise-55/main.c b/src/exercise-55/main.c index ced1843..bb91088 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 -- Gitee From 593337a376aff8bf8879f1f574825cb9675ccbbd Mon Sep 17 00:00:00 2001 From: Ruby_Facetious_a005 <1621059562@qq.com> Date: Sun, 16 Jun 2024 05:41:41 +0000 Subject: [PATCH 2/4] test Signed-off-by: Ruby_Facetious_a005 <1621059562@qq.com> --- src/exercise-23/convolution.c | 6 +- src/exercise-36/max_value.c | 7 +-- src/exercise-37/timer.c | 19 +++---- src/exercise-39/fileop.c | 86 +++++++++++++---------------- src/exercise-46/main.c | 62 +++++++++++---------- src/exercise-47/main.c | 73 ++++++++++++------------- src/exercise-51/lru.c | 5 +- src/exercise-53/v2p.c | 4 +- src/exercise-54/RR.c | 100 ++++++++++++++++++++-------------- 9 files changed, 182 insertions(+), 180 deletions(-) diff --git a/src/exercise-23/convolution.c b/src/exercise-23/convolution.c index 863bb61..9366a44 100644 --- a/src/exercise-23/convolution.c +++ b/src/exercise-23/convolution.c @@ -7,6 +7,7 @@ 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++) @@ -15,8 +16,7 @@ convolution2D (int input[5][5], int kernel[3][3], int output[3][3], } } - // 在下面通过多重循环实现卷积运算 - // 计算卷积 + // 计算卷积 for (i = 0; i < inputSize - kernelSize + 1; i++) { for (j = 0; j < inputSize - kernelSize + 1; j++) @@ -32,4 +32,4 @@ convolution2D (int input[5][5], int kernel[3][3], int output[3][3], } } } -} \ No newline at end of file + diff --git a/src/exercise-36/max_value.c b/src/exercise-36/max_value.c index 824dffc..0e1af80 100644 --- a/src/exercise-36/max_value.c +++ b/src/exercise-36/max_value.c @@ -1,4 +1,4 @@ -include +#include #include #include #include @@ -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,7 +55,7 @@ max_value (int arr[], int size) int max = arr[0]; // >>> 在这里实现最大值查找。 - for (i = 1; i < size; i++) + for (int i = 1; i < size; i++) { if (arr[i] > max) { @@ -66,7 +66,6 @@ max_value (int arr[], int size) return max; } - static int __init max_init (void) { diff --git a/src/exercise-37/timer.c b/src/exercise-37/timer.c index 1869651..224b467 100644 --- a/src/exercise-37/timer.c +++ b/src/exercise-37/timer.c @@ -1,4 +1,4 @@ -include +#include #include #include #include @@ -17,11 +17,11 @@ static int parse_input (const char *input, int *arr, int *size) { char *str, *token; - char *saveptr; int value, count = 0; // Allocate memory for the input string copy - str = kstrdup (input, GFP_KERNEL); + char *str_orig = kstrdup (input, GFP_KERNEL); + str = str_orig; if (!str) return -ENOMEM; @@ -44,7 +44,7 @@ parse_input (const char *input, int *arr, int *size) *size = count; // Free the allocated memory - kfree (str); + kfree (str_orig); return 0; } @@ -55,18 +55,15 @@ max_value (int arr[], int size) int max = arr[0]; // >>> 在这里实现最大值查找。 - for (i = 1; i < size; i++) - { - if (arr[i] > max) - { - max = arr[i]; - } + for (int i = 1; i < size; i++) { + if (arr[i] > max) { + max = arr[i]; } + } return max; } - static int __init max_init (void) { diff --git a/src/exercise-39/fileop.c b/src/exercise-39/fileop.c index c8a787d..f616d63 100644 --- a/src/exercise-39/fileop.c +++ b/src/exercise-39/fileop.c @@ -6,75 +6,63 @@ static struct file *file_ptr = NULL; -static int __init -fileop_init (void) +static int __init fileop_init(void) { - mm_segment_t old_fs; - loff_t pos = 0; - ssize_t bytes; - char *buf; - size_t buf_size = 1024; + loff_t pos = 0; + ssize_t bytes; + char *buf; + size_t buf_size = 1024; - printk(KERN_INFO "Module loaded\n"); + printk(KERN_INFO "Module loaded\n"); - // Set the address limit to kernel space - old_fs = get_fs(); - set_fs(KERNEL_DS); - - // Open the file - file_ptr = filp_open(FILE_NAME, O_RDONLY, 0); - if (IS_ERR(file_ptr)) + // Open the file + file_ptr = filp_open(FILE_NAME, O_RDONLY, 0); + if (IS_ERR(file_ptr)) { - printk(KERN_ALERT "Failed to open file\n"); - set_fs(old_fs); - return PTR_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) + // 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"); - set_fs(old_fs); - return -ENOMEM; + 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) + // 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"); + buf[bytes] = '\0'; // Null-terminate the buffer + printk(KERN_INFO "File content:\n%s\n", buf); + printk(KERN_INFO "File operation successful\n"); } - else + else { - printk(KERN_ALERT "Failed to read file\n"); + printk(KERN_ALERT "Failed to read file\n"); } - // Free the buffer - kfree(buf); - - // Restore the address limit - set_fs(old_fs); + // Free the buffer + kfree(buf); - return 0; + 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-46/main.c b/src/exercise-46/main.c index fc8673e..fd15c6a 100644 --- a/src/exercise-46/main.c +++ b/src/exercise-46/main.c @@ -2,7 +2,6 @@ #include #include -// RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 // RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 int is_sorted(int *arr, int n) { @@ -13,18 +12,24 @@ int is_sorted(int *arr, int n) "addi t1, %1, 4\n\t" "loop:\n\t" - "PLACEHOLDER\n\t" - "PLACEHOLDER\n\t" + // 保存数组当前元素到t2寄存器 + "lw t2, 0(%1)\n\t" + // 保存数组下一个元素到t3寄存器 + "lw t3, 0(t1)\n\t" + // 如果当前元素大于下一个元素,数组不是按非降序排列 "bge t3, t2, sorted\n\t" "li %0, 0\n\t" "j end\n\t" "sorted:\n\t" - "PLACEHOLDER\n\t" - "PLACEHOLDER\n\t" + // 指针移动到数组下一个元素 + "addi %1, %1, 4\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) @@ -34,43 +39,40 @@ int is_sorted(int *arr, int n) 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 81e1ccd..325aa59 100644 --- a/src/exercise-47/main.c +++ b/src/exercise-47/main.c @@ -2,53 +2,47 @@ #include #include -// RISC-V 汇编内联汇编函数,用于检查数组是否按非降序排列 -int -is_sorted (int *arr, int n) +// RISC-V 汇编内联汇编函数,返回目标值在数组中出现的次数 +int count_occurrences (int *arr, int n, int target) { - int result = 1; // 默认为已排序 + int count = 0; - // >>> 替换 PLACEHOLDER 为合适的指令完成注释的功能 __asm__ volatile ( - // 用于循环计数的寄存器 - "li t0, 1\n\t" - "addi t1, %1, 4\n\t" + // 用于保存目标值出现的次数 + "li t0, 0\n" + // 用于循环计数(索引)的寄存器 + "li t1, 0\n" + + "loop_start:\n" + // 如果索引 index >= n,则跳转到 loop_end + "bge t1, %2, loop_end\n" - "loop:\n\t" // 保存数组当前元素到t2寄存器 - "lw t2, 0(%1)\n\t" - // 保存数组下一个元素到t3寄存器 - "lw t3, 0(t1)\n\t" - // 如果当前元素大于下一个元素,数组不是按非降序排列 - "bge t3, t2, sorted\n\t" - "li %0, 0\n\t" - "j end\n\t" + "lw t2, 0(%1)\n" - "sorted:\n\t" - // 指针移动到数组下一个元素 - "addi %1, %1, 4\n\t" - // 指针移动到数组下下一个元素 - "addi t1, t1, 4\n\t" + // 对比数组元素与目标值,如果不相等,跳转到not_equal标签 + "bne t2, %3, not_equal\n" + "addi t0, t0, 1\n" - "addi t0, t0, 1\n\t" - // 如果计数器小于数组长度,则继续循环 - "blt t0, %2, loop\n\t" + "not_equal:\n" + "addi t1, t1, 1\n" + "addi %1, %1, 4\n" + "j loop_start\n" - "end:\n\t" - : "=r"(result) - : "r"(arr), "r"(n) - : "t0", "t1", "t2", "t3"); + "loop_end:\n" + "mv %0, t0\n" + : "=r"(count) + : "r"(arr), "r"(n), "r"(target) + : "t0", "t1", "t2"); - // <<< - return result; + return count; } -int -main (int argc, char *argv[]) +int main (int argc, char *argv[]) { - if (argc != 3) + if (argc != 4) { - fprintf (stderr, "Usage: %s \n", argv[0]); + fprintf (stderr, "Usage: %s \n", argv[0]); return 1; } @@ -77,9 +71,10 @@ main (int argc, char *argv[]) return 1; } - if (is_sorted (arr, n)) - printf ("Array is sorted.\n"); - else - printf ("Array is not sorted.\n"); + int target = atoi (argv[3]); + + int occurrences = count_occurrences (arr, n, target); + printf ("Occurrences of target:%d\n", occurrences); + return 0; -} \ No newline at end of file +} diff --git a/src/exercise-51/lru.c b/src/exercise-51/lru.c index 6e07ac2..d679822 100644 --- a/src/exercise-51/lru.c +++ b/src/exercise-51/lru.c @@ -21,7 +21,7 @@ void lru_page_replacement(char *queue_frames, int num_frames) { memset(frames, -1, num_frames * sizeof(int)); // 初始化页框数组为 -1 int lru_victim = 0; // 最近最少使用的页面索引 - int lru_min_time = 0; // 最近最少使用的页面的时间 + int lru_min_time = 0x7f7f7f7f; // 最近最少使用的页面的时间 int *lru_time = (int *)malloc(num_frames * sizeof(int)); // 分配时间数组 memset(lru_time, -1, num_frames * sizeof(int)); // 初始化时间数组为 -1 @@ -30,7 +30,7 @@ void lru_page_replacement(char *queue_frames, int num_frames) { while (token != NULL) { int access = atoi(token); int hit = 0; - lru_min_time = t + 1; + lru_min_time = 0x7f7f7f7f; for (int i = 0; i < num_frames; i++) { if (frames[i] == access) { lru_time[i] = t; @@ -56,3 +56,4 @@ void lru_page_replacement(char *queue_frames, int num_frames) { free(frames); // 释放内存 free(lru_time); // 释放内存 } + diff --git a/src/exercise-53/v2p.c b/src/exercise-53/v2p.c index 2019e63..6f82959 100644 --- a/src/exercise-53/v2p.c +++ b/src/exercise-53/v2p.c @@ -1,3 +1,5 @@ +#define PAGE_SIZE 0x1000 // 假设每个页大小为4KB,即2^12 + #include "v2p.h" #include #include @@ -10,8 +12,6 @@ uint32_t page_table[] = { 0x20003000 // 第四个虚拟页映射到物理页帧基地址 0x20003000 }; -#define PAGE_SIZE 0x1000 // 假设每个页大小为4KB,即2^12 - uint32_t translate_address (uint32_t virtual_address) { diff --git a/src/exercise-54/RR.c b/src/exercise-54/RR.c index f2896a7..f81d544 100644 --- a/src/exercise-54/RR.c +++ b/src/exercise-54/RR.c @@ -2,52 +2,72 @@ #include #include -void -calculateTimes (Process *processes, int n, int time_slice) -{ - int remaining_time[n]; // 用于跟踪每个进程的剩余执行时间 +void calculateTimes(Process *processes, int n, int time_slice) { + int remaining_time[n]; // 用于跟踪每个进程的剩余执行时间 - // 初始化剩余执行时间和其他计算结果为0 - for (int i = 0; i < n; i++) { - remaining_time[i] = processes[i].burst_time; - processes[i].completion_time = 0; - processes[i].turnaround_time = 0; - processes[i].waiting_time = 0; - } + // 初始化剩余执行时间和其他计算结果为0 + for (int i = 0; i < n; i++) { + remaining_time[i] = processes[i].burst_time; + processes[i].completion_time = 0; + processes[i].turnaround_time = 0; + processes[i].waiting_time = 0; + } - int current_time = 0; // 当前时间 + int current_time = 0; // 当前时间 - // 循环执行调度 - while (1) { - int all_finished = 1; // 所有进程是否完成的标志 + // 循环执行调度 + while (1) { + int all_finished = 1; // 所有进程是否完成的标志 - for (int i = 0; i < n; i++) { - if (remaining_time[i] > 0) { - all_finished = 0; // 还有进程未完成 - - if (remaining_time[i] > time_slice) { - // 执行一个时间片的工作量 - current_time += time_slice; - remaining_time[i] -= time_slice; - } else { - // 执行剩余的工作量 - current_time += remaining_time[i]; - 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; - remaining_time[i] = 0; // 进程完成 + for (int i = 0; i < n; i++) { + if (remaining_time[i] > 0) { + all_finished = 0; // 还有进程未完成 + + if (remaining_time[i] > time_slice) { + // 执行一个时间片的工作量 + current_time += time_slice; + remaining_time[i] -= time_slice; + } else { + // 执行剩余的工作量 + current_time += remaining_time[i]; + remaining_time[i] = 0; // 进程完成 + + 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; + } + } } - } + + if (all_finished) // 所有进程都已经完成 + break; + } + + // 输出每个进程的完成时间、周转时间和等待时间 + 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); } - if (all_finished) // 所有进程都已经完成 - break; - } + calculateTimes(processes, n, time_slice); - // 输出每个进程的完成时间、周转时间和等待时间 - 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); - } + return 0; } -- Gitee From 9f888197856dfa914bb56ca105e477d0157c26d7 Mon Sep 17 00:00:00 2001 From: Ruby_Facetious_a005 <1621059562@qq.com> Date: Sun, 16 Jun 2024 06:02:31 +0000 Subject: [PATCH 3/4] test Signed-off-by: Ruby_Facetious_a005 <1621059562@qq.com> --- src/exercise-23/convolution.c | 30 +++++----- src/exercise-37/timer.c | 110 +++++++++++++++++----------------- src/exercise-39/fileop.c | 2 +- src/exercise-51/lru.c | 32 ++++++---- src/exercise-53/v2p.c | 29 +++++---- src/exercise-54/RR.c | 41 ++++++------- 6 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/exercise-23/convolution.c b/src/exercise-23/convolution.c index 9366a44..06f2133 100644 --- a/src/exercise-23/convolution.c +++ b/src/exercise-23/convolution.c @@ -9,27 +9,27 @@ convolution2D (int input[5][5], int kernel[3][3], int output[3][3], // 初始化输出数组 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 = 0; i < inputSize - kernelSize + 1; i++) + // 在下面通过多重循环实现卷积运算 + for (i = kernelRadius; i < inputSize - kernelRadius; ++i) + { + for (j = kernelRadius; j < inputSize - kernelRadius; ++j) { - for (j = 0; j < inputSize - kernelSize + 1; j++) + for (m = -kernelRadius; m <= kernelRadius; ++m) + { + for (n = -kernelRadius; n <= kernelRadius; ++n) { - // 对于每个输出元素,应用卷积核 - for (m = 0; m < kernelSize; m++) - { - for (n = 0; n < kernelSize; n++) - { - output[i][j] += input[i + m][j + n] * kernel[m][n]; - } - } + output[i - kernelRadius][j - kernelRadius] + += input[i + m][j + n] * kernel[m + kernelRadius][n + kernelRadius]; } + } } + } } diff --git a/src/exercise-37/timer.c b/src/exercise-37/timer.c index 224b467..9387354 100644 --- a/src/exercise-37/timer.c +++ b/src/exercise-37/timer.c @@ -7,101 +7,103 @@ #define MAX_ARR_SIZE 100 static char *input_str = NULL; -module_param (input_str, charp, S_IRUGO); -MODULE_PARM_DESC (input_str, "A comma-separated string of integers"); +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) +static int parse_input(const char *input, int *arr, int *size) { - char *str, *token; - int value, count = 0; + 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; + // 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) + // Split the input string by commas using strsep + while ((token = strsep(&str, ",")) != NULL) { - if (kstrtoint (token, 10, &value) == 0) + if (kstrtoint(token, 10, &value) == 0) { - if (count < MAX_ARR_SIZE) + if (count < MAX_ARR_SIZE) { - arr[count++] = value; + arr[count++] = value; } - else + else { - break; + break; } } } - *size = count; + *size = count; - // Free the allocated memory - kfree (str_orig); + // Free the allocated memory + kfree(str_orig); - return 0; + return 0; } -static int -max_value (int arr[], int size) +static int max_value(int arr[], int size) { - int max = arr[0]; + int max = arr[0]; - // >>> 在这里实现最大值查找。 - for (int i = 1; i < size; i++) { - if (arr[i] > max) { - max = arr[i]; + // 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; + return max; } -static int __init -max_init (void) +static int __init max_init(void) { - int max; + int max; - if (!input_str) + if (!input_str) { - printk (KERN_ERR "No input string provided\n"); - return -EINVAL; + printk(KERN_ERR "No input string provided\n"); + return -EINVAL; } - if (parse_input (input_str, arr, &arr_size) != 0) + if (parse_input(input_str, arr, &arr_size) != 0) { - printk (KERN_ERR "Failed to parse input string\n"); - return -EINVAL; + printk(KERN_ERR "Failed to parse input string\n"); + return -EINVAL; } - if (arr_size == 0) + if (arr_size == 0) { - printk (KERN_ERR "Array is empty\n"); - return -EINVAL; + printk(KERN_ERR "Array is empty\n"); + return -EINVAL; } - max = max_value (arr, arr_size); - printk (KERN_INFO "Maximum value in the array: %d\n", max); + max = max_value(arr, arr_size); + printk(KERN_INFO "Maximum value in the array: %d\n", max); - return 0; + return 0; } -static void __exit -max_exit (void) +static void __exit max_exit(void) { - printk (KERN_INFO "Module unloaded\n"); + printk(KERN_INFO "Module unloaded\n"); } -module_init (max_init); -module_exit (max_exit); +module_init(max_init); +module_exit(max_exit); -MODULE_LICENSE ("GPL"); -MODULE_AUTHOR ("Your Name"); -MODULE_DESCRIPTION ("Array Maximum Value Module"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Your Name"); +MODULE_DESCRIPTION("Array Maximum Value Module"); diff --git a/src/exercise-39/fileop.c b/src/exercise-39/fileop.c index f616d63..88dab57 100644 --- a/src/exercise-39/fileop.c +++ b/src/exercise-39/fileop.c @@ -16,7 +16,7 @@ static int __init fileop_init(void) printk(KERN_INFO "Module loaded\n"); // Open the file - file_ptr = filp_open(FILE_NAME, O_RDONLY, 0); + file_ptr = filp_open(FILE_NAME, O_RDWR | O_CREAT, 0644); if (IS_ERR(file_ptr)) { printk(KERN_ALERT "Failed to open file\n"); diff --git a/src/exercise-51/lru.c b/src/exercise-51/lru.c index d679822..310c773 100644 --- a/src/exercise-51/lru.c +++ b/src/exercise-51/lru.c @@ -3,7 +3,6 @@ #include #include -// 打印当前页框状态 void print_frames(int access, int *frames, int num) { printf("Access: %d, Frames: [", access); for (int i = 0; i < num; ++i) { @@ -15,18 +14,26 @@ void print_frames(int access, int *frames, int num) { printf("]\n"); } -// LRU页面置换算法 void lru_page_replacement(char *queue_frames, int num_frames) { - int *frames = (int *)malloc(num_frames * sizeof(int)); // 分配页框数组 - memset(frames, -1, num_frames * sizeof(int)); // 初始化页框数组为 -1 + 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)); // 分配时间数组 - memset(lru_time, -1, num_frames * sizeof(int)); // 初始化时间数组为 -1 + 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, ","); // 解析页面访问序列 + int t = 1; + char *token = strtok(queue_frames, ","); while (token != NULL) { int access = atoi(token); int hit = 0; @@ -53,7 +60,6 @@ void lru_page_replacement(char *queue_frames, int num_frames) { ++t; } - free(frames); // 释放内存 - free(lru_time); // 释放内存 + free(frames); + free(lru_time); } - diff --git a/src/exercise-53/v2p.c b/src/exercise-53/v2p.c index 6f82959..a550433 100644 --- a/src/exercise-53/v2p.c +++ b/src/exercise-53/v2p.c @@ -1,26 +1,25 @@ -#define PAGE_SIZE 0x1000 // 假设每个页大小为4KB,即2^12 - #include "v2p.h" #include -#include + +#define PAGE_SIZE 0x1000 // 假设每个页大小为4KB,即2^12 // 模拟页表(在真实情况下,这会在内存中) uint32_t page_table[] = { - 0x20000000, // 第一个虚拟页映射到物理页帧基地址 0x20000000 - 0x20001000, // 第二个虚拟页映射到物理页帧基地址 0x20001000 - 0x20002000, // 第三个虚拟页映射到物理页帧基地址 0x20002000 - 0x20003000 // 第四个虚拟页映射到物理页帧基地址 0x20003000 + 0x20000000, // 第一个虚拟页映射到物理页帧基地址 0x20000000 + 0x20001000, // 第二个虚拟页映射到物理页帧基地址 0x20001000 + 0x20002000, // 第三个虚拟页映射到物理页帧基地址 0x20002000 + 0x20003000 // 第四个虚拟页映射到物理页帧基地址 0x20003000 }; -uint32_t -translate_address (uint32_t virtual_address) +uint32_t translate_address(uint32_t virtual_address) { - // 获取虚拟页号 - uint32_t page_num = virtual_address / PAGE_SIZE; + // 计算虚拟页号 + uint32_t page_number = virtual_address / PAGE_SIZE; - // 获取页内偏移量 - uint32_t offset = virtual_address % PAGE_SIZE; + // 计算页内偏移量 + uint32_t offset = virtual_address % PAGE_SIZE; - // 返回物理地址 - return page_table[page_num] + offset; + // 返回物理地址 + return page_table[page_number] + offset; } + diff --git a/src/exercise-54/RR.c b/src/exercise-54/RR.c index f81d544..54f4d04 100644 --- a/src/exercise-54/RR.c +++ b/src/exercise-54/RR.c @@ -2,45 +2,38 @@ #include #include -void calculateTimes(Process *processes, int n, int time_slice) { - int remaining_time[n]; // 用于跟踪每个进程的剩余执行时间 - - // 初始化剩余执行时间和其他计算结果为0 +int all_done(Process *processes, int n) { for (int i = 0; i < n; i++) { - remaining_time[i] = processes[i].burst_time; - processes[i].completion_time = 0; - processes[i].turnaround_time = 0; - processes[i].waiting_time = 0; + if (processes[i].burst_time > 0) { + return 0; + } } + return 1; +} - int current_time = 0; // 当前时间 +void calculateTimes(Process *processes, int n, int time_slice) { + int current_time = 0; + int all_finished = 0; - // 循环执行调度 - while (1) { - int all_finished = 1; // 所有进程是否完成的标志 + while (!all_finished) { + all_finished = 1; for (int i = 0; i < n; i++) { - if (remaining_time[i] > 0) { - all_finished = 0; // 还有进程未完成 + if (processes[i].burst_time > 0) { + all_finished = 0; - if (remaining_time[i] > time_slice) { - // 执行一个时间片的工作量 + if (processes[i].burst_time > time_slice) { current_time += time_slice; - remaining_time[i] -= time_slice; + processes[i].burst_time -= time_slice; } else { - // 执行剩余的工作量 - current_time += remaining_time[i]; - remaining_time[i] = 0; // 进程完成 - + 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; } } } - - if (all_finished) // 所有进程都已经完成 - break; } // 输出每个进程的完成时间、周转时间和等待时间 -- Gitee From 1ecb5d63e0c83605d6d1baac629a94002f82f275 Mon Sep 17 00:00:00 2001 From: Ruby_Facetious_a005 <1621059562@qq.com> Date: Sun, 16 Jun 2024 06:15:03 +0000 Subject: [PATCH 4/4] test Signed-off-by: Ruby_Facetious_a005 <1621059562@qq.com> --- src/exercise-53/v2p.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/exercise-53/v2p.c b/src/exercise-53/v2p.c index a550433..74ccf1a 100644 --- a/src/exercise-53/v2p.c +++ b/src/exercise-53/v2p.c @@ -1,25 +1,20 @@ #include "v2p.h" #include - -#define PAGE_SIZE 0x1000 // 假设每个页大小为4KB,即2^12 +#include // 模拟页表(在真实情况下,这会在内存中) + uint32_t page_table[] = { - 0x20000000, // 第一个虚拟页映射到物理页帧基地址 0x20000000 - 0x20001000, // 第二个虚拟页映射到物理页帧基地址 0x20001000 - 0x20002000, // 第三个虚拟页映射到物理页帧基地址 0x20002000 - 0x20003000 // 第四个虚拟页映射到物理页帧基地址 0x20003000 + 0x20000000, // 第一个虚拟页映射到物理页帧基地址 0x20000000 + 0x20001000, // 第二个虚拟页映射到物理页帧基地址 0x20001000 + 0x20002000, // 第三个虚拟页映射到物理页帧基地址 0x20002000 + 0x20003000 // 第四个虚拟页映射到物理页帧基地址 0x20003000 }; -uint32_t translate_address(uint32_t virtual_address) +uint32_t +translate_address (uint32_t virtual_address) { - // 计算虚拟页号 - uint32_t page_number = virtual_address / PAGE_SIZE; - - // 计算页内偏移量 - uint32_t offset = virtual_address % PAGE_SIZE; - - // 返回物理地址 - return page_table[page_number] + offset; + uint32_t page_number = virtual_address / PAGE_SIZE; + return page_table[page_number] + (virtual_address % PAGE_SIZE); } -- Gitee