///////////////////////////////////////////////////////////////////////////////
// File   :  pgcd.c
// Date   :  November 2017
// Author :  Alain Greiner <alain.greiner@lip6.fr>
///////////////////////////////////////////////////////////////////////////////
// This single thread interactive application computes the PGCD.
///////////////////////////////////////////////////////////////////////////////


#include <stdio.h>
#include <stdlib.h>
#include <almosmkh.h>

#define   INSTRUMENTATION  0
#define   IDBG             0

/////////////////
void main( void )
{
    unsigned int       opx;
    unsigned int       opy;
    unsigned int       x;
    unsigned int       y;
    unsigned long long cycle;
    unsigned int       cxy;
    unsigned int       lid;

    get_cycle( &cycle );
    get_core_id( &cxy , &lid );

    printf( "\n[pgcd] starts on core[%x,%d] / cycle %d\n\n",
    cxy , lid , (unsigned int)cycle ); 

    // get operand X
    printf("operand X = ");
    get_uint32( &opx );
    printf("\n");

    // get operand Y
    printf("operand Y = ");
    get_uint32( &opy );
    printf("\n");

    // check operands 
    if( (opx == 0) || (opy == 0) ) 
    {
        printf("\n[pgcd error] operands must be strictly positive\n");
        exit(0);
    } 

    // compute PGCD
    x = opx;
    y = opy;
    while (x != y) 
    {
        if(x > y)   x = x - y;
        else        y = y - x;
    }

    // display result
    printf("pgcd      = %d\n", x);

#if INSTRUMENTATION

    char   name[64];
    char   path[128];

    // build a file name from X and Y values
    snprintf( name , 64 , "pgcd_%d_%d", opx, opy ); 

    // build file pathname
    snprintf( path , 128 , "home/%s" , name );

#if IDBG
idbg();
#endif

    // open file
    FILE * stream = fopen( path , NULL );

    if( stream == NULL )
    {
        printf("\n[pgcd error] cannot open instrumentation file <%s>\n", name );
        exit(0);
    }

    printf("\n[pgcd] file %s successfully open\n", path);

#if IDBG
idbg();
#endif

    // register results to file
    int ret = fprintf( stream , "pgcd( %d , %d ) = %d\n", opx, opy, x );

    if( ret < 0 )
    {
        printf("\n[pgcd error] cannot write to instrumentation file <%s>\n", name );
        exit(0);
    }

    printf("\n[pgcd] file %s successfully written\n", path);

    display_mapper( path , 0 , 64 );

    // close instrumentation file

#if IDBG
idbg();
#endif

    if( fclose( stream ) )
    {
        printf("\n[pgcd error] cannot close the file <%s>\n", name );
        exit(0);
    }

    printf("\n[pgcd] file %s successfully closed\n", path);

#endif

    exit(0);
        
} // end pgcd

