Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
unix
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
tu-wien
unix
Commits
4d9c62cb
Commit
4d9c62cb
authored
Jan 12, 2019
by
Ivaylo Ivanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add documentation, signal handling, initial supervisor and semaphor functions
parent
0c024698
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
208 additions
and
13 deletions
+208
-13
fb_arc_set/generator.c
fb_arc_set/generator.c
+7
-0
fb_arc_set/shared/sem.c
fb_arc_set/shared/sem.c
+72
-2
fb_arc_set/shared/shm.c
fb_arc_set/shared/shm.c
+46
-1
fb_arc_set/shared/structs.c
fb_arc_set/shared/structs.c
+34
-4
fb_arc_set/supervisor.c
fb_arc_set/supervisor.c
+49
-6
No files found.
fb_arc_set/generator.c
View file @
4d9c62cb
...
@@ -38,6 +38,8 @@ int main(int argc, char *argv[]) {
...
@@ -38,6 +38,8 @@ int main(int argc, char *argv[]) {
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
process_signal
();
/// Create a regex to check the input against
/// Create a regex to check the input against
regex_t
regex
;
regex_t
regex
;
if
(
regcomp
(
&
regex
,
"^[0-9]*-[0-9]*$"
,
REG_EXTENDED
|
REG_NOSUB
))
{
if
(
regcomp
(
&
regex
,
"^[0-9]*-[0-9]*$"
,
REG_EXTENDED
|
REG_NOSUB
))
{
...
@@ -66,5 +68,10 @@ int main(int argc, char *argv[]) {
...
@@ -66,5 +68,10 @@ int main(int argc, char *argv[]) {
}
}
}
}
int
buffer_shmfd
=
create_shmfd
(
BUFF_SHM_NAME
);
circ_buffer
=
(
buffer_t
*
)
open_shm
(
buffer_shmfd
,
sizeof
(
buffer_t
));
int
wr_pos
=
0
;
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_SUCCESS
);
}
}
fb_arc_set/shared/sem.c
View file @
4d9c62cb
...
@@ -7,16 +7,25 @@
...
@@ -7,16 +7,25 @@
#include <unistd.h>
#include <unistd.h>
#endif
#endif
#include <errno.h>
#include <semaphore.h> ///< For semaphores
#include <semaphore.h> ///< For semaphores
#define FREE_SEM_NAME "/11777707_free"
#define FREE_SEM_NAME "/11777707_free"
#define USE
D
_SEM_NAME "/11777707_used"
#define USE_SEM_NAME "/11777707_used"
#define MUTEX_NAME "/11777707_mutex"
#define MUTEX_NAME "/11777707_mutex"
static
sem_t
*
free_sem
;
static
sem_t
*
free_sem
;
static
sem_t
*
use
d
_sem
;
static
sem_t
*
use_sem
;
static
sem_t
*
mutex
;
static
sem_t
*
mutex
;
/**
* @brief Function that executes sem_open(3) and does error handling.
* @details The function executes sem_open(3), giving it a semaphor name and size as parameters,
* and handles the errors if any. The same behaviour as sem_open(3) should be expected.
* Returns a new semaphore
* @param sem_name, sem_size
* @return res
**/
sem_t
*
open_sem
(
char
*
sem_name
,
size_t
sem_size
)
{
sem_t
*
open_sem
(
char
*
sem_name
,
size_t
sem_size
)
{
sem_t
*
res
=
sem_open
(
sem_name
,
O_CREAT
|
O_EXCL
,
0600
,
sem_size
);
sem_t
*
res
=
sem_open
(
sem_name
,
O_CREAT
|
O_EXCL
,
0600
,
sem_size
);
if
(
res
==
SEM_FAILED
)
{
if
(
res
==
SEM_FAILED
)
{
...
@@ -26,6 +35,60 @@ sem_t * open_sem(char *sem_name, size_t sem_size) {
...
@@ -26,6 +35,60 @@ sem_t * open_sem(char *sem_name, size_t sem_size) {
return
res
;
return
res
;
}
}
/**
* @brief Function that executes sem_getvalue(3) and does error handling.
* @details The function executes sem_getvalue(3), giving it a semaphor and size as parameters,
* and handles the errors if any. The same behaviour as sem_getvalue(3) should be expected.
* Writes the value of a semaphore to a chosen pointer
* @param sem, rem
* @return none
**/
void
getval_sem
(
sem_t
*
sem
,
int
*
res
)
{
if
(
sem_getvalue
(
sem
,
res
)
==
-
1
)
{
fprintf
(
stderr
,
"ERROR: Failed getting semaphore value
\n
"
);
exit
(
EXIT_FAILURE
);
}
}
/**
* @brief Function that executes sem_wait(3) and does error handling.
* @details The function executes sem_wait(3), giving it a semaphor as a parameter,
* and handles the errors if any. The same behaviour as sem_wait(3) should be expected.
* If the process was terminated, the function exits
* @param sem
* @return none
**/
void
wait_sem
(
sem_t
*
sem
)
{
if
(
sem_wait
(
sem
)
==
-
1
)
{
if
(
errno
==
EINTR
)
{
return
;
}
fprintf
(
stderr
,
"ERROR: Failed locking semaphore
\n
"
);
exit
(
EXIT_FAILURE
);
}
}
/**
* @brief Function that executes sem_post(3) and does error handling.
* @details The function executes sem_post(3), giving it a semaphor as a parameter,
* and handles the errors if any. The same behaviour as sem_post(3) should be expected.
* @param sem
* @return none
**/
void
post_sem
(
sem_t
*
sem
)
{
if
(
sem_post
(
sem
)
==
-
1
)
{
fprintf
(
stderr
,
"ERROR: Failed unlocking semaphore
\n
"
);
exit
(
EXIT_FAILURE
);
}
}
/**
* @brief Function that executes sem_close(3) and does error handling.
* @details The function executes sem_close(3), giving it a semaphor as a parameter,
* and handles the errors if any. The same behaviour as sem_close(3) should be expected.
* @param sem
* @return none
**/
void
close_sem
(
sem_t
*
sem
)
{
void
close_sem
(
sem_t
*
sem
)
{
if
(
sem_close
(
sem
)
<
0
)
{
if
(
sem_close
(
sem
)
<
0
)
{
fprintf
(
stderr
,
"ERROR: Failed closing semaphore
\n
"
);
fprintf
(
stderr
,
"ERROR: Failed closing semaphore
\n
"
);
...
@@ -33,6 +96,13 @@ void close_sem(sem_t *sem) {
...
@@ -33,6 +96,13 @@ void close_sem(sem_t *sem) {
}
}
}
}
/**
* @brief Function that executes sem_unlink(3) and does error handling.
* @details The function executes sem_unlink(3), giving it a semaphor name as a parameter,
* and handles the errors if any. The same behaviour as sem_unlink(3) should be expected.
* @param sem_name
* @return none
**/
void
destroy_sem
(
char
*
sem_name
)
{
void
destroy_sem
(
char
*
sem_name
)
{
if
(
sem_unlink
(
sem_name
)
<
0
)
{
if
(
sem_unlink
(
sem_name
)
<
0
)
{
fprintf
(
stderr
,
"ERROR: Failed closing semaphore
\n
"
);
fprintf
(
stderr
,
"ERROR: Failed closing semaphore
\n
"
);
...
...
fb_arc_set/shared/shm.c
View file @
4d9c62cb
...
@@ -11,8 +11,16 @@
...
@@ -11,8 +11,16 @@
#include <sys/mman.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/types.h>
#define BUFF
ER
_SHM_NAME "/11777707_buff"
#define BUFF_SHM_NAME "/11777707_buff"
/**
* @brief Function that executes shm_open(3) and does error handling.
* @details The function executes shm_open(3), giving it a name as a param,
* and handles the errors if any. The same behaviour as shm_open(3) should be expected.
* Returns a shared memory object file descriptor
* @param shm_name
* @return shmfd
**/
int
create_shmfd
(
char
*
shm_name
)
{
int
create_shmfd
(
char
*
shm_name
)
{
int
shmfd
=
shm_open
(
shm_name
,
O_RDWR
|
O_CREAT
,
0600
);
int
shmfd
=
shm_open
(
shm_name
,
O_RDWR
|
O_CREAT
,
0600
);
if
(
shmfd
==
-
1
)
{
if
(
shmfd
==
-
1
)
{
...
@@ -22,6 +30,13 @@ int create_shmfd(char *shm_name) {
...
@@ -22,6 +30,13 @@ int create_shmfd(char *shm_name) {
return
shmfd
;
return
shmfd
;
}
}
/**
* @brief Function that executes ftruncate(2) and does error handling.
* @details The function executes ftruncate(2), giving it a file descriptor and size as parameters,
* and handles the errors if any. The same behaviour as ftruncate(2) should be expected.
* @param shmfd, shm_size
* @return none
**/
void
truncate_shm
(
int
shmfd
,
size_t
shm_size
)
{
void
truncate_shm
(
int
shmfd
,
size_t
shm_size
)
{
if
(
ftruncate
(
shmfd
,
shm_size
)
<
0
)
{
if
(
ftruncate
(
shmfd
,
shm_size
)
<
0
)
{
fprintf
(
stderr
,
"ERROR: Failed truncating shared memory object
\n
"
);
fprintf
(
stderr
,
"ERROR: Failed truncating shared memory object
\n
"
);
...
@@ -29,6 +44,14 @@ void truncate_shm(int shmfd, size_t shm_size) {
...
@@ -29,6 +44,14 @@ void truncate_shm(int shmfd, size_t shm_size) {
}
}
}
}
/**
* @brief Function that executes mmap(2) and does error handling.
* @details The function executes mmap(2), giving it a file descriptor and size as parameters,
* and handles the errors if any. The same behaviour as mmap(2) should be expected.
* Returns a mapped shared memory object
* @param shmfd, shm_size
* @return shm
**/
void
*
open_shm
(
int
shmfd
,
size_t
shm_size
)
{
void
*
open_shm
(
int
shmfd
,
size_t
shm_size
)
{
void
*
shm
;
void
*
shm
;
shm
=
mmap
(
NULL
,
shm_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
shmfd
,
0
);
shm
=
mmap
(
NULL
,
shm_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
shmfd
,
0
);
...
@@ -41,10 +64,24 @@ void* open_shm(int shmfd, size_t shm_size) {
...
@@ -41,10 +64,24 @@ void* open_shm(int shmfd, size_t shm_size) {
return
shm
;
return
shm
;
}
}
/**
* @brief Function to write a value to shared memory object
* @details The functions copies the value of a string with a specified size to a shared memory object
* @param shm, message, message_size
* @return none
**/
void
write_to_shm
(
void
*
shm
,
char
*
message
,
size_t
message_size
)
{
void
write_to_shm
(
void
*
shm
,
char
*
message
,
size_t
message_size
)
{
memcpy
(
shm
,
message
,
message_size
);
memcpy
(
shm
,
message
,
message_size
);
}
}
/**
* @brief Function that executes munmap(2) and does error handling.
* @details The function executes munmap(2), giving it a shared memory object and size as parameters,
* and handles the errors if any. The same behaviour as munmap(2) should be expected.
* Returns a mapped shared memory object
* @param shmfd, shm_size
* @return none
**/
void
close_shm
(
void
*
shm
,
size_t
shm_size
)
{
void
close_shm
(
void
*
shm
,
size_t
shm_size
)
{
if
(
munmap
(
shm
,
shm_size
)
==
-
1
)
{
if
(
munmap
(
shm
,
shm_size
)
==
-
1
)
{
fprintf
(
stderr
,
"ERROR: Failed unmapping shared memory object
\n
"
);
fprintf
(
stderr
,
"ERROR: Failed unmapping shared memory object
\n
"
);
...
@@ -52,6 +89,14 @@ void close_shm(void* shm, size_t shm_size) {
...
@@ -52,6 +89,14 @@ void close_shm(void* shm, size_t shm_size) {
}
}
}
}
/**
* @brief Function that executes shm_unlink(3) and close(2) and does error handling.
* @details The function executes shm_unlink(3) and close(2), giving them a shared memory object name
* and a file descriptor respectively, and handles the errors if any.
* The same behaviour as shm_unlink(3) and close(2) should be expected.
* @param shm_name, shmfd
* @return none
**/
void
destroy_shm
(
char
*
shm_name
,
int
shmfd
)
{
void
destroy_shm
(
char
*
shm_name
,
int
shmfd
)
{
if
(
shm_unlink
(
shm_name
)
==
-
1
)
{
if
(
shm_unlink
(
shm_name
)
==
-
1
)
{
fprintf
(
stderr
,
"ERROR: Failed unlinking shared memory object
\n
"
);
fprintf
(
stderr
,
"ERROR: Failed unlinking shared memory object
\n
"
);
...
...
fb_arc_set/shared/structs.c
View file @
4d9c62cb
#include <stdbool.h> ///< For boolean constants
#include <stdbool.h> ///< For boolean constants
#include <signal.h>
#define BUFF_SIZE 8
#define BUFF_SIZE 8
#define SET_MAX_SIZE 8
#define SET_MAX_SIZE 8
...
@@ -9,15 +10,44 @@ typedef struct edge {
...
@@ -9,15 +10,44 @@ typedef struct edge {
}
edge_t
;
}
edge_t
;
/// Struct for the feedback arc set
/// Struct for the feedback arc set
typedef
struct
fb_set
{
typedef
struct
fb_
arc_
set
{
bool
valid
;
bool
valid
;
int
edge_num
;
edge_t
edges
[
SET_MAX_SIZE
];
edge_t
edges
[
SET_MAX_SIZE
];
}
fb_set_t
;
}
fb_
arc_
set_t
;
/// Struct for the circular buffer
/// Struct for the circular buffer
typedef
struct
buffer
{
typedef
struct
buffer
{
bool
terminate
;
bool
finished
;
fb_set_t
sets
[
BUFF_SIZE
];
short
best_arc_len
;
fb_arc_set_t
sets
[
BUFF_SIZE
];
}
buffer_t
;
}
buffer_t
;
static
bool
terminate
=
false
;
/**
* @brief Function to execute when the program gets a signal
* @details flips the terminate variable to true
* @param none
* @return none
**/
static
void
signal_handler
()
{
terminate
=
true
;
}
/**
* @brief Function to process the signals passed by the user
* @details creates a new sigaction structure
* and changes the behaviour of the SIGINT and SIGTERM signals
* @param none
* @return none
**/
static
void
process_signal
(
void
){
struct
sigaction
sa
;
memset
(
&
sa
,
0
,
sizeof
(
sa
));
sa
.
sa_handler
=
signal_handler
;
sigaction
(
SIGINT
,
&
sa
,
NULL
);
sigaction
(
SIGTERM
,
&
sa
,
NULL
);
}
static
buffer_t
*
circ_buffer
;
static
buffer_t
*
circ_buffer
;
fb_arc_set/supervisor.c
View file @
4d9c62cb
...
@@ -31,27 +31,70 @@ int main(int argc, char *argv[]) {
...
@@ -31,27 +31,70 @@ int main(int argc, char *argv[]) {
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
process_signal
();
/// Open shared memory objects
/// Open shared memory objects
int
buffer_shmfd
=
create_shmfd
(
BUFF
ER
_SHM_NAME
);
int
buffer_shmfd
=
create_shmfd
(
BUFF_SHM_NAME
);
truncate_shm
(
buffer_shmfd
,
BUFF_SIZE
);
truncate_shm
(
buffer_shmfd
,
BUFF_SIZE
);
circ_buffer
=
(
buffer_t
*
)
open_shm
(
buffer_shmfd
,
sizeof
(
buffer_t
));
circ_buffer
=
(
buffer_t
*
)
open_shm
(
buffer_shmfd
,
sizeof
(
buffer_t
));
/// Open semaphores
/// Open semaphores
free_sem
=
open_sem
(
FREE_SEM_NAME
,
BUFF_SIZE
);
free_sem
=
open_sem
(
FREE_SEM_NAME
,
BUFF_SIZE
);
used_sem
=
open_sem
(
USED_SEM_NAME
,
0
);
use_sem
=
open_sem
(
USE_SEM_NAME
,
0
);
mutex
=
open_sem
(
MUTEX_NAME
,
1
);
int
free_space
=
0
;
int
use_space
=
0
;
int
r_pos
=
0
;
///< Position of the circular buffer to read from
circ_buffer
->
best_arc_len
=
__INT8_MAX__
;
fb_arc_set_t
fb_arc
;
while
(
terminate
==
false
)
{
/// Get the values of the semaphores
getval_sem
(
free_sem
,
&
free_space
);
getval_sem
(
use_sem
,
&
use_space
);
wait_sem
(
use_sem
);
/// Loop until we find a place that has been written to
while
(
circ_buffer
->
sets
[
r_pos
].
valid
==
false
)
{
r_pos
=
(
r_pos
+
1
)
%
BUFF_SIZE
;
}
/// Get the valid set and save it
fb_arc
=
circ_buffer
->
sets
[
r_pos
];
circ_buffer
->
sets
[
r_pos
].
valid
=
false
;
post_sem
(
free_sem
);
///< Free the semaphore
r_pos
=
(
r_pos
+
1
)
%
BUFF_SIZE
;
///< Increase read position
if
(
fb_arc
.
edge_num
==
0
)
{
/// If the graph is acyclic, set the terminate flag
puts
(
"The graph is acyclic!"
);
signal_handler
();
}
else
if
(
fb_arc
.
edge_num
<
circ_buffer
->
best_arc_len
)
{
/// Save ther best feedback arc length and print a solution
circ_buffer
->
best_arc_len
=
fb_arc
.
edge_num
;
printf
(
"Solution with %d edges: "
,
circ_buffer
->
best_arc_len
);
for
(
int
i
=
0
;
i
<
fb_arc
.
edge_num
;
i
++
)
{
printf
(
"%d-%d "
,
fb_arc
.
edges
[
i
].
u
,
fb_arc
.
edges
[
i
].
v
);
}
printf
(
"
\n
"
);
}
}
/// Close and destory semaphores
/// Close and destory semaphores
close_sem
(
free_sem
);
close_sem
(
free_sem
);
close_sem
(
use
d
_sem
);
close_sem
(
use_sem
);
close_sem
(
mutex
);
close_sem
(
mutex
);
destroy_sem
(
FREE_SEM_NAME
);
destroy_sem
(
FREE_SEM_NAME
);
destroy_sem
(
USE
D
_SEM_NAME
);
destroy_sem
(
USE_SEM_NAME
);
destroy_sem
(
MUTEX_NAME
);
destroy_sem
(
MUTEX_NAME
);
/// Close and destroy shared memory objects
/// Close and destroy shared memory objects
close_shm
(
circ_buffer
,
sizeof
(
buffer_t
));
close_shm
(
circ_buffer
,
sizeof
(
buffer_t
));
destroy_shm
(
BUFFER_SHM_NAME
,
buffer_shmfd
);
destroy_shm
(
BUFF_SHM_NAME
,
buffer_shmfd
);
exit
(
EXIT_SUCCESS
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment