Commit 7b891e18 authored by Arnaud Blanchard's avatar Arnaud Blanchard
Browse files

If in quitting mode then quit before waiting for semaphores

parent e0117410
......@@ -33,7 +33,6 @@
#include "blc_tools.h"
#include "blc_program.h"
//Identical to argparse in Python
#define POSITIONAL_ARGUMENTS_TITLE "\npositional arguments:\n"
#define OPTIONAL_ARGUMENTS_TITLE "\noptional arguments:\n"
......@@ -49,7 +48,6 @@ typedef struct
void *user_data;
}blc_command;
// Static means it is only existing in this file
static blc_command *blc_commands = NULL;
static int blc_commands_nb = 0;
......@@ -65,8 +63,6 @@ void blc_loop_sem_to_unlock_on_stop(void *sem){
}
START_EXTERN_C
void blc_command_forward_blc_channels(){
forward_blc_channel=1;
}
......@@ -101,13 +97,11 @@ void blc_command_add(const char *command_name, type_blc_command_cb callback, con
tmp_command.help = help;
tmp_command.user_data = user_data;
FOR_INV(i, blc_commands_nb)
if (strcmp(blc_commands[i].name, command_name) == 0) EXIT_ON_ERROR("%s: command '%s' is already defined.", blc_program_id, command_name);
FOR_INV(i, blc_commands_nb) if (strcmp(blc_commands[i].name, command_name) == 0) EXIT_ON_ERROR("%s: command '%s' is already defined.", blc_program_id, command_name);
APPEND_ITEM(&blc_commands, &blc_commands_nb, &tmp_command);
}
void blc_command_remove(const char *command_name){
int i;
......@@ -127,9 +121,8 @@ void blc_command_interpret_string(char const *input_string, size_t size){
const blc_command *command;
size_t name_size, line_capability=0;
if (forward_blc_channel) {
if (strchr("./^:", input_string[0])) //it starts with ., ^ , / , :, it may be a blc_channel.
if (forward_blc_channel){
if (strchr("./^:", input_string[0])){ //it starts with ., ^ , / , :, it may be a blc_channel.
if (memchr(&input_string[1], '/', size)==0) // There is no / after the first char it is a blc_channel. NOTE: It may be an error with /usr /bin the user has to use /usr/ /bin/ etc.
{
......@@ -137,6 +130,7 @@ void blc_command_interpret_string(char const *input_string, size_t size){
SYSTEM_ERROR_CHECK(fflush(stdout), -1, NULL);
return;
}
}
}
FOR_EACH(command, blc_commands, blc_commands_nb){
......@@ -159,7 +153,7 @@ void blc_command_interpret_string(char const *input_string, size_t size){
}
else{
//A parameter was expected
if (command->prompt) {
if (command->prompt){
command->callback(parameter, command->user_data);
break;
}
......
......@@ -4,19 +4,18 @@
#include <unistd.h> //sleep
#include <errno.h> //errno
#include <math.h> //pthread_mutex
#include <time.h> //nanosleep
#include <sys/time.h> //gettimeofday
#include <pthread.h> //pthread_mutex
#include "blc_program.h"
struct timeval blc_loop_timer;
static uint blc_period=0;
static uint blc_duration=0;
static uint blc_duration_min=UINT_MAX, blc_duration_max=0;
static long blc_current_duration;
static int intermediate_iteration;
long blc_command_loop_period=-2; //unitialised
uint64_t blc_loop_iteration_limit=UINT64_MAX;
uint64_t blc_loop_iteration=0;
......@@ -39,12 +38,10 @@ static struct timeval step_timer, profile_timer;
static sem_t *blocking_semaphore=NULL;
#include "blc_program.h"
type_blc_status blc_status=BLC_RUN;
void blc_fprint_stats(FILE *file)
{
void blc_fprint_stats(FILE *file){
if (intermediate_iteration){
fprintf(file, "%-16.16s %4d iterations duration:%8.3fms[%8.3f, %8.3f] frequency:%8.3fHz period:%8.3fms\n", blc_program_id, intermediate_iteration, blc_duration/(1000.f*intermediate_iteration), blc_duration_min/1000., blc_duration_max/1000., 1e6*intermediate_iteration/(double)blc_period, blc_period/(1000.*intermediate_iteration));
intermediate_iteration=0;
......@@ -112,7 +109,6 @@ static void blc_command_send_to_all(char const *argument){
void blc_command_ask_quit(){
if (blc_status==BLC_PAUSE) BLC_PTHREAD_CHECK(pthread_mutex_unlock(&mutex_lock_keyboard), NULL);
if (blc_status!=BLC_STEPS) blc_status=BLC_QUIT;
if (blocking_semaphore){
......@@ -150,8 +146,7 @@ static void step_forward_cb(const char* steps_nb_str, void*){
blc_command_remove(">");
}
void pause_cb()
{
void pause_cb(){
if (blc_status==BLC_RUN || blc_status==BLC_STEPS){
blc_status=BLC_PAUSE;
blc_command_add(">", step_forward_cb, "|iterations", "continue for steps nb iterations", NULL);
......@@ -189,7 +184,7 @@ static void *loop_check_stuck(void*){
return NULL;
}
/// if the parameter is not null we should display the help at each command.
///If the parameter is not null we should display the help at each command.
static void *command_thread_interpret_loop(void *){
while(blc_status!=BLC_QUIT){
......@@ -205,6 +200,7 @@ void blc_command_loop_init(long loop_period){
intermediate_iteration=0;
blc_command_loop_period=loop_period;
//If blc_command_loop_period==2 we execute an iteration before stopping
if (blc_command_loop_period==-2){
blc_command_loop_period=-1;
}
......@@ -213,6 +209,7 @@ void blc_command_loop_init(long loop_period){
if (blc_input_terminal){
blc_command_display_help(); //We display help only for keyboard
}
if (blc_command_loop_period!=-1) blc_command_add("", (type_blc_command_cb)pause_cb, NULL, "set on/off pause", NULL);
blc_command_add("h", (type_blc_command_cb)blc_command_display_help, NULL, "display this help", NULL);
......@@ -230,10 +227,9 @@ void blc_command_loop_init(long loop_period){
}
int blc_command_loop_start(){
int continue_value;
int i;
if (blc_profile_file) gettimeofday(&profile_timer, NULL); //this is only for profiling
//We wait before counting the duration time as the time for waiting does not matter
......@@ -242,16 +238,19 @@ int blc_command_loop_start(){
pause_cb();
}
//We eventiualy wait for keyboard return key
//If we quit, we quit now before blockinhs semaphores.
if (blc_status==BLC_QUIT) return 0;
//We eventually wait for keyboard return key
if ((blc_status==BLC_PAUSE) || (blc_command_loop_period==-1)) BLC_PTHREAD_CHECK(pthread_mutex_lock(&mutex_lock_keyboard), NULL);
else if (blc_status==BLC_RUN){
//We wait for semaphore
FOR(i, waiting_semaphores_nb) {
blocking_semaphore=waiting_semaphores[i]; //This is used to be able to unlock all blocking semaphore on quiting
//We wait for semaphores
FOR(i, waiting_semaphores_nb){
blocking_semaphore=waiting_semaphores[i]; //This is used to be able to unlock all blocking semaphores on quiting
SYSTEM_ERROR_CHECK(sem_wait(blocking_semaphore), -1, NULL);
blocking_semaphore=NULL;
}
blocking_semaphore=NULL;
//Waiting general user defined callbacks
FOR(i, waiting_callbacks_nb) waiting_callbacks[i](waiting_callabacks_user_data[i]);
}
......
......@@ -477,7 +477,7 @@ void blc_program_init(int *argc, char ***argv, void (*exit_cb)(void))
blc_input_terminal=isatty(STDIN_FILENO);
blc_output_terminal=isatty(STDOUT_FILENO);
if (isatty(STDERR_FILENO) && blc_input_terminal) blc_stderr_ansi=1;
if (isatty(STDERR_FILENO)) blc_stderr_ansi=1;
else blc_stderr_ansi=0; //This is not waranty. It is safer to use blc_stderr_ansi_detect but it causes trouble when many program are launched at once
blc_program_add_option(&profile, '~', "profile", "filename", "profile the execution of the loop", NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment