Here's a sample of algo_gate code as a teaser. The funny syntax is just how c defines
function pointers. This technique used used a lot in file systems and device
drivers due to it's flexibility and extensibility.
It's kinda OOish but without the pretensions.
I'm just tidying up the syntax errors and should have a compile later today
// declare some function pointers
// mandatory functions require a custom target function specific to each algo.
// Otherwise the null instance will return a fail code.
// Optional functions may not be required for certain algos or the null
// instance provides a safe default. If the default null instance is suitable for
// a particular algo it is not necessary to define a custom target function.
typedef struct
{
//mandatory
int *( *scanhash ) ( int, uint32_t*, const uint32_t*, uint32_t, uint64_t* );
void *( *hash )( void*, const void*, uint32_t ) ;
//optional
void *( *init_ctx ) ();
uint32_t *( *get_max64 ) ();
void *( *get_opt) ();
bool *( *full_test) ();
void *( *set_target) ( struct work*, uint32_t, uint32_t );
void *( *gen_merkle_root) ( char* merkle_root, struct stratum_ctx* );
bool *( *get_scratchbuf ) ( char* );
int *( *check_algo_alias) ( enum algos );
void *( *ignore_pok) ( int, int );
void *( *display_hashrate)( int, uint64_t );
void *( *display_benchmark_hashrate)( int, uint64_t* );
void *( *wait_for_diff) ( struct stratum_ctx* );
} algo_gate_t;
Each algo then implements the target functions it needs and a function to register
them with algo_gate:
bool register_x11_algo( algo_gate_t* gate )
{
gate->init_ctx = &init_x11_aes_ctx;
gate->scanhash = &scanhash_x11_aes;
gate->hash = &x11_hash_aes;
return true;
};
Each miner thread then calls the registration function for the algo to be mined
if ( false == register_algo_gate( opt_algo, algo_gate[thr_id] ) )
{
applog(LOG_ERR,"Thread %d algo_gate registration failed.\n", thr_id);
if ( NULL != algo_gate )
{
free( algo_gate );
}
exit(1);
}
And the functions are called:
if ( algo_gate->scanhash != null_scanhash )
{
rc = algo_gate->scanhash( thr_id, work.data, work.target, max_nonce,
&hashes_done );
}
else
{
applog(LOG_ERR,"%s has no scanhash function registered.\n",
algo_names[opt_algo]);
}
And that's all there is to it. There ar no references to any specific algos in the miner thread, it is completely
absract.