Commit 7aa0c12a authored by Mattia Bondanza's avatar Mattia Bondanza

Prima versione. Sembra funzonare; interfaccia carina per seguirne il...

Prima versione. Sembra funzonare; interfaccia carina per seguirne il funzionamento. La funzione di test fa una serie di operazioni casuali per verificare che non scazzi.
parents
File added
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#define INBUF_DIMENSION 40
#define LOG_LEN 40
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
#define ANSI_COLOR_BLUE "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN "\x1b[36m"
#define ANSI_COLOR_RESET "\x1b[0m"
#define ANSI_COLOR_BRIGHT_WHITE "\x1b[37;1m"
#define ANSI_COLOR_WHITE "\x1b[37;0m"
typedef int inbuf_element;
typedef struct __inbuf{
inbuf_element ring[ INBUF_DIMENSION ];
int wr;
int rd;
} inbuf;
typedef inbuf *inbufPrt;
void inbuf_init( inbufPrt buf ){
for( int j = 0; j < INBUF_DIMENSION; j++ )
buf->ring[j] = 0;
buf->wr = 0;
buf->rd = 0;
return;
}
void inbuf_push( inbuf_element val, inbufPrt buf ){
buf->ring[ buf->wr ] = val;
if( buf->wr == INBUF_DIMENSION - 1 ){
//Se ho raggiunto la fine del buffer...
if( buf->rd != 0 ){
//Se ho un elemento libero ripartendo dall'inizio...
buf->wr = 0;
}
}
else{
if( buf->wr + 1 != buf->rd )
//Se il successivo elemento è libero lo scirve
buf->wr++;
}
}
inbuf_element inbuf_pull( inbufPrt buf ){
//Legge il successivo elemento della FIFO
inbuf_element val = buf->ring[ buf->rd ];
//Porta il puntatore di lettura al successivo elemento della FIFO
if( buf->rd != buf->wr ){
//Se i due puntatori non coincidono hai ancora elementi da leggere
buf->rd++;
if( buf->rd == INBUF_DIMENSION )
buf->rd = 0;
return val;
}
else
return -1;
}
int isread( int j, inbufPrt buf ){
if( buf->wr < buf->rd )
if( j >= buf->rd || j <= buf->wr ) return 0;
else return 1;
else
if( j >= buf->rd && j < buf->wr ) return 0;
return 1;
}
unsigned char inbuf_usage( inbufPrt buf ){
if( buf->rd > buf->wr )
return INBUF_DIMENSION - buf->rd + buf->wr;
return buf->wr - buf->rd;
}
//**********************************************************
//*******************TESTING FUNCTIONS**********************
//**********************************************************
char slog[LOG_LEN][1024];
int log_cnt = 0;
void mini_log_print( void ){
printf("\n\n************** LOG **************\n\n");
for( unsigned char i = 0; i < log_cnt; i++ )
printf("%s", slog[i]);
return;
}
void add_log_str( char *str ){
if( log_cnt < LOG_LEN )
strcpy( slog[ log_cnt++ ], str );
else{
for( unsigned char i = 0; i < LOG_LEN - 1; i++ )
strcpy( slog[ i ], slog [ i+1 ] );
strcpy( slog[ LOG_LEN - 1], str );
}
}
void print_inbuf( inbufPrt buf ){
printf(ANSI_COLOR_BLUE);
printf("RD:\t ");
for( unsigned char j = 0; j < buf->rd * 4; j++ ) putchar(' '); printf("\\/");
printf(ANSI_COLOR_RESET);
printf("\n\t[ ");
for( unsigned char i = 0; i < INBUF_DIMENSION; i++ )
printf("%s%.3d%s ", isread(i, buf)?ANSI_COLOR_RESET:ANSI_COLOR_GREEN, buf->ring[i], ANSI_COLOR_RESET );
printf(" ]\n");
printf(ANSI_COLOR_RED);
printf("WR:\t ");
for( unsigned char j = 0; j < buf->wr * 4; j++ ) putchar(' '); printf("/\\");
printf(ANSI_COLOR_RESET);
printf("\n\n%sBuffer usage: %g\%\n", ANSI_COLOR_BRIGHT_WHITE, 100.0 * inbuf_usage( buf ) / INBUF_DIMENSION);
printf( ANSI_COLOR_WHITE );
}
void test( int cycle, int consec, int ms, inbufPrt buf ){
//Testa 'cycle' cicli di lettura e scrittura in cui vengono pushati o pullati un numero
//di dati tra 0 e 'consec' a caso. I dati sono inseriti in ordine crescente ed e' mostrato
//un output abbondante.
int cnt = 0; //Variabile che alloca il dato da inserire
srand( time( NULL ) ); //Seme per il generatore di numeri casuali
//Variabili per le statistiche globali
int total_push = 0;
int total_pull = 0;
int total_push_lost = 0;
//Stringa temporanea per i log.
char str[1024];
//Inizia i cicli
for(unsigned char i = 0; i < cycle; i++ ){
int read_cy = rand() % consec; //Numero di cicli di lettura consecutivi
int write_cy = rand() % consec; //Numero di cicli di scrittura consecutivi
int j, k; //Contatori per i cicli di lettura e scrittura
//Inizia la scrittura
sprintf(str, "%sInserting %d numbers, from %d to %d%s\n", ANSI_COLOR_RED, write_cy, cnt, cnt+write_cy-1, ANSI_COLOR_RESET);
add_log_str( str );
for( j = 0; j < write_cy; j++){
int tmp = buf->wr;
inbuf_push( cnt++, buf );
if( buf->wr != tmp ) //Se il puntatore di scrittura si e' mosso il dato è stato inserito con successo
sprintf(str, "\t%sPushed value %d%s\n", ANSI_COLOR_MAGENTA, cnt-1, ANSI_COLOR_RESET );
else{ //Altrimenti la FIFO è pienai
putchar('\a');
sprintf(str, "\t%sCan't push value, stack is full.%s\n", ANSI_COLOR_YELLOW, ANSI_COLOR_RESET );
add_log_str( str );
printf("\e[1;1H\e[2J");
print_inbuf(buf);
mini_log_print();
usleep( ms * 1000 );
break;
}
add_log_str( str );
printf("\e[1;1H\e[2J");
print_inbuf(buf);
mini_log_print();
usleep( ms * 1000 );
}
total_push += j;
total_push_lost += write_cy - j;
//Inizia i cicli di lettura
sprintf(str, "%sExtracting %d numbers%s\n", ANSI_COLOR_BLUE, read_cy, ANSI_COLOR_RESET);
add_log_str( str );
for( k = 0; k < read_cy; k++){
int ext = inbuf_pull(buf);
if( ext >= 0 ) //Se ritorna un valore lo mostra
sprintf(str, "\t%sExtracted value: %d%s\n", ANSI_COLOR_GREEN, ext, ANSI_COLOR_RESET );
else{ //Se ritorna -1 vuol dire che la FIFO è vuota e smette di fare le letture.
putchar('\a');
sprintf(str, "\t%sNo more value to extract.%s\n", ANSI_COLOR_YELLOW, ANSI_COLOR_RESET );
add_log_str( str );
printf("\e[1;1H\e[2J");
print_inbuf(buf);
mini_log_print();
usleep( ms * 1000 );
break;
}
add_log_str( str );
printf("\e[1;1H\e[2J");
print_inbuf(buf);
mini_log_print();
usleep( ms * 1000 );
}
total_pull += k;
}
printf("\n\n*** STATISTICS ***\n\n%s * Total pushed numbers: %d\n%s * Total pulled numbers: %d\n%s * Total lost numbers: %d%s\n",
ANSI_COLOR_RED, total_push, ANSI_COLOR_BLUE, total_pull, ANSI_COLOR_MAGENTA, total_push_lost, ANSI_COLOR_RESET);
}
int main( int argc, char **argv ){
inbuf buf;
inbuf_init(&buf);
test( 100, 15, 100, &buf );
return 0;
}
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