diskaccess.cpp File Reference

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "vsidevice.h"

Go to the source code of this file.

Functions

void * FuncaoThread (void *Param)
int main (int argc, char *argv[])

Variables

char * NomeDisco
unsigned long long int TamanhoDisco
unsigned int TamanhoBloco
unsigned int NumeroBlocos
unsigned int NumLeituras
unsigned int MaxMicroSegundos
CvsiDevice Disco

Function Documentation

void* FuncaoThread ( void *  Param  ) 

Definition at line 37 of file diskaccess.cpp.

00038 {
00039     int                erro;
00040     unsigned int       i;
00041     unsigned int       Bloco;
00042     unsigned int       TempoEspera;
00043     unsigned long long int PosicaoDisco;
00044     double             TempoInicial;
00045     double             TempoFinal; 
00046     CvsiDevice         DiscoThread;
00047     struct timeval     inicio;
00048     struct timeval     fim;
00049     char              *BufferLeitura;
00050     pthread_t          ThreadId;
00051 
00052     // Obtem a id da thread
00053     ThreadId = pthread_self();
00054     printf("Thread %lu (pid=%lu): iniciada. \n", ThreadId, syscall(SYS_gettid) ); 
00055     TempoEspera = random() % MaxMicroSegundos;
00056     printf("Thread %lu: esperando %u ms. \n", ThreadId, TempoEspera);
00057     usleep(TempoEspera * 1000);
00058     printf("Thread %lu: iniciando a leitura. \n", ThreadId); 
00059     // Cria o buffer de leitura
00060     BufferLeitura = new char[ TamanhoBloco ];
00061 
00062     if( BufferLeitura == NULL )
00063     {
00064         printf("Thread %lu: erro ao criar o buffer com %u bytes. \n", ThreadId, 
00065                TamanhoBloco );
00066         pthread_exit( NULL );
00067     }
00068     
00069     // Abre novamente o disco
00070     erro = DiscoThread.OpenDeviceAgain(NomeDisco, TamanhoDisco);
00071     if( erro != 0 )
00072     {
00073         printf( "Thread %lu: erro ao abrir o dispositivo %s. \n", ThreadId,
00074                 NomeDisco );
00075         pthread_exit( NULL );
00076     }
00077     else
00078         printf( "Thread %lu: dispositivo %s aberto com sucesso. \n", ThreadId,
00079                 NomeDisco);
00080 
00081     for( i = 0; i < NumLeituras; i++ )
00082     {
00083         // Escolhe um bloco do disco aleatoriamente do disco
00084         Bloco = random() % NumeroBlocos;
00085         PosicaoDisco = Bloco * TamanhoBloco;
00086         gettimeofday( &inicio, NULL );
00087         erro = DiscoThread.Read( PosicaoDisco, TamanhoBloco, BufferLeitura );   
00088         gettimeofday( &fim, NULL );
00089         if( erro != 0 )
00090         {
00091             printf( "Thread %lu: erro ao ler o bloco %u (com %u bytes) do dispositivo %s. ",
00092                     ThreadId, Bloco, TamanhoBloco, NomeDisco);
00093             printf( "Posicao no disco %llu. Tipo do erro gerado %d. ",
00094                     PosicaoDisco, erro);
00095             printf( "Erro do sistema %u (%s).\n", errno, strerror( errno ) );
00096             fflush( stdout );
00097         }
00098         else
00099         {
00100             TempoInicial = ( ( double ) inicio.tv_sec ) * 1000.0 +
00101                            ( ( double ) inicio.tv_usec / 1000.0);
00102             TempoFinal =   ( ( double ) fim.tv_sec ) * 1000.0 +
00103                            ( ( double ) fim.tv_usec / 1000.0);
00104             if( TempoFinal-TempoInicial > 1000 )
00105             {
00106                 printf( "*************************************************\n" );
00107                 printf( "Thread %lu: bloco %u (com %u bytes) do dispositivo %s lido em %4.6f ms. \n",
00108                         ThreadId, Bloco, TamanhoBloco, NomeDisco,
00109                         TempoFinal-TempoInicial );
00110                 printf( "*************************************************\n" );
00111             }
00112             else
00113                 printf( "Thread %lu: bloco %u (com %u bytes) do dispositivo %s lido em %4.6f ms. \n", 
00114                         ThreadId, Bloco, TamanhoBloco, NomeDisco,
00115                         TempoFinal-TempoInicial );
00116         }
00117     }
00118     
00119     delete[] BufferLeitura;
00120     DiscoThread.Close();
00121     printf( "Thread %lu: terminada. \n", ThreadId );
00122     pthread_exit( NULL );  
00123 }

int main ( int  argc,
char *  argv[] 
)

Definition at line 125 of file diskaccess.cpp.

00126 {   
00127     int             erro;
00128     unsigned int    i;
00129     unsigned int    NumeroThreads;
00130     pthread_attr_t  ThreadAttr;
00131     pthread_t      *ThreadId;
00132     CvsiDevice      Disco;
00133     struct timeval  atual;
00134 
00135     gettimeofday( &atual, NULL );
00136     srandom(atual.tv_sec);
00137 
00138     if( argc < 6 )
00139     {
00140         printf( "Sintaxe: %s [dispositivo] [tambloco] [numthreads] [numleituras] [maxmicrosegundos]\n",
00141                 argv[ 0 ] );
00142         return -1;  
00143     }
00144     
00145     NomeDisco        = argv[ 1 ];
00146     TamanhoBloco     = atoi(argv[ 2 ]);
00147     NumeroThreads    = atoi(argv[ 3 ]);
00148     NumLeituras      = atoi(argv[ 4 ]);
00149     MaxMicroSegundos = atoi(argv[ 5 ]);
00150 
00151     // Abre o dispositivo
00152     erro = Disco.Open( NomeDisco );
00153     if( erro != 0 )
00154     {
00155         printf( "main: erro ao abrir o dispositivo %s.\n", NomeDisco );
00156         return erro;    
00157     }   
00158     
00159     // Determina o numero total de blocos
00160     TamanhoDisco = Disco.Size();
00161     if( TamanhoDisco % TamanhoBloco != 0 )
00162     {
00163         printf( "main: o tamanho do bloco %u nao divide o tamanho do disco %llu.\n",
00164                 TamanhoBloco, TamanhoDisco);
00165         Disco.Close();       
00166         return -2;  
00167     }
00168     
00169     NumeroBlocos = (unsigned int) (TamanhoDisco /
00170                                   (unsigned long long int) TamanhoBloco);
00171     // Cria as threads
00172     ThreadId = new pthread_t [NumeroThreads];
00173     if( ThreadId == NULL )
00174     {
00175         printf( "main: erro ao alocar o vetor com as ids de threads com %u ids/\n",
00176                 NumeroThreads);
00177         Disco.Close();       
00178         return -3;  
00179     }
00180     
00181     pthread_attr_init( &ThreadAttr );
00182     pthread_attr_setstacksize( &ThreadAttr, 2 * PTHREAD_STACK_MIN );
00183     
00184     for( i = 0; i < NumeroThreads; i++ )
00185     {
00186         erro = pthread_create( &ThreadId[ i ], &ThreadAttr, FuncaoThread,
00187                                NULL );
00188         if( erro != 0 )
00189             printf("main: aviso - erro ao criar uma das threads.\n");
00190         else
00191             printf("main: thread %lu criada com sucesso.\n", ThreadId[i]);
00192     }
00193     // Espera pelas threads
00194     for( i = 0; i < NumeroThreads; i++ )
00195         pthread_join( ThreadId[ i ], NULL );
00196 
00197     Disco.Close();   
00198     delete[] ThreadId;    
00199     return 0;
00200 }


Variable Documentation

Definition at line 35 of file diskaccess.cpp.

unsigned int MaxMicroSegundos

Definition at line 34 of file diskaccess.cpp.

char* NomeDisco

Definition at line 29 of file diskaccess.cpp.

unsigned int NumeroBlocos

Definition at line 32 of file diskaccess.cpp.

unsigned int NumLeituras

Definition at line 33 of file diskaccess.cpp.

unsigned int TamanhoBloco

Definition at line 31 of file diskaccess.cpp.

unsigned long long int TamanhoDisco

Definition at line 30 of file diskaccess.cpp.

Generated on Wed Jul 4 16:03:29 2012 for RIO by  doxygen 1.6.3