Skip to content

Commit e863bd2

Browse files
committed
Pushing labs 1->6
All laboratories of the first part of the course, related to Linux (system and device) programming
1 parent 2df8b04 commit e863bd2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3756
-0
lines changed

Lab1/D01/E01.c

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <unistd.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <time.h>
5+
#include <fcntl.h>
6+
7+
int cmpfunc (const void*, const void*);
8+
9+
int main(int argc, char* argv[]){
10+
if (argc != 3){
11+
fprintf(stderr, "Error: wrong # of arguments");
12+
return -1;
13+
}
14+
15+
srand(time(NULL));
16+
// Take from command line two integer numbers - as parameters
17+
int n1 = atoi(argv[1]);
18+
int n2 = atoi(argv[2]);
19+
20+
// Allocate two vectors v1 and v2
21+
int *v1 = malloc(n1*sizeof(int));
22+
int *v2 = malloc(n2*sizeof(int));
23+
24+
// Fill v1 with n1 random numbers between 10 and 100 - need random lib
25+
for (int i=0; i<n1; i++){
26+
do {
27+
v1[i] = rand() % 90;
28+
v1[i] += 10;
29+
} while (v1[i]%2!=0);
30+
}
31+
// Fill v2 with n2 random numbers between 21 and 101 - need random lib
32+
for (int i=0; i<n2; i++){
33+
do {
34+
v2[i] = rand() % 81;
35+
v2[i] += 21;
36+
} while (v2[i]%2==0);
37+
}
38+
// Printing arrays before Sorting
39+
printf("Array before sort:\n");
40+
printf("Array 1:\n");
41+
for (int i=0; i<n1; i++) printf ("%d\t", v1[i]);
42+
printf("\n");
43+
printf("Array 2:\n");
44+
for (int i=0; i<n2; i++) printf ("%d\t", v2[i]);
45+
printf("\n");
46+
47+
//Sort v1 and v2
48+
qsort(v1, n1, sizeof(int), cmpfunc);
49+
qsort(v2, n2, sizeof(int), cmpfunc);
50+
51+
// Print after sort (to check)
52+
printf("Array after sort:\n");
53+
printf("Array 1:\n");
54+
for (int i=0; i<n1; i++) printf ("%d\t", v1[i]);
55+
printf("\n");
56+
printf("Array 2:\n");
57+
for (int i=0; i<n2; i++) printf ("%d\t", v2[i]);
58+
printf("\n");
59+
60+
// Print the first text file
61+
int fv1, fv2;
62+
if ((fv1 = open("fv1.txt", O_WRONLY | O_CREAT, 0777))<0){
63+
return -1;
64+
}
65+
char myBuff1[n1*4 + 4];
66+
int j = 0;
67+
for (int i=0; i<n1; i++) j+=sprintf(&myBuff1[j], "%d ", v1[i]);
68+
write(fv1, myBuff1, sizeof(char)*j);
69+
close(fv1);
70+
printf("File v1 written. \n");
71+
72+
// Print the second text file
73+
if ((fv2 = open("fv2.txt", O_WRONLY | O_CREAT, 0777))<0){
74+
return -1;
75+
}
76+
char myBuff2[n2*4 + 4];
77+
j = 0;
78+
for (int i=0; i<n2; i++) j+=sprintf(&myBuff2[j], "%d ", v2[i]);
79+
write(fv2, myBuff2, sizeof(char)*j);
80+
close(fv2);
81+
printf("File v2 written. \n");
82+
83+
// Print v1 in fv1.b
84+
if ((fv1 = open("fv1.b", O_WRONLY | O_CREAT, 0777))<0){
85+
return -1;
86+
}
87+
write(fv1, v1, sizeof(int)*n1);
88+
// Print v2 in fv2.b
89+
if ((fv2 = open("fv2.b", O_WRONLY | O_CREAT, 0777))<0){
90+
return -1;
91+
}
92+
write(fv2, v2, sizeof(int)*n2);
93+
94+
exit(1);
95+
}
96+
97+
int cmpfunc (const void * a, const void * b){
98+
return ( *(int*)a - *(int*)b );
99+
}

Lab1/D01/E01_report.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# SDP 2016/17 - Lab 1 - Davide Gallitelli S241521
2+
3+
### E01 - C program for file generation
4+
The first task of this laboratory asks to implement a C program which creates a total of four files, fv1 and fv2 as both binary and text files, containing a user-specified number of random integer numbers.
5+
6+
In order to receive from input these values, the approach chosen is to read them from command line as arguments of the program. This means that _argv[1]_ and _argv[2]_ will have the characters related to the values in input. The _atoi_ function is used to return the integer value from the ASCII read by the console. If the number of arguments is different from 3 (./file n1 n2), the program prints an error and exits with a -1 return value.
7+
8+
```
9+
if (argc != 3){
10+
fprintf(stderr, "Error: wrong # of arguments");
11+
return -1;
12+
}
13+
14+
srand(time(NULL));
15+
// Take from command line two integer numbers - as parameters
16+
int n1 = atoi(argv[1]);
17+
int n2 = atoi(argv[2]);
18+
```
19+
20+
In order to allocate an array with a dimension defined by a variable, a dynamic array has to be allocated by means of the _malloc_ function:
21+
22+
```
23+
int *v1 = malloc(n1*sizeof(int));
24+
int *v2 = malloc(n2*sizeof(int));
25+
```
26+
27+
According to the given specification, the values accepted for the array elements are:
28+
29+
- file v1: even integers between 10 and 100 --> generate even integers from 0 to 90 then add 10
30+
- file v2: odd integers between 21 and 101 --> generate odd integers from 0 to 80 then add 21
31+
To sort the arrays just generated, the _qsort_ function of the C _stdlib_.
32+
33+
The _open()_ system call allows to both open and create, with specified permissions, files, returning an integer associated to the file descriptor. Our goal is to print to a text file the characters which relate to the integer from the array. To achieve this, we iterate over the array, pushing the values to a string by means of the _sprintf()_ call. This calls return the actual number of chars written, which is why it is used through the _j_ variable to determine the size of the buffer for the later _write()_ call. The _write()_ call finalizes the writing of the buffer into the text file, having as parameter the file descriptor, the buffer itself (the string previously generated with the _sprintf()_) and the size of the string, which is _j_ times the size of a character in bytes. This value will never exceed _n1*4 + 4_ (or _n2*4 + 4_), because the worst case possible is having n1 (or n2) times the value "100", which needs 3 characters as well as one character for a space to separate the values. The last 4 characters are added for CR.
34+
35+
In order to write a binary file, it is sufficient to call a _write()_ function on the binary file, writing the generating array (v1 or v2), which will have size of n1 (or n2) times the size of an integer.

Lab1/D01/E01_report.pdf

62.9 KB
Binary file not shown.

Lab1/D01/E01_text.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## E01 - C program for file generation
2+
3+
Implement a C program that:
4+
5+
- takes from the command line two integer numbers n1, n2,
6+
- allocates two vectors v1 and v2, of dimensions n1 and n2, respectively,
7+
- fills v1 with n1 random even integer numbers between 10-100,
8+
- fills v2 with n2 random odd integer numbers between 21-101,
9+
- sort v1 and v2 (increasing values),
10+
- save the content of vectors v1 and v2 in two text files fv1.txt and
11+
fv2.txt, respectively,
12+
- save the content of vectors v1 and v2 in two binary files fv1.b and
13+
fv2.b, respectively,
14+
Use command _od_ for verifying the content of files v1, v2.
15+
16+
_Standard ANSI C_
17+
```
18+
FILE *fpw; // file pointer
19+
if ((fpw = fopen (filename, "wb")) == NULL){ // w for write,
20+
b for binary
21+
fprinf(stderr," error open %s\n", filename);
22+
return(1);
23+
}
24+
fwrite(buffer,sizeof(buffer),1, fpw); // write sizeof(buffer)
25+
bytes from buffer
26+
```
27+
_Using Unix system calls_
28+
```
29+
#include <unistd.h>
30+
#include <fcntl.h>
31+
int fdo; // file descriptor
32+
if ((fdo = open(filename, O_WRONLY)) < 0){
33+
fprinf(stderr," error open %s\n", filename);
34+
return 1;
35+
}
36+
write(fdo, buffer, sizeof(buffer));
37+
```

Lab1/D01/E01_text.pdf

61.1 KB
Binary file not shown.

Lab1/D01/E02_text.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## E02 - Synchronization with semaphores
2+
3+
Implement a concurrent program in C language, using Pthreads, which creates two client
4+
threads, then it acts as a server.
5+
6+
A client thread loops reading the next number from the binary file (fv1.b and fv2.b,
7+
respectively), and storing it in a global variable g. Then, it performs a signals on a
8+
semaphore to indicate to the server that the variable is ready, and it waits on a semaphore
9+
a signal from the server indicating that the number has been processed (simply multiplied
10+
by 3), finally, it prints the result and its identifier.
11+
The server loops waiting the signal of the clients, doing the multiplication, storing the
12+
results on the same global variable g, and signalling to the client that the string is ready to
13+
be printed.
14+
15+
The main thread waits the end on the threads, and prints the total number of served
16+
requests.

Lab1/D02/E02.c

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include <pthread.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
#include <fcntl.h>
6+
#include <semaphore.h>
7+
#include <sys/syscall.h> //For syscall()
8+
#include <string.h> //For STRCAT
9+
10+
#define testPrintActivator 0 //Set to 1 if debug is wanted
11+
#define CHILDREN_NO 2
12+
13+
void *tF (void *myFDptr);
14+
15+
/* Section for the global variables*/
16+
int g;
17+
sem_t *s1, *s2, *s3;
18+
19+
int main(int argc, char* argv[]){
20+
int fd[CHILDREN_NO], requests = 0;
21+
// To check treads creation status
22+
long int rc;
23+
24+
// allocating semaphores
25+
s1 = (sem_t *) malloc(sizeof(sem_t));
26+
s2 = (sem_t *) malloc(sizeof(sem_t));
27+
s3 = (sem_t *) malloc(sizeof(sem_t));
28+
29+
// initializing semaphores
30+
if(sem_init(s1, 0, 1) == -1){
31+
fprintf(stderr, "ERROR init semaphore s1");
32+
}
33+
if(testPrintActivator > 0)printf("semaphore s1 initialized\n");
34+
if(sem_init(s2, 0, 0) == -1){
35+
fprintf(stderr, "ERROR init semaphore s2");
36+
}
37+
if(testPrintActivator > 0)printf("semaphore s2 initialized\n");
38+
if(sem_init(s3, 0, 0) == -1){
39+
fprintf(stderr, "ERROR init semaphore s3");
40+
}
41+
if(testPrintActivator > 0)printf("semaphore s3 initialized\n");
42+
43+
pthread_t tid[CHILDREN_NO];
44+
//test print
45+
if(testPrintActivator > 0)printf ("TEST before open files\n");
46+
47+
for (int i=0; i<CHILDREN_NO; i++){
48+
char path[] = "fv", path2[10];
49+
sprintf(path2,"%d", i+1);
50+
strcat(path2, ".b");
51+
strcat(path, path2); //Code for generating path
52+
if ((fd[i] = open(path, O_RDONLY)) <0) {
53+
fprintf(stderr, "error open %s\n", path);
54+
return -1;
55+
}
56+
}
57+
58+
//test print
59+
if(testPrintActivator > 0) printf ("TEST before pthread_create\n");
60+
// creating threads
61+
for (int i=0; i<CHILDREN_NO; i++){
62+
rc = pthread_create (&tid[i], NULL, tF, (void*) &fd[i]);
63+
if(rc) {
64+
fprintf(stderr,"ERROR: pthread_create() of thread %d with code %ld\n", i, rc );
65+
exit(-1);
66+
}
67+
}
68+
69+
int myChildCount = 0;
70+
do {
71+
sem_wait(s2);
72+
if (g==-1) myChildCount++;
73+
else {
74+
g *= 3;
75+
requests++;
76+
}
77+
sem_post(s3);
78+
} while (myChildCount<CHILDREN_NO);
79+
80+
printf("The number of served request is: %d\n", requests);
81+
/* Exit with no errors */
82+
return 0;
83+
}
84+
85+
void *tF (void* myFDptr){
86+
//test print
87+
if(testPrintActivator > 0) printf ("Loaded thread %d .\n", syscall(SYS_gettid));
88+
int number;
89+
int *myFDptr2 = (int*) myFDptr;
90+
int myFD = *myFDptr2;
91+
while (read(myFD, &number, sizeof(int))){
92+
sem_wait(s1);
93+
if(testPrintActivator > 0) printf("Thread %d has read %d\n", syscall(SYS_gettid), number);
94+
g = number;
95+
sem_post(s2);
96+
97+
sem_wait(s3);
98+
printf("Value %d from thread %d \n", g, syscall(SYS_gettid));
99+
sem_post(s1);
100+
}
101+
102+
sem_wait(s1);
103+
g = -1;
104+
sem_post(s2);
105+
sem_wait(s3);
106+
sem_post(s1);
107+
108+
//pthread_exit(NULL);
109+
}

Lab1/D02/E02_report.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SDP 2016/17 - Lab 1 - Davide Gallitelli S241521
2+
3+
### E02 - Synchronization with semaphores
4+
5+
The second part of the first lab aims at implementing a C server/client application by means of the _pthread_ library. Its purpose is to read the two binary files previously generated, fv1.b and fv2.b. Each time a value is read from a file by a thread and stored in the global variable _g_, the server multiplies that value by 3 and notifies the thread which wrote _g_ to print on the console.
6+
7+
In order to do so, three sempahores are to be used. The first one, sempahore s1, is the one that allows client threads to run. As only one thread is supposed to be running at a time, both threads wait on the same semaphore, which is initialized to 1 - only one can enter the critical section. The first CS generates the value for _g_ by reading the next int from the file descriptor specified as parameter of the thread until EOF is reached (_read()_ returns false, condition of the _while_ is not met). Once the value is read, the semaphore s2 signals the server to do its computation - multiplication by 3 - and increase its counter of requests served. The semaphore s3 allows the thread which just generated the value to print the new computation, and then unlock any other thread waiting for s1 semaphore.
8+
9+
The value _g = -1_ is used as reference value for the server to understand when the thread is done reading: the computation section of the server keeps running until all clients have processed their files - represented in the code by the counter _myChildCount_ being lower than the constant _CHILDREN\_NO_.
10+
11+
By using the _CHILDREN\_NO_ constant, this program is extremely versatile and allows for any number of clients to be launched, provided enough files (CHILDREN\_NO files, each named _fvX.b_, with X from 1 to _CHILDREN\_NO + 1_).

Lab1/D02/E02_report.pdf

29.5 KB
Binary file not shown.

Lab1/D02/E02_text.pdf

28.6 KB
Binary file not shown.

Lab1/desktop.ini

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[.ShellClassInfo]
2+
InfoTip=Questa cartella è condivisa online.
3+
IconFile=C:\Program Files (x86)\Google\Drive\googledrivesync.exe
4+
IconIndex=16
5+

0 commit comments

Comments
 (0)