Skip to content
Snippets Groups Projects
Commit 9c0b6f35 authored by ael-mess's avatar ael-mess
Browse files

removing ptask

parent c0902449
No related branches found
No related tags found
No related merge requests found
Showing
with 1 addition and 1976 deletions
No preview for this file type
build/
.vscode/
next
buildscript.sh
test/
\ No newline at end of file
* Version 0.2 beta
** Changes with respect to version 0.1
*** New ptask_init()
Now ptask_init() takes three parameters: the scheduling policy
(SCHED_FIFO, SCHED_RR or SCHED_OTHER), the global flag (PARTITIONED
or GLOBAL), and the semaphore protocol (PRIO_INHERITANCE or PRIO_CEILING).
*** Changes in the name of the types
Now ptime_t -> ptime
Now tspec_t -> tspec
**** *WARNING*
ptime is a common name, quite easy to come up with and use in
your program. Maybe it is better to go back and use ptime_t
again
*** wait_flag has been removed
Now, if you specify act_flag=ACT then the thread starts right away (as in
pthread). If you specify act_flag=NOACT, then the thread waits for an
explicit activation with the task_activate()
*** wait_for_period() has been substituted with wait_for_instance()
The latter is also valid for aperiodic tasks.
Now, a task (both periodic and aperiodic) has the same structure:
while (...) {
<task body>
wait_for_instance();
}
if the task is periodic, the wait_for_instance waits until the end of the
period; if it is aperiodic, the wait_for_instance() waits for an explicit
activate.
Function wait_for_activation() has been kept, and is simply blocks the
task on a private semaphore until the task is activated expliticely with
a task_activate(). This function can be invoked by both periodic and
aperiodic tasks without distinctions.
*** task_create() and task_create_ex() have been remaned
Now their name starts with ptask_ for uniformity of the interface.
*** removed the wcet related function
To measure wcet, use module tstat.h
** Known Issues
*** ball.c crashes on exit.
In particular, the allegro_exit() produces a core-dump. I still
do not know what is going on with that.
*** pcp.c sometimes crashes
Not clear why. Here is the error message:
> pcp: pthread_mutex_lock.c:459: __pthread_mutex_lock_full: Assertion `mutex->__data.__owner == 0' failed.
> Aborted (core dumped)
* Version 0.3
** Changes wrt to version 0.2
- Solved many bugs related to macros
- Changed the interface for ptask_param_add_mode()
** Known issues
Crashes on exit of pcp.c is still there.
cmake_minimum_required(VERSION 3.1)
project(ptask)
SET(CMAKE_C_FLAGS "-Wall")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
add_subdirectory(src)
add_subdirectory(examples)
enable_testing()
add_subdirectory(tests)
This diff is collapsed.
# ptask
Periodic Real-Time Task interface to pthreads
* Version 0.1, April 2013
* Version 0.2, August 2013
* Version 0.3, September 2015
* Version 0.4, July 2017
----
## Authors
* Giorgio Buttazzo (g.buttazzo@sssup.it)
* Giuseppe Lipari (g.lipari@sssup.it)
## Contributors
* Alessio Balsini (a.balsini@sssup.it)
* Alexandre Becart and Benoit Delecroix (integration SCHED_DEADLINE)
License: GPL 3.0
----
## Introduction
PTASK is a simple wrapper to the pthread library. It is intended for
real-time programmers that wish to control the timing behaviour and
the synchronisation of threads. It is intended to be minimalistic, yet
extensible to more complex usage scenarios.
Currently it provides:
- An API for implementing periodic and aperiodic tasks;
- A simple API for group scheduling and synchronization;
- An API for mode changes.
A manual is available in `docs/ptask_manual_x.x.pdf`.
----
## Instructions
### Prerequisites
* Allegro 4 libraries
* CMake 3.1+
### Compiling
To compile the library the first time, enter the main `ptask` folder
(from now identified with `ptask/`) and type:
```
$ mkdir build
$ cd build
$ cmake ..
$ make
```
this produces the library file `ptask/build/src/libptask.a`, that must be
included into your projects.
This also compiles all the:
* **examples** (`ptask/build/src/examples`);
* **tests** (`ptask/build/src/tests`).
To compile the examples, use the same procedure in directory
examples/. Before doing that, make sure you have already installed
the Allegro library, version 4 (http://liballeg.org/download.html). On
Ubuntu systems, you can install it with
```
sudo apt-get install liballegro4-dev
```
Once you compiled the sources, remember to become **super-user**,
otherwise Linux will not allow you to create real-time tasks!
To run the tests, execute the script
```
$ ptask/build/src/tests/runtest.sh
```
or, from the `ptask/build/` directory, run
```
$ sudo make test
```
Happy programming!
* Things to be done in the interface
** DONE Si possono mischiare PI e PC?
secondo noi no, succede casino.
Quindi
- si modifica la ptask_init() aggiungendo un parametro per
specificare il protocollo, PI o PC o SEM.
- Il semaforo interno per la struttura _tp_mutex va creato del
tipo giusto.
** DONE ptask_init()
Si aggiunge un ulteriore parametro GLOBAL, PARTITIONED
Se GLOBAL, si usa lo scheduler di Linux normalmente.
Se PARTITIONED, ogni volta che si crea un task, si setta l'affinità
a un processore (per default, 0)
** TODO la tspec_init deve essere invisibile
** TODO Alternative per il prefisso delle funzioni
- ptask_
- pt_
- task_
** DONE Tipi per il tempo
- ptime è un intero, senza unità
- internamente, per massima precisione, tspec
** TODO parametri di creazione del task
*** TODO Rimuovere:
- period
- priority
- wait_flag
*** DONE attivazione
o lo creo senza farlo partire per attivarlo successivamente
oppure lo creo facendolo partire immediatamente.
ACT --> IMMEDIATE (default)
NO_ACT --> DEFERRED
*** DONE periodico o aperiodico
unificare la wait_for_period() e la wait_for_activation(), adesso
solo la seconda che decide cosa fare a seconda del "tipo" del task
- nella struttura interna, devo avere un campo "tipo".
- posso impostare il tipo dinamicamente con una funzione set_type()
- alla creazione aggiungo un parametro nella funzione
int idx = task_create(body, tipo, periodo, priorità, other_params);
*** DONE parametri addizionali
seguire pthread, fare funzioni addizionali per cambiare i parametri
esempio:
pt_init_rdline(p, rd);
per i flag, aggiungere _flag in fondo al nome
*** TODO parametri dinamici
alcuni parametri si possono cambiare:
void pt_set_period(taskid, val);
void pt_set_priority(taskid, val);
e funzioni per ritornare il valore attuale
int pt_get_period(taskid);
int pt_get_priority(taskid);
** DONE struttura interna
- cancellare wcet e funzioni relative
** TODO deadline_miss
- aggiungere un flag nella struttura dati, che ci dice se l'ultima
istanza del task ha mancato la deadline.
- fare in modo che la funzione deadline_miss si possa chiamare solo
da dentro il task.
** TODO Task groups con offset
da fare
** TODO aperiodico che parte ad un certo istante preciso.
ptask_activate_at(taskid, abstime);
quando si sveglia dal semaforo, fa una clock_nanosleep() per vedere
cosa fare. (serve un ulteriore flag o qualcosa di simile nella task_struct)
** DONE Commentare bene i modi
** TODO add error codes
* Internal refactoring
** TODO move _tsem structure into _tp structure
(there is no reason to put them outside)
** TODO group all global sys params into a structure
(easier to document and to understand)
File deleted
File deleted
# Add include directory
include_directories(.)
include_directories(../src/)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_package(Allegro REQUIRED)
include_directories(${ALLEGRO_INCLUDE_DIR})
add_executable(ball ball.c)
add_executable(pbarr_example pbarr_example.c)
add_executable(modes modes.c)
add_executable(deadline_exception deadline_exception.c)
add_executable(pcp pcp.c)
target_link_libraries(ball lttng ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust) #mie
target_link_libraries(pbarr_example lttng ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust) #mie
target_link_libraries(modes lttng ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust) #mie
target_link_libraries(deadline_exception lttng ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust) #mie
target_link_libraries(pcp lttng ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust) #mie
file(COPY pcp.dat DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(activation_example)
add_subdirectory(advanced_act_test)
add_subdirectory(system_example)
# - Find allegro
# Find the native ALLEGRO includes and library
#
# ALLEGRO_INCLUDE_DIR - where to find allegro.h, etc.
# ALLEGRO_LIBRARIES - List of libraries when using allegro.
# ALLEGRO_FOUND - True if allegro found.
IF (ALLEGRO_INCLUDE_DIR)
# Already in cache, be silent
SET(ALLEGRO_FIND_QUIETLY TRUE)
ENDIF (ALLEGRO_INCLUDE_DIR)
FIND_PATH(ALLEGRO_INCLUDE_DIR allegro.h
/usr/local/include
/usr/include
$ENV{MINGDIR}/include
)
if(UNIX AND NOT CYGWIN)
exec_program(allegro-config ARGS --libs OUTPUT_VARIABLE ALLEGRO_LIBRARY)
else(UNIX AND NOT CYGWIN)
SET(ALLEGRO_NAMES alleg alleglib alleg41 alleg42 allegdll)
FIND_LIBRARY(ALLEGRO_LIBRARY
NAMES ${ALLEGRO_NAMES}
PATHS /usr/lib /usr/local/lib $ENV{MINGDIR}/lib)
endif(UNIX AND NOT CYGWIN)
IF (ALLEGRO_INCLUDE_DIR AND ALLEGRO_LIBRARY)
SET(ALLEGRO_FOUND TRUE)
SET( ALLEGRO_LIBRARIES ${ALLEGRO_LIBRARY} )
ELSE (ALLEGRO_INCLUDE_DIR AND ALLEGRO_LIBRARY)
SET(ALLEGRO_FOUND FALSE)
SET( ALLEGRO_LIBRARIES )
ENDIF (ALLEGRO_INCLUDE_DIR AND ALLEGRO_LIBRARY)
IF (ALLEGRO_FOUND)
IF (NOT ALLEGRO_FIND_QUIETLY)
MESSAGE(STATUS "Found Allegro: ${ALLEGRO_LIBRARY}")
ENDIF (NOT ALLEGRO_FIND_QUIETLY)
ELSE (ALLEGRO_FOUND)
IF (ALLEGRO_FIND_REQUIRED)
MESSAGE(STATUS "Looked for Allegro libraries named ${ALLEGRO_NAMES}.")
MESSAGE(FATAL_ERROR "Could NOT find Allegro library")
ENDIF (ALLEGRO_FIND_REQUIRED)
ENDIF (ALLEGRO_FOUND)
MARK_AS_ADVANCED(
ALLEGRO_LIBRARY
ALLEGRO_INCLUDE_DIR
)
\ No newline at end of file
# Add include directory
include_directories(.)
include_directories(../src/)
include_directories(${ALLEGRO_INCLUDE_DIR})
add_executable(activation_example animation.c graphics.c testTaskFun.c)
target_link_libraries(activation_example ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust)
#define _GNU_SOURCE
#include "testParameters.h"
#include "animation.h"
#include <stdbool.h>
#include <sched.h>
#include <pthread.h>
/*--------------------------------------------------------------*/
/* Periodic task */
/*--------------------------------------------------------------*/
void periodicLine_testSystemTask() {
int ox; /* old position */
int col; /* line color */
int offset = 0; /* offset from base0 and base 1*/
int unit = MILLI; /* unit of measurement for the time variables */
int i; /* index of task */
int x, y; /* coordinates of the ball */
char id[3]; /* string of index thread */
bool bloccato = false;
i = ptask_get_index();
ptime time_activation = ptask_gettime(unit);
col = 2 + i % 14;
offset = 20;
y= BASE + offset + (L * i * 3);
x = ox = XMIN;
snprintf(id, 3, "T%d", i+1);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, X_LINE_VERT1 + 5, Y_TIMES + i * ALT_RIGA, FGC, BGC, "%ld", time_activation);
textout_ex(screen, font, id, 5,y, FGC, 0);
pthread_mutex_unlock(&mxa);
while (x < XMAX) {
x = x + 10;
pthread_mutex_lock(&mxa);
rectfill(screen, ox, y+L, x, y, col);
pthread_mutex_unlock(&mxa);
ox = x;
ptask_wait_for_period();
if((x >= XMAX/2) && !bloccato) {
bloccato = true;
fprintf(stderr, "Sono il thread%d, mi sono bloccato!!!\n", i);
ptask_wait_for_activation();
time_activation = ptask_gettime(unit);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, X_LINE_VERT1 + 5, Y_TIMES + i * ALT_RIGA, FGC, BGC, "%ld", time_activation);
pthread_mutex_unlock(&mxa);
}
}
}
void periodicLine_testSystemTaskOFFSET() {
int i; /* index of task */
int x, y; /* coordinates of the ball */
int ox; /* old position */
int col; /* line color */
int offset = 0; /* offset from base0 and base 1 */
int unit = MILLI; /* unit of measurement for the time variables */
char id[3]; /* string of index thread */
ptime time_start = ptask_gettime(unit);
ptime offset_misurato;
i = ptask_get_index();
offset_misurato = time_start - time_t0;
fprintf(stderr, "---Thread%d: inizio l'esecuzione al time=%ldms!!!\n", i, time_start);
col = 2 + i % 14;
offset = 20;
y= BASE + offset + (L * i * 3);
x = ox = XMIN;
snprintf(id, 3, "T%d", i+1);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, X_LINE_VERT2 + 5, Y_TIMES + i * ALT_RIGA, FGC, BGC, "%ld", offset_misurato);
textprintf_ex(screen, font, X_LINE_VERT1 + 5, Y_TIMES + i * ALT_RIGA, FGC, BGC, "%ld", time_start);
textout_ex(screen, font, id, 5,y, FGC, 0);
pthread_mutex_unlock(&mxa);
while (x < XMAX) {
x = x + 10;
pthread_mutex_lock(&mxa);
rectfill(screen, ox, y+L, x, y, col);
pthread_mutex_unlock(&mxa);
ox = x;
ptask_wait_for_period();
}
}
void periodicLine_testSystemTask();
void periodicLine_testSystemTaskOFFSET();
#include "graphics.h"
const char* string_sched[] = {"SCHEDULER = OTHER", "SCHEDULER = FIFO", "SCHEDULER = RR"};
const char* string_prior[] = {"PRIORITY = ALL EQUAL", "PRIORITY = ALL DIFF.", "PRIORITY = CUSTOM"};
const char* string_part[] = {" -PARTITIONING = PARTITIONED- ", "-- PARTITIONING = GLOBAL --"};
const char* string_prot[] = {" PROTOCOL = PRIO_INHERITANCE", " PROTOCOL = PRIO_CEILING", " PROTOCOL = NO_PROTOCOL"};
const char* string_act_mode[] = {" ACTIV. MODE = NOW", " ACTIV. MODE = DEFERRED (with time offset)", " ACTIV. MODE = DEFERRED (no time offset)"};
#define MAX_STR_PROT strlen(string_prot[0])
#define MAX_STR_PART strlen(string_part[0])
/* s = scheduler, p = task's priority , tipo_test={0:SCHED,1:PART,2:PROT} */
void draw_system_info (int s, int part, int prot, int act_mode, int p, int tipo_test, bool verbose) {
int len_stringProt_Part = MAX_STR_PROT + MAX_STR_PART + 1;
int x, nc;
int col_prot ,col_sched, col_part, col_act_flag; //colors of various modes
int col_selected = 14; //selected color = YELLOW
col_prot = col_sched = col_part = FGC;
clear_to_color(screen, BGC);
/*rectangle for animation*/
rect(screen, XMIN-L-1, BASE-1, XMAX+L+1, TOP+L+1, FGC);
/*rectangle for tasks informations*/
rect(screen, XMIN-L-1, BASE1-1, XMAX+L+1, TOP1+L+10+1, FGC);
if(tipo_test == SCHED)
col_sched = col_selected;
else if (tipo_test == PART)
col_part = col_selected;
else if (tipo_test == PROT)
col_prot = col_selected;
else if (tipo_test == TASK_FUN) {
col_act_flag = col_selected;
textprintf_ex(screen, font, 2 + 50, 25, col_act_flag, BGC, "%s", string_act_mode[act_mode]);
}
/*draw system information ( protocol - partitioning)*/
textprintf_ex(screen, font, 2, 10, col_prot, BGC, "%s", string_prot[prot]);
textprintf_ex(screen, font, 2 + PIXEL_CHAR * MAX_STR_PROT, 10, col_part, BGC, "%s", string_part[part]);
x = len_stringProt_Part * PIXEL_CHAR;
textout_ex(screen, font, string_sched[s], x, 10, col_sched, 0);
nc = ptask_getnumcores();
textprintf_ex(screen, font, 2, 25, FGC, BGC, " NumCores = %d", nc);
textout_ex(screen, font, string_prior[p], x, 25, FGC, 0);
textout_ex(screen, font, "ACTIVATION SEQUENCE = ", XMIN, BASE1+10, FGC, 0);
if ( verbose ){
textout_ex(screen, font, " PRIORITY = ", XMIN, BASE1+20, FGC, 0);
textout_ex(screen, font, "TERMINATION SEQUENCE = ", XMIN, BASE1+30, FGC, 0);
}
textout_ex(screen, font, "KEY [1-9] to activate tasks (mod != MOD_DEF_OFFSET)", 5, YWIN-20, 10, 0);
textout_ex(screen, font, "ESC exit", XWIN-70, YWIN-20, 12, 0);
}
/* draw the identifier of the task activated */
void draw_activation (int numTActive, int idT, int prio, bool verbose){
char str_prio[3];
char str_id[3];
int x;
snprintf(str_id,3, "T%d", idT+1);
snprintf(str_prio,3, "%d", prio);
x = XMIN + ( (strlen("ACTIVATION SEQUENCE = ") + 1) * PIXEL_CHAR ) + ( 3 * numTActive ) * PIXEL_CHAR;
pthread_mutex_lock(&mxa);
textout_ex(screen, font, str_id, x, BASE1 + 10, FGC, 0);
if (verbose) textout_ex(screen, font, str_prio, x, BASE1 + 20, FGC, 0);
pthread_mutex_unlock(&mxa);
}
/* Draw time information about task activations and their start time and offset */
/* The time offset are time intervals from 'ptask_init(...)' to activation of tasks*/
// modeACT={MOD_NOW=0, MOD_DEF_OFFSET=1, MOD_DEF_NO_OFFS = 2}
void draw_Timetask_info(int modeACT) {
int i;
int y_inizio_vline = BASE1 + 3 * ALT_RIGA + ALT_MEZZARIGA;
vline(screen, X_LINE_VERT0, y_inizio_vline, YMAX1-10, FGC);
vline(screen, X_LINE_VERT1, y_inizio_vline, YMAX1-10, FGC);
vline(screen, X_LINE_VERT2, y_inizio_vline, YMAX1-10, FGC);
hline(screen, XMIN , Y_ORRIZ_LINE , XMAX -5, FGC);
if (modeACT == MOD_DEF_OFFSET) {
textout_ex(screen, font, "Time offset(ms) inseriti = ", XMIN, BASE1 + 2 * ALT_RIGA, FGC, 0);
}
textout_ex(screen, font, "TIME ACTIVATION(ms)", X_LINE_VERT0 + 5, Y_ORRIZ_LINE - ALT_RIGA, FGC, 0);
textout_ex(screen, font, "TIME START(ms)", X_LINE_VERT1 + 5, Y_ORRIZ_LINE - ALT_RIGA, FGC, 0);
textout_ex(screen, font, "TIME OFFSET measured(ms)", X_LINE_VERT2 + 5 , Y_ORRIZ_LINE - ALT_RIGA, FGC, 0);
for(i = 0; i < NUM_T_TEST; i++ ) {
textprintf_ex(screen, font, XMIN, Y_TIMES + i * ALT_RIGA,FGC, BGC, "T%d:", i+1);
}
}
void init_vett(int tipo , int* vett, int dim, int val) {
int i;
if(tipo == INIZIALIZED) {
for(i = 0; i < dim; i++) {
vett[i] = val;
}
}
else if(tipo == DIFFERENT){
for(i = 0; i < dim; i++) {
vett[i] = val-i;
}
}
}
/*type= {PRIO_EQUAL = 0: task with equal priority,
* PRIO_DIFF = 1: task with different priority,
* PRIO_CUSTOM= 2: task with customizable priority} */
void init_vettore_prio(int tipo, int* prio, int dim) {
int prioMAX = PRIO;
init_vett(tipo , prio, dim, prioMAX);
}
char *listboxAct_getter(int index, int *list_size) {
static char *strings[] = { "NOW", "DEFERRED with OFFSET", "DEFERRED without OFFSET" };
if (index < 0) {
*list_size = 3;
return NULL;
}
else
return strings[index];
}
/* Dialog used to select the mode activation of tasks */
DIALOG taskFunction_dialog[(9 + NUM_T_TEST * 2)] =
{
/* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
/* First object used for clear the screen */
{ d_clear_proc, 0, 0, 0, 0, FGC, BGC, 0, 0, 0, 0, NULL, NULL, NULL },
/* program title */
{ d_ctext_proc, XWIN/2-150, 30, 300, 50, 14, BGC, 0, 0, 0, 0,"----- TASK FUNCTION TEST -----", NULL, NULL },
{ d_box_proc, 20, YWIN/2-80, 600, 50, FGC, BGC, 0, 0, 0, 0, NULL, NULL, NULL },
{ d_text_proc, XMIN, YWIN/2-60, 80, 20, FGC, BGC, 0, 0, 0, 0, "ACTIVATION FLAG setting", NULL, NULL },
{ d_list_proc, XWIN/2+50, YWIN/2-70, 200, 30, FGC, 0, 0, 0, 0, 0, listboxAct_getter, NULL, NULL },
{ d_button_proc, 80, YWIN-80, 161, 49, 10, 0, 0, D_EXIT, 0, 0, "OK", NULL, NULL },
{ d_button_proc, XWIN-280, YWIN-80, 161, 49, 12, 0, 0, D_EXIT, 0, 0, "EXIT", NULL, NULL },
{ d_box_proc, 20, YWIN/2 -30, 600, 50, FGC, BGC, 0, D_HIDDEN, 0, 0, NULL, NULL, NULL },
/* Final object */
{ NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
};
/* Final object*/
DIALOG d_final = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL };
int control_bound_value(int val, bool* error_found, const char* name_value, int upper_bound) {
const char* mess1 = "Hai inserito un numero di ";
const char* mess2 = " troppo alto!!!";
int len = strlen(mess1) + strlen(name_value) + strlen(mess2) + 1;
char mess_alert[len];
snprintf(mess_alert, len, "%s%s%s", mess1, name_value, mess2);
if(!(*error_found) && ((val > upper_bound) || (val < 0))) {
alert(mess_alert, NULL, NULL, "OK", NULL, 0, 0);
*error_found = true;
return 0;
}
else return -1;
}
/* Errors checking on edit fields */
bool error_edit(char* string, const char* name_value, char* endptr, int val, int upper_bound) {
char* error2 = "errore conversione in long(strtol)!!!\n";
char* error3_4 = "Presenti lettere o simboli nei valori immessi!!!\n";
bool error_found = false;
char* tmp2, *tmp3;
tmp2 = tmp3 = NULL;
errno = 0; /* To distinguish success/failure after call */
/* Checking errors*/
bool cond_error1 = ((val == INT_MAX) || (val == INT_MIN));
bool cond_error2 = (errno == ERANGE && cond_error1) || (errno != 0 && (val == 0));
bool cond_error3 = (endptr == string);
bool cond_error4 = (*endptr != '\0');
if(cond_error1 || cond_error2 || cond_error3 || cond_error4) {
error_found = true;
if (cond_error2) {
perror(error2);
}
if (cond_error2 || cond_error3 || cond_error4) {
tmp3 = error3_4;
alert(tmp2, tmp3, NULL, "OK", NULL, 0, 0);
}
}
control_bound_value(val, &error_found, name_value, upper_bound);
return error_found;
}
void activate_offset_box (int var){
int i;
for(i = 7; i <= (NUM_T_TEST * 2 + 7); i++) {
taskFunction_dialog[i].flags = D_DIRTY;
if ( var==ON ) taskFunction_dialog[i].fg = FGC;
else if ( var==OFF ) taskFunction_dialog[i].fg = 0;
}
}
/* It draws dinamically the offset's field */
void update_dialogAct (char textOffset[NUM_T_TEST][W_TEXT_OFFSET+1], char editOffset[NUM_T_TEST][NUM_CIF_OFFSET+1]){
int i, j;
int offset = 0;
int default_offset = 10000;
int sum_offset = 0;
for(i = 0; i < NUM_T_TEST; i++) {
snprintf(textOffset[i], W_TEXT_OFFSET + 1, "Offs%d:", i + 1);
snprintf(editOffset[i], NUM_CIF_OFFSET + 1, "%d", sum_offset);
sum_offset += default_offset;
}
/* Temporary dialog */
DIALOG d7 = taskFunction_dialog[7]; // 'hidden' box
//general structure: proc, x, y, w, h, fg, bg, key, flags, d1, d2, dp, dp2, NULL
DIALOG d_temp_text = { d_text_proc, XMIN, d7.y + (d7.h)/2,
W_TEXT_OFFSET * PIXEL_CHAR, /*weight text in pixel 72*/
20, FGC, BGC, 0, 0, 0, 0, "Offs0:" , NULL, NULL
};
DIALOG d_temp_edit = { d_edit_proc, XMIN + d_temp_text.w , d7.y + (d7.h)/2,
(NUM_CIF_OFFSET + 1) * PIXEL_CHAR, //W_EDIT_PRIO * PIXEL_CHAR,
20, FGC, BGC, 0, 0, NUM_CIF_OFFSET, 0, editOffset[0], NULL, NULL
};
for(i = 0; i < NUM_T_TEST; i++) {
j = 8 + i * 2;
/* TEXT FIELD Priority (ex. p0:)*/
taskFunction_dialog[j] = d_temp_text;
taskFunction_dialog[j].x = XMIN + i * ( d_temp_text.w + d_temp_edit.w + offset) ;
//snprintf(sched_dialog[j].dp, lun_text_prio, "P%d:", i);
taskFunction_dialog[j].dp = textOffset[i];
taskFunction_dialog[j].flags = D_HIDDEN; //D_DIRTY;
/* EDIT FIELD */
j++;
taskFunction_dialog[j] = d_temp_edit;
taskFunction_dialog[j].x = taskFunction_dialog[j-1].x + d_temp_text.w;
taskFunction_dialog[j].dp = editOffset[i];
taskFunction_dialog[j].flags = D_HIDDEN; //D_DIRTY;
}
/*Final object*/
taskFunction_dialog[8 + (NUM_T_TEST) * 2] = d_final;
}
/* Function to select type of activation mode */
int select_act(ptime* v_offset, int numTask) {
int i, id, ret, mode;
int val;
bool box_offset_active = false;
char* endptr;
char text_offset[NUM_T_TEST][W_TEXT_OFFSET+1]; //all strings OFFSET "Px" (ex.text_offset[0]="Offs0:")
char edit_offset[NUM_T_TEST][NUM_CIF_OFFSET+1]; //all strings of edit fields
/* add editable fields (offset) to dialog */
update_dialogAct (text_offset, edit_offset);
show_mouse(screen);
DIALOG_PLAYER *player = init_dialog(taskFunction_dialog, -1);
while (update_dialog(player)) {
/* reading activation mod (NOW, DEF offset, DEFFERED no offset)*/
mode = taskFunction_dialog[4].d1;
if(mode == MOD_DEF_OFFSET && !box_offset_active) {
box_offset_active = true;
/* it makes offset's box visible and active */
activate_offset_box (ON);
}
if( mode != MOD_DEF_OFFSET && box_offset_active ) {
box_offset_active = false;
/* it makes offset's box invisible and inactive */
activate_offset_box (OFF);
}
if( mode == MOD_DEF_OFFSET) {
/* index of object get focus */
id = find_dialog_focus(taskFunction_dialog);
/* ex.: if tasks are 5, the index of editable fields to checking are 12 14 16 18 20:
* we dont'check editable field that get focus*/
for(i = 9; i <= (NUM_T_TEST * 2 + 7) && i != id; i = i + 2) {
val = strtol(taskFunction_dialog[i].dp, &endptr, 10);
if (error_edit (taskFunction_dialog[i].dp, "offset", endptr, val, OFFSET_MAX)) {
snprintf (taskFunction_dialog[i].dp, NUM_CIF_OFFSET + 1, "%d", OFFSET_MAX);
taskFunction_dialog[i].flags = D_DIRTY;
}
}
}
}
ret = shutdown_dialog(player);
scare_mouse();
for(i = 0; i < NUM_T_TEST; i++) {
v_offset[i] = strtol(edit_offset[i], &endptr, 10);
}
if (ret == 6 || ret < 0)
return -1;
else {
return mode;
}
}
#include "testParameters.h"
#include <stdbool.h>
#include <string.h>
void draw_system_info(int s, int part, int prot, int act_mode, int p,
int tipo_test, bool verbose);
/* draw the identifier of the task activated */
void draw_activation(int numTActive, int idT, int prio, bool verbose);
/* Draw time information about task activations and their start time and offset
*/
/* The time offset are time intervals from 'ptask_init(...)' to activation of
* tasks*/
// modeACT={MOD_NOW=0, MOD_DEF_OFFSET=1, MOD_DEF_NO_OFFS = 2}
void draw_Timetask_info(int modeACT);
void init_vett(int tipo, int *vett, int dim, int val);
/*type= {PRIO_EQUAL = 0: task with equal priority,
* PRIO_DIFF = 1: task with different priority,
* PRIO_CUSTOM= 2: task with customizable priority} */
void init_vettore_prio(int tipo, int *prio, int dim);
/* Errors checking on edit fields */
int control_bound_value(int val, bool *error_found, const char *name_value,
int upper_bound);
/* Errors checking on edit fields */
bool error_edit(char *string, const char *name_value, char *endptr, int val,
int upper_bound);
/* Function to select type of activation mode */
int select_act(ptime *v_offset, int numTask);
#include <allegro.h>
#include <math.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pmutex.h"
#include "ptask.h"
#include "tstat.h"
#define XWIN 640
#define YWIN 480
#define BGC 0 /* background color */
#define FGC 15 /* foreground color */
#define L 5 /* dimension of a ball or hight line */
#define NUM_T_TEST 3
#define INIZIALIZED 0
#define DIFFERENT 1
#define NUM_CIF_OFFSET 6 // offset (usually in ms)
#define W_EDIT_OFFSET 2 + NUM_CIF_OFFSET
#define W_TEXT_OFFSET 6 // "OffsXX: "
#define PIXEL_CHAR 8
#define ON 1
#define OFF 0
#define OFFSET_MAX 60000
#define PRIO_EQUAL 0 /* Modes of priority */
#define PRIO_DIFF 1
#define PRIO_CUSTOM 2
#define OFFSET_EQUAL 0 /* Modes of OFFSET */
#define OFFSET_DIFF 1
#define OFFSET_CUSTOM 2
#define MOD_NOW 0
#define MOD_DEF_OFFSET 1
#define MOD_DEF_NO_OFFS 2
#define SCHED 0 /* Types of test */
#define PART 1
#define PROT 2
#define TASK_FUN 3
#define BASE 60 /* position of the floor */
#define TOP BASE + 15 * NUM_T_TEST + 20 /* initial height of the ball */
#define BASE1 TOP + 25
#define TOP1 BASE1 + 15 * NUM_T_TEST + 40
#define XMIN 40 /* min position X of the ball */
#define XMAX 600 /* max position Y of the ball */
/* Parameters for draw times of the functions task*/
#define YMAX1 TOP1 + L + 10 + 1
#define ALT_RIGA 10 /* height row in pixels */
#define ALT_MEZZARIGA ALT_RIGA / 2 /* height row/2 in pixels */
#define X_LINE_VERT0 XMIN + 25 /* coordinats x of first vertical line */
#define X_LINE_VERT1 \
(((0.0f + XMAX) - (0.0f + XMIN)) / (3)) + \
XMIN /* coordinats x of second vertical line */
#define X_LINE_VERT2 \
(X_LINE_VERT1 - XMIN) * 2 + XMIN /* coordinats x of third vertical line */
#define Y_ORRIZ_LINE BASE1 + 5 * ALT_RIGA /* height of horrizontal line */
#define Y_TIMES Y_ORRIZ_LINE + ALT_MEZZARIGA
#define PER 100 /* task period in ms */
#define DREL 100 /* realtive deadline in ms */
#define PRIO 80 /* task priority */
ptime time_t0; /* Time reference for timeoffset (from ptask_init(...))*/
/* *************************************************************************************************
*/
/* mutual exclusion semaphores */
pthread_mutex_t mxa; // = PTHREAD_MUTEX_INITIALIZER;
#include <stdbool.h>
#include <string.h>
#include "animation.h"
#include "graphics.h"
#include "testParameters.h"
void init() {
allegro_init();
/* Initializes this library */
tspec_init();
set_gfx_mode(GFX_AUTODETECT_WINDOWED, XWIN, YWIN, 0, 0);
clear_to_color(screen, BGC);
install_keyboard();
install_mouse();
srand(time(NULL));
/* semaphore to write on the screen */
pmux_create_pi(&mxa);
}
/*--------------------------------------------------------------*/
/* MAIN process */
/*--------------------------------------------------------------*/
int main(void)
{
int unit = MILLI;
int i, id, k;
int c; /* character from keyboard */
int ntasks = 0; /* total number of activated tasks*/
int ret = 0;
int tipo_prio = PRIO_EQUAL;
int sched = SCHED_RR;
int part = GLOBAL;
int prot = NO_PROTOCOL;
int test = TASK_FUN;
int modeACT = MOD_NOW; /* {MOD_NOW=0, MOD_DEF_OFFSET=1, MOD_DEF_NO_OFFS = 2} */
int act_flag = NOW;
init();
int num_tasks = NUM_T_TEST;
int priority[num_tasks];
ptime v_offset[num_tasks]; /* time offset vector */
for(i = 0; i < num_tasks; i++) v_offset[i] = 0;
modeACT = select_act (v_offset, num_tasks); // {MOD_NOW=0, MOD_DEF_OFFSET=1, MOD_DEF_NO_OFFS = 2}
if ( modeACT == -1 ) {
allegro_exit();
return 0;
}
ptask_init(sched, part, prot);
/* Time reference for timeoffset */
time_t0 = ptask_gettime(MILLI);
ptime time_tmp;
if(modeACT == 0) { // {MOD_NOW=0, MOD_DEF_OFFSET=1, MOD_DEF_NO_OFFS = 2}
act_flag = NOW;
}
else {
act_flag = DEFERRED;
}
init_vettore_prio(tipo_prio, priority, num_tasks);
draw_system_info(sched, part, prot, modeACT, tipo_prio, test, false);
draw_Timetask_info(modeACT);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, 2, 25 + 15, FGC, BGC, " Time reference t0 = %ld (time creation/visualization of this screen)", time_t0);
pthread_mutex_unlock(&mxa);
const char* str_offset = "Time offset(ms) inseriti = ";
/* Creation of aperiodic task */
for ( i = 0; i < num_tasks; i++) {
if (modeACT != MOD_DEF_OFFSET) {
/* MODE WITHOUT OFFSET */
time_tmp = ptask_gettime(MILLI);
if(act_flag == NOW) {
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, X_LINE_VERT0 + 5, Y_TIMES + i * ALT_RIGA, FGC, BGC, "%ld ", time_tmp);
pthread_mutex_unlock(&mxa);
}
id = ptask_create_prio(periodicLine_testSystemTask, PER, priority[i], act_flag);
}
else {
/* MODE WITH OFFSET */
time_tmp = ptask_gettime(MILLI);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, (X_LINE_VERT0 + X_LINE_VERT1)/2, Y_TIMES + i * ALT_RIGA, FGC, BGC, "-");
pthread_mutex_unlock(&mxa);
id = ptask_create_prio(periodicLine_testSystemTaskOFFSET, PER, priority[i], act_flag);
printf("act_flag = %d, id = %d, v_offset[%d] = %ld\n", act_flag, id+1, id, v_offset[id]);
ret = ptask_activate_at(id, v_offset[i], MILLI);
if (ret != -1) {
draw_activation (ntasks, i, priority[i], false);
ntasks++;
if (i == 0) {
pthread_mutex_lock(&mxa);
textout_ex(screen, font, str_offset, XMIN, BASE1 + 2 * ALT_RIGA, FGC, 0);
pthread_mutex_unlock(&mxa);
}
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, XMIN + (strlen(str_offset)+i*(NUM_CIF_OFFSET))*PIXEL_CHAR, BASE1 + 2 * ALT_RIGA,FGC, BGC, "%ld", v_offset[i]);
pthread_mutex_unlock(&mxa);
}
else fprintf(stderr, "Task %d non può essere attivato o già avviato!!!\n", i+1);
}
if (id != -1) {
char* temp = " e attivato!\n";
if(act_flag == DEFERRED) {
temp = "!\n";
}
printf("Task %d creato%s", id+1, temp);
}
else {
allegro_exit();
printf("Errore nella creazione(o anche attivazione NOW) del task!\n");
exit(-1);
}
}
do {
k = 0;
if (keypressed()) {
c = readkey();
k = c >> 8;
}
if ((k >= KEY_1) && (k <= KEY_0 + num_tasks) && (modeACT != MOD_DEF_OFFSET)) {
id = k - KEY_0 - 1;
time_tmp = ptask_gettime(unit);
ret = ptask_activate(id);
if (ret != -1) {
printf("Task %d attivato\n", id);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, X_LINE_VERT0 + 5, Y_TIMES + (id) * ALT_RIGA,
FGC, BGC, "%ld ", time_tmp);
pthread_mutex_unlock(&mxa);
draw_activation (ntasks, id, priority[id], false);
ntasks++;
}
else{
printf("Task %d non può essere attivato o già avviato!!!\n", id);
pthread_mutex_lock(&mxa);
textprintf_ex(screen, font, X_LINE_VERT0 + 5, Y_TIMES + id * ALT_RIGA,FGC, BGC, "T%d: Gia' attivo! ", id);
pthread_mutex_unlock(&mxa);
}
}
} while (k != KEY_ESC);
allegro_exit();
return 0;
}
END_OF_MAIN()
/*--------------------------------------------------------------*/
# Add include directory
include_directories(.)
include_directories(../src/)
include_directories(${ALLEGRO_INCLUDE_DIR})
add_executable(advanced_act_test animation.c graphics.c testParam.c)
target_link_libraries(advanced_act_test ptask Threads::Threads ${ALLEGRO_LIBRARY} m rt dl lttng-ust)
file(COPY param.dat DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
#define _GNU_SOURCE
#include "animation.h"
#include "testParameters.h"
#include <pthread.h>
#include <sched.h>
#include <stdbool.h>
#include <sys/resource.h>
#include <sys/time.h>
void draw_ball(int x, int y, int c) { circlefill(screen, x, y, L, c); }
void print_id_task(int id, int x, int y, int color) {
textprintf_ex(screen, font, x, y, color, BGC, "T%d", id);
}
void periodicBall_testParam() {
int i, j = 0;
int dcol = BGC;
int *pun_col;
int color;
int x, ox, xStart;
int y, oy;
float vel = VELX;
float tx = 0.0, dt;
i = ptask_get_index();
pun_col = ptask_get_argument();
color = *pun_col;
x = ox = xStart = XMIN;
y = oy = BASE - 1 + 20 + (i * 4 * L);
dt = ptask_get_period(i, MILLI) / 100.;
/* print task's id on screen on the right of task animation */
pthread_mutex_lock(&mxa);
print_id_task(i, 5, y, color);
pthread_mutex_unlock(&mxa);
sample[i] = 0;
while (1) {
/* update position x of the ball */
x = xStart + vel * tx;
if (x > XMAX) {
tx = 0.0;
xStart = XMAX;
vel = -vel;
x = xStart;
}
if (x < XMIN) {
tx = 0.0;
xStart = XMIN;
vel = -vel;
x = xStart;
}
pthread_mutex_lock(&mxa);
draw_ball(ox, y, BGC);
draw_ball(x, y, color);
pthread_mutex_unlock(&mxa);
dt = ptask_get_period(i, MILLI) / 100.;
tx += dt;
ox = x;
if (ptask_deadline_miss()) {
/* draw with a different color a circle that represent deadline miss
*/
dcol = (dcol + 1) % 15;
pthread_mutex_lock(&mxa);
draw_ball(XMAX + 15, y, dcol);
pthread_mutex_unlock(&mxa);
}
ptask_wait_for_period();
/* get sample of start time and next_activation time (not more than
* MAX_SAMPLE)*/
if (j < MAX_SAMPLE) {
start_time[i][j] = ptask_gettime(MILLI);
v_next_at[i][j] = ptask_get_nextactivation(MILLI);
sample[i]++;
j++;
}
}
}
void periodicBall_testParamDEP_PER() {
int i, j = 0;
int dcol = BGC;
int *pun_col;
int color;
int x, ox, xStart;
int y, oy;
float vel = VELX;
float tx = 0.0;
float dt = 20.0 / 100.0; /* dt is constant */
i = ptask_get_index();
pun_col = ptask_get_argument();
color = *pun_col;
x = ox = xStart = XMIN;
y = oy = BASE - 1 + 20 + (i * 4 * L);
/* print task's id on screen on the right of task animation */
pthread_mutex_lock(&mxa);
print_id_task(i, 5, y, color);
pthread_mutex_unlock(&mxa);
sample[i] = 0;
while (1) {
/* update position x of the ball */
x = xStart + vel * tx;
if (x > XMAX) {
tx = 0.0;
xStart = XMAX;
vel = -vel;
x = xStart;
}
if (x < XMIN) {
tx = 0.0;
xStart = XMIN;
vel = -vel;
x = xStart;
}
pthread_mutex_lock(&mxa);
draw_ball(ox, y, BGC);
draw_ball(x, y, color);
pthread_mutex_unlock(&mxa);
tx += dt;
ox = x;
if (ptask_deadline_miss()) {
/* draw with a different color a circle that represent deadline miss
*/
dcol = (dcol + 1) % 15;
pthread_mutex_lock(&mxa);
draw_ball(XMAX + 15, y, dcol);
pthread_mutex_unlock(&mxa);
}
ptask_wait_for_period();
/* get sample of start time and next_activation time (not more than
* MAX_SAMPLE)*/
if (j < MAX_SAMPLE) {
start_time[i][j] = ptask_gettime(MILLI);
v_next_at[i][j] = ptask_get_nextactivation(MILLI);
sample[i]++;
j++;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment