First implementation of lab1

This commit is contained in:
Andrew Golovashevich 2024-10-11 01:30:30 +03:00
parent 2e968232c2
commit f8286f50b0
7 changed files with 194 additions and 6 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
/.idea/ /.idea/
/*build*/ *build*/
*.o *.o
*.obj *.obj
*.exe *.exe

View File

@ -1,5 +1,5 @@
services: services:
environment: environment:
image: "bgtu/os/environment:l1v0.3" image: "bgtu/os/environment:l1v1"
build: build:
dockerfile: ./environment.dockerfile dockerfile: ./environment.dockerfile

View File

@ -1,6 +1,3 @@
FROM alpine:3.20.3 FROM alpine:3.20.3
RUN apk update && apk upgrade RUN apk update && apk upgrade
RUN apk add clang cmake linux-headers RUN apk add clang cmake linux-headers lldb make gdb
RUN apk add lldb
RUN apk add make
RUN apk add gdb

7
lab1/v7/CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.25)
project(os)
set(CMAKE_CXX_STANDARD 20)
add_executable(using_pause using_pause.c)
add_executable(using_signal_handlers using_signal_handlers.c)

56
lab1/v7/using_pause.c Normal file
View File

@ -0,0 +1,56 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
void wait_clocks(clock_t clocks_to_wait) {
const clock_t end = clock() + clocks_to_wait;
while (clock() < end);
}
struct ping_pong_data {
char const *name;
const pid_t pid_to_print;
const pid_t pid_to_send;
double delay_seconds;
};
int run_exchange(char const *name, pid_t pid_to_print, pid_t pid_to_send, int wait_first, double delay_seconds) {
const clock_t delay_clocks = (clock_t) (CLOCKS_PER_SEC * delay_seconds);
if (wait_first)
goto WAIT;
while (1) {
printf("[%s] Got signal\n", name);
printf("[%s] PID=%d\n", name, pid_to_print);
printf("[%s] Sleeping %lf seconds before sending signal\n", name, delay_seconds);
wait_clocks(delay_clocks);
printf("[%s] Sending signal\n", name);
kill(pid_to_send, SIGUSR1);
WAIT:
pause();
}
perror("Program interrupted");
return EXIT_SUCCESS;
}
void noop(int){
}
int main(void) {
signal(SIGUSR1, noop);
pid_t parent_pid = getpid();
pid_t child_pid = fork();
switch (child_pid) {
case -1:
perror("Failed to fork\n");
return EXIT_FAILURE;
case 0:
child_pid = getpid();
return run_exchange("c", parent_pid, parent_pid, 1, 2.5);
default:
return run_exchange("p", child_pid, child_pid, 0, 2.5);
}
}

45
lab1/v7/using_pipes.c Normal file
View File

@ -0,0 +1,45 @@
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int run_exchange(int in_pipe, int out_pipe) {
}
int main(void) {
struct {
int in_pipe;
int out_pipe;
} p2c_pipe, c2p_pipe;
if (pipe2((int *) &p2c_pipe, O_DIRECT) == -1) {
perror("Failed to create pipes\n");
return EXIT_FAILURE;
}
if (pipe2((int *) &c2p_pipe, O_DIRECT) == -1) {
close(p2c_pipe.in_pipe);
close(p2c_pipe.out_pipe);
perror("Failed to create pipes\n");
return EXIT_FAILURE;
}
pid_t parent_pid = getpid();
pid_t child_pid = fork();
switch (child_pid) {
case -1:
close(p2c_pipe.in_pipe);
close(p2c_pipe.out_pipe);
close(c2p_pipe.in_pipe);
close(c2p_pipe.out_pipe);
perror("Failed to fork\n");
return EXIT_FAILURE;
case 0:
close(p2c_pipe.in_pipe);
close(c2p_pipe.out_pipe);
default:
close(c2p_pipe.in_pipe);
close(p2c_pipe.out_pipe);
}
}

View File

@ -0,0 +1,83 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <strings.h>
void wait_clocks(clock_t clocks_to_wait) {
const clock_t end = clock() + clocks_to_wait;
while (clock() < end);
}
struct ping_pong_data_t {
char const *name;
pid_t pid_to_print;
pid_t pid_to_send;
double delay_seconds;
} ping_pong_data;
void do_ping_pong(int signo) {
if (signo != SIGUSR1)
return;
const clock_t delay_clocks = (clock_t) (CLOCKS_PER_SEC * ping_pong_data.delay_seconds);
printf("[%s] Got signal\n", ping_pong_data.name);
printf("[%s] PID=%d\n", ping_pong_data.name, ping_pong_data.pid_to_print);
printf("[%s] Sleeping %lf seconds before sending signal\n", ping_pong_data.name, ping_pong_data.delay_seconds);
wait_clocks(delay_clocks);
printf("[%s] Sending signal\n", ping_pong_data.name);
kill(ping_pong_data.pid_to_send, SIGUSR1);
}
volatile int is_running = 1;
void interrupt(int signo) {
if (signo != SIGINT)
return;
is_running = 0;
}
int main(void) {
signal(SIGINT, interrupt);
pid_t parent_pid = getpid();
pid_t child_pid = fork();
switch (child_pid) {
case -1:
perror("Failed to fork\n");
return EXIT_FAILURE;
case 0:
child_pid = getpid();
ping_pong_data.name = "c";
ping_pong_data.delay_seconds = 2.5;
ping_pong_data.pid_to_print = parent_pid;
ping_pong_data.pid_to_send = parent_pid;
signal(SIGUSR1, do_ping_pong);
break;
default:
ping_pong_data.name = "c";
ping_pong_data.delay_seconds = 2.5;
ping_pong_data.pid_to_print = child_pid;
ping_pong_data.pid_to_send = child_pid;
signal(SIGUSR1, do_ping_pong);
kill(parent_pid, SIGUSR1);
break;
}
while (is_running)
pause();
return EXIT_SUCCESS;
}