init commit
This commit is contained in:
Executable
+32
@@ -0,0 +1,32 @@
|
||||
В ОЗУ 16-разрядного компьютера используется контроль целостности данных по
|
||||
четности. Описать возможную структуру ячейки памяти и ее побитовое содержимое
|
||||
для случая хранения в машинном слове восьмеричного числа 17735.
|
||||
|
||||
64 6
|
||||
128 7
|
||||
256 8
|
||||
|
||||
2 pow 10 = 1024
|
||||
2 pow 11 = 2048
|
||||
2 pow 12 = 4096
|
||||
2 pow 13 = 8192
|
||||
2 pow 14 = 16384
|
||||
|
||||
17735 -
|
||||
16384 =
|
||||
01351 -
|
||||
01024 =
|
||||
00327 -
|
||||
00256 =
|
||||
00071 -
|
||||
00064 =
|
||||
00007
|
||||
|
||||
|
||||
0010 0010 1010 0111
|
||||
|
||||
xor all = 1 - somewhere
|
||||
|
||||
всё сверху хуйня, число восьмиричное
|
||||
001 111 111 011 101
|
||||
xor = 1
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
Пусть дано восьмеричное число 173357, являющееся адресом оперативной памяти,
|
||||
расслоенной по 16 банкам. Банку с каким номером принадлежит заданный адрес?
|
||||
001 111 011 011 101 111
|
||||
|
||||
1111 0110 1110 1111
|
||||
|
||||
4 bit
|
||||
|
||||
15?
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct segment
|
||||
{
|
||||
unsigned int base;
|
||||
unsigned int size;
|
||||
} segment;
|
||||
|
||||
// 8-ми сегментная
|
||||
unsigned int
|
||||
VirtIntoPhys(segment *segTable, unsigned int VirtAdr)
|
||||
{
|
||||
unsigned int SegNum = VirtAdr >> 29;
|
||||
unsigned int offset = (VirtAdr << 3) >> 3;
|
||||
|
||||
if (offset > segTable[SegNum].size) {
|
||||
_exit(25);
|
||||
}
|
||||
|
||||
return segTable[SegNum].base + offset;
|
||||
}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// Стоит добавить проверки на успешность системных вызовов
|
||||
|
||||
enum
|
||||
{
|
||||
BlockSize = 16,
|
||||
}
|
||||
|
||||
int fds[4];
|
||||
unsigned int sizes[4];
|
||||
char **list = [ "Disk0", "Disk0", "Disk0", "Disk0" ];
|
||||
|
||||
void
|
||||
Ini_Raid0(void)
|
||||
{
|
||||
struct stat st;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
fds[i] = open(list[i], O_RDWR);
|
||||
lstat(list[i], &st);
|
||||
sizes[i] = st.st_size;
|
||||
if (i != 0) {
|
||||
sizes[i] += sizes[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Read_Raid0(int num, char *buf)
|
||||
{
|
||||
unsigned int byte = num * BlockSize;
|
||||
int now_disk = 0;
|
||||
|
||||
for (int i = 0; i < BlockSize; ++i) {
|
||||
while (byte > sizes[now_disk]) {
|
||||
now_disk++;
|
||||
}
|
||||
|
||||
if (now_disk > 3) {
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
if (now_disk != 0) {
|
||||
lseek(fds[now_disk], byte - sizes[now_disk - 1]);
|
||||
} else {
|
||||
lseek(fds[now_disk], byte);
|
||||
}
|
||||
read(fds[now_disk], 1, buf + i);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
enum
|
||||
{
|
||||
BlockSize = 16,
|
||||
}
|
||||
|
||||
int fds[4];
|
||||
unsigned int sizes[4];
|
||||
char **list = [ "Disk0", "Disk0", "Disk0", "Disk0" ];
|
||||
|
||||
void
|
||||
Ini_Raid0(void)
|
||||
{
|
||||
struct stat st;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
fds[i] = open(list[i], O_RDWR);
|
||||
lstat(list[i], &st);
|
||||
sizes[i] = st.st_size / BlockSize;
|
||||
if (i != 0) {
|
||||
sizes[i] += sizes[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Read_Raid0(int num, char *buf)
|
||||
{
|
||||
int now_disk = 0;
|
||||
int now_block = 0;
|
||||
while (now_block != num) {
|
||||
if (sizes[now_disk]
|
||||
|
||||
now_disk++;
|
||||
now_block++;
|
||||
now_disk %= 4;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
Что будет выведено на экран? Прокомментировать, почему? Если возможны несколько вариантов – привести все. Предполагается, что
|
||||
обращение к функции вывода на экран прорабатывает атомарно и без буферизации. Все системные вызовы прорабатывают успешно.
|
||||
Подключение заголовочных файлов опущено.
|
||||
|
||||
int main() {
|
||||
int pid;
|
||||
int fd[2];
|
||||
char c = 'a';
|
||||
pipe(fd);
|
||||
|
||||
if( (pid = fork()) > 0 ) {
|
||||
read(fd[0], &c, 1);
|
||||
kill(pid, SIGKILL);
|
||||
wait(NULL);
|
||||
} else {
|
||||
putchar(c);
|
||||
c = 'b';
|
||||
write(fd[1], &c, 1);
|
||||
c = 'c';
|
||||
}
|
||||
|
||||
putchar(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(Вес задачи: 2 балла)
|
||||
|
||||
Answer:
|
||||
1) начнётся с a т.к. отец заблокируется на считывании
|
||||
2) сын записал б в канал, дальше либо отец может отправить его "на убийство", либо сын проработает быстрее. У сына с
|
||||
3) только после смерти сына отец выведет б
|
||||
|
||||
aсб
|
||||
aб
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
Сколько раз система обратится к содержимому индексных дескрипторов при вызове: open("/dir1/dir2/dir3/file", O_RDONLY)?
|
||||
Прокомментировать, почему? Считаем, что ни один из элементов пути к файлу не является символической ссылкой. (Вес задачи: 1 балл)
|
||||
|
||||
$$ Answer:
|
||||
1) система будет последовательно пробегать по каждому из каталогов.
|
||||
1) будет искать, есть ли файл в каталоге.
|
||||
2) будет проверять, является ли сам файл каталогом.
|
||||
|
||||
2) сначала корень. ищем в нём dir1.<#> Первое обращение. Проверяем dir1 на каталог.<#> Второе обращение
|
||||
find dir2 in dir1.<#> dir2 is dir?<#>
|
||||
find dir3 in dir2.<#> dir3 is dir?<#>
|
||||
find file in dir3.<#>
|
||||
|
||||
=> всего нам надо 7 обращений к содержимому индексных дескрипторов
|
||||
|
||||
|
||||
$$ Ответ GPT:
|
||||
При вызове open("/dir1/dir2/dir3/file", O_RDONLY) система обращается к индексным дескрипторам (inode) для каждого элемента пути.
|
||||
|
||||
Основные этапы:
|
||||
|
||||
Корневая директория /:
|
||||
Первое обращение к индексному дескриптору (inode) — система обращается к inode корневого каталога /.
|
||||
|
||||
Директория dir1:
|
||||
Второе обращение — система читает содержимое inode корневого каталога и ищет запись для dir1, после чего обращается к inode для dir1.
|
||||
|
||||
Директория dir2:
|
||||
Третье обращение — система читает inode для dir1, затем ищет в его содержимом запись о dir2 и обращается к соответствующему inode.
|
||||
|
||||
Директория dir3:
|
||||
Четвёртое обращение — система аналогично читает inode для dir2, находит запись для dir3 и обращается к inode для dir3.
|
||||
|
||||
Файл file:
|
||||
Пятое обращение — система читает inode для dir3, находит запись о файле file и обращается к inode для файла.
|
||||
|
||||
Итог:
|
||||
Таким образом, система обращается к содержимому индексных дескрипторов 5 раз (по количеству элементов пути /, dir1, dir2, dir3, file).
|
||||
|
||||
Почему:
|
||||
Каждая директория в Unix-подобных файловых системах представлена как файл каталога, содержащий список файлов и подкаталогов.
|
||||
Чтобы найти нужный файл, система последовательно открывает каждый inode, пока не доберётся до конечного файла.
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
cal
|
||||
Executable
BIN
Binary file not shown.
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int
|
||||
return_bit_int(int *mas, int n)
|
||||
{
|
||||
unsigned int byte = mas[n / (sizeof(int) * 8)]; // (sizeof(int) * 8) == 32
|
||||
int offset = 32 - 1 - n % 32;
|
||||
|
||||
return (byte & (1 << offset)) >> offset;
|
||||
}
|
||||
|
||||
int
|
||||
return_bit_byte(unsigned char *mas, int n)
|
||||
{
|
||||
unsigned int byte = mas[n / (sizeof(char) * 8)]; // (sizeof(char) * 8) == 8
|
||||
int offset = 8 - 1 - n % 8;
|
||||
|
||||
return (byte & (1 << offset)) >> offset;
|
||||
}
|
||||
|
||||
// пусть битовый массив записан в файл. Массив - свободные блоки ФС. Вывести максимальную длину свободных блоков.
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd = open(argv[1], O_RDONLY);
|
||||
|
||||
int size = lseek(fd, 0, SEEK_END);
|
||||
unsigned char *mas = malloc(size);
|
||||
|
||||
lseek(fd, 0, 0); // SEEK_CUR == 0, SEEK_SET == 1, SEEK_END == 2
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
read(fd, mas + i, 1); // читаем из файла массив
|
||||
}
|
||||
|
||||
int max_len = 0;
|
||||
int tmp = 0; // для хранения текущей длины
|
||||
for (int i = 0; i < size * 8; ++i) { // пробегаем по всем битам
|
||||
if (return_bit_byte(mas, i) == 1) {
|
||||
tmp++;
|
||||
} else {
|
||||
max_len = (max_len > tmp) ? max_len : tmp;
|
||||
tmp = 0;
|
||||
}
|
||||
}
|
||||
max_len = (max_len > tmp) ? max_len : tmp; // если последний бит был 1, то надо доп проверку
|
||||
|
||||
printf("%d\n", max_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
// на вход подаётся имя каталога.
|
||||
// пробежать рекурсивно по всему каталогу и папкам в нём. Если встретился регулярный файл с именем, которое
|
||||
// заканчивается на .exeсute, открыть, прочесть путь, запустить по нему прогу.
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
DIR *d = opendir(argv[1]);
|
||||
struct dirent *dd;
|
||||
while ((dd = readdir(d))) {
|
||||
char str[PATH_MAX];
|
||||
snprintf(str, PATH_MAX, "%s/%s", argv[1], dd->d_name);
|
||||
|
||||
write(1, str, strlen(str));
|
||||
write(1, "\n", 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
// на вход подаётся имя каталога.
|
||||
// пробежать рекурсивно по всему каталогу и папкам в нём. Если встретился регулярный файл с именем, которое
|
||||
// заканчивается на .exeсute, открыть, прочесть путь, запустить по нему прогу.
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
DIR *d = opendir(argv[1]);
|
||||
struct dirent *dd;
|
||||
struct stat st;
|
||||
while ((dd = readdir(d))) {
|
||||
if (strcmp(dd->d_name, ".") == 0 || strcmp(dd->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char str[PATH_MAX];
|
||||
snprintf(str, PATH_MAX, "%s/%s", argv[1], dd->d_name);
|
||||
lstat(str, &st);
|
||||
if (S_ISREG(st.st_mode) && st.st_size < strtol(argv[2], NULL, 10)) {
|
||||
if (strlen(str) >= 8 && strcmp(str + strlen(str) - 8, ".execute") == 0) {
|
||||
int fd = open(str, O_RDONLY);
|
||||
char s[PATH_MAX + 1];
|
||||
// memset(s, 0, PATH_MAX);
|
||||
s[read(fd, s, PATH_MAX)] = '\0';
|
||||
if (!fork()) {
|
||||
execlp(s, s, NULL);
|
||||
_exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
enum
|
||||
{
|
||||
BlockSize = 16,
|
||||
}
|
||||
|
||||
int fds[4];
|
||||
unsigned int sizes[4];
|
||||
char **list = [ "Disk0", "Disk0", "Disk0", "Disk0" ];
|
||||
|
||||
void
|
||||
Ini_Raid0(void)
|
||||
{
|
||||
struct stat st;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
fds[i] = open(list[i], O_RDWR);
|
||||
lstat(list[i], &st);
|
||||
sizes[i] = st.st_size / BlockSize;
|
||||
if (i != 0) {
|
||||
sizes[i] += sizes[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Read_Raid0(int num, char *buf)
|
||||
{
|
||||
int now_disk = 0;
|
||||
int now_block = 0;
|
||||
while (now_block != num) {
|
||||
if (sizes[now_disk]
|
||||
|
||||
now_disk++;
|
||||
now_block++;
|
||||
now_disk %= 4;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
enum
|
||||
{
|
||||
BlockSize = 16,
|
||||
}
|
||||
|
||||
int fds[5];
|
||||
void
|
||||
Write_Raid4(int num, char *buf)
|
||||
{
|
||||
unsigned char tmp1[BlockSize];
|
||||
unsigned char tmp2[BlockSize];
|
||||
int num_disk = num % 4;
|
||||
|
||||
lseek(fd[num_disk], num * BlockSize);
|
||||
lseek(fd[4], num * BlockSize);
|
||||
read(fd[num_disk], tmp1, BlockSize);
|
||||
read(fd[4], tmp2, BlockSize);
|
||||
|
||||
for (int i = 0; i < BlockSize; ++i) {
|
||||
tmp2[i] ^= tmp1[i];
|
||||
tmp2[i] ^= buf[i];
|
||||
}
|
||||
|
||||
lseek(fd[num_disk], num * BlockSize);
|
||||
lseek(fd[4], num * BlockSize);
|
||||
write(fd[num_disk], buf, BlockSize);
|
||||
write(fd[4], tmp2, BlockSize);
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
// суть - предсказываем поведение кэша.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
enum
|
||||
{
|
||||
CACHE_LEN = 1024,
|
||||
BLOCK_SIZE = 512,
|
||||
};
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
unsigned addrs[CACHE_LEN];
|
||||
memset(addrs, -1, CACHE_LEN);
|
||||
|
||||
unsigned addr, cnt = 0;
|
||||
while (scanf("%u", &addr) == 1) {
|
||||
int i = (addr / BLOCK_SIZE) % CACHE_LEN;
|
||||
cnt += (addrs[i] != -1) && (addrs[i] != addr);
|
||||
addrs[i] = addr;
|
||||
}
|
||||
}
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
struct record
|
||||
{
|
||||
double dbl, int num,
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int shm_key = shmget(IPC_PRIVATE, sizeof(record), IPC_CREAT | 0666);
|
||||
int sem_key = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
|
||||
|
||||
record *mem = shmat(shm_key, NULL, 0);
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
int fd = open(argv[i], O_RDONLY);
|
||||
double sum = 0;
|
||||
int num = 0;
|
||||
double tmp;
|
||||
|
||||
while (read(fd, &tmp, sizeof(tmp)) {
|
||||
num++;
|
||||
sum += tmp;
|
||||
}
|
||||
semop(sem_key, &(struct sembuf){.sem_num = 0, .sem_op = -2}, 1);
|
||||
*mem = (struct record){.dbl = sum, .num = num};
|
||||
semop(sem_key, &(struct sembuf){.sem_num = 0, .sem_op = -1}, 1);
|
||||
}
|
||||
|
||||
while (wait(NULL) != -1) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user