Better usability in browser
Signed-off-by: Tiago Garcia <tiago.rgarcia@ua.pt>
This commit is contained in:
parent
fa06494b59
commit
a906816cd4
|
|
@ -24,6 +24,8 @@ static volatile int keep_running = 1;
|
|||
static u64_t total_attempts = 0;
|
||||
static u32_t coins_found = 0;
|
||||
static double mining_start_time = 0;
|
||||
static double pause_time_offset = 0; // Track paused time
|
||||
static double last_pause_time = 0; // When mining was paused
|
||||
static u32_t found_coins[1024][14]; // Store up to 1024 found coins
|
||||
static u32_t found_coins_count = 0;
|
||||
|
||||
|
|
@ -158,8 +160,20 @@ void get_statistics(u64_t *attempts, u32_t *coins, double *hash_rate, double *el
|
|||
{
|
||||
*attempts = total_attempts;
|
||||
*coins = coins_found;
|
||||
*elapsed_time = get_time() - mining_start_time;
|
||||
*hash_rate = (*elapsed_time > 0) ? (total_attempts / *elapsed_time) : 0;
|
||||
|
||||
double current_time = get_time();
|
||||
double actual_elapsed;
|
||||
|
||||
if(!keep_running && last_pause_time > 0) {
|
||||
// If paused, use the paused time
|
||||
actual_elapsed = last_pause_time - mining_start_time - pause_time_offset;
|
||||
} else {
|
||||
// If running, calculate normally
|
||||
actual_elapsed = current_time - mining_start_time - pause_time_offset;
|
||||
}
|
||||
|
||||
*elapsed_time = actual_elapsed;
|
||||
*hash_rate = (actual_elapsed > 0) ? (total_attempts / actual_elapsed) : 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -170,7 +184,26 @@ EMSCRIPTEN_KEEPALIVE
|
|||
#endif
|
||||
void stop_mining()
|
||||
{
|
||||
keep_running = 0;
|
||||
if(keep_running) {
|
||||
keep_running = 0;
|
||||
last_pause_time = get_time();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resume mining
|
||||
//
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
#endif
|
||||
void resume_mining()
|
||||
{
|
||||
if(!keep_running && last_pause_time > 0) {
|
||||
double pause_duration = get_time() - last_pause_time;
|
||||
pause_time_offset += pause_duration;
|
||||
keep_running = 1;
|
||||
last_pause_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -209,6 +242,8 @@ void reset_mining()
|
|||
total_attempts = 0;
|
||||
coins_found = 0;
|
||||
found_coins_count = 0;
|
||||
pause_time_offset = 0;
|
||||
last_pause_time = 0;
|
||||
mining_start_time = get_time();
|
||||
}
|
||||
|
||||
|
|
|
|||
139
index.html
139
index.html
|
|
@ -6,6 +6,8 @@
|
|||
body {
|
||||
font-family: monospace;
|
||||
padding: 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
|
|
@ -17,6 +19,24 @@
|
|||
padding: 10px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#coins-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
#coins {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
padding: 10px;
|
||||
background: #f9f9f9;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 5px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.control-group {
|
||||
margin: 10px 0;
|
||||
|
|
@ -25,6 +45,17 @@
|
|||
display: inline-block;
|
||||
width: 200px;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.coin-entry {
|
||||
color: #006400;
|
||||
font-weight: bold;
|
||||
}
|
||||
.coin-data {
|
||||
color: #000080;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -40,16 +71,25 @@
|
|||
<button id="start">Start Mining</button>
|
||||
<button id="stop">Stop Mining</button>
|
||||
<button id="reset">Reset</button>
|
||||
<button id="clearCoins">Clear Coins Display</button>
|
||||
|
||||
<div id="stats">
|
||||
Waiting to start...
|
||||
</div>
|
||||
|
||||
<script src="aad_coin_miner_wasm.js"></script>
|
||||
<div id="coins-container">
|
||||
<h2>Found Coins (<span id="coin-count">0</span>)</h2>
|
||||
<div id="coins"></div>
|
||||
</div>
|
||||
|
||||
<script src="coin_miner_wasm.js"></script>
|
||||
<script>
|
||||
let mining = false;
|
||||
let Module;
|
||||
let miningInterval;
|
||||
let updateInterval;
|
||||
let lastDisplayedCoinCount = 0;
|
||||
let pausedStats = false;
|
||||
|
||||
CoinMinerModule().then(mod => {
|
||||
Module = mod;
|
||||
|
|
@ -58,6 +98,8 @@
|
|||
document.getElementById('start').onclick = () => {
|
||||
if (!mining) {
|
||||
mining = true;
|
||||
Module._resume_mining();
|
||||
pausedStats = false;
|
||||
console.log('Starting mining...');
|
||||
startMining();
|
||||
}
|
||||
|
|
@ -68,27 +110,111 @@
|
|||
Module._stop_mining();
|
||||
clearInterval(miningInterval);
|
||||
clearInterval(updateInterval);
|
||||
|
||||
updateStats();
|
||||
|
||||
let currentHTML = document.getElementById('stats').innerHTML;
|
||||
document.getElementById('stats').innerHTML = currentHTML.replace('Mining Statistics:', 'Mining Statistics (PAUSED):');
|
||||
|
||||
pausedStats = true;
|
||||
|
||||
console.log('Mining stopped');
|
||||
};
|
||||
|
||||
document.getElementById('reset').onclick = () => {
|
||||
Module._reset_mining();
|
||||
mining = false;
|
||||
pausedStats = false;
|
||||
clearInterval(miningInterval);
|
||||
clearInterval(updateInterval);
|
||||
lastDisplayedCoinCount = 0;
|
||||
document.getElementById('stats').innerHTML = 'Reset complete. Click Start to begin.';
|
||||
document.getElementById('coins').innerHTML = '';
|
||||
document.getElementById('coin-count').textContent = '0';
|
||||
console.log('Mining reset');
|
||||
};
|
||||
|
||||
document.getElementById('clearCoins').onclick = () => {
|
||||
document.getElementById('coins').innerHTML = '';
|
||||
console.log('Coins display cleared');
|
||||
};
|
||||
|
||||
function coinToString(coinPtr) {
|
||||
let coinStr = '';
|
||||
for (let i = 0; i < 55; i++) {
|
||||
const byteIdx = i ^ 3;
|
||||
const wordIdx = Math.floor(byteIdx / 4);
|
||||
const byteInWord = byteIdx % 4;
|
||||
|
||||
const word = Module.getValue(coinPtr + wordIdx * 4, 'i32');
|
||||
const byte = (word >> (byteInWord * 8)) & 0xFF;
|
||||
|
||||
if (byte >= 32 && byte <= 126) {
|
||||
coinStr += String.fromCharCode(byte);
|
||||
} else if (byte === 10) {
|
||||
coinStr += '\\n';
|
||||
} else if (byte === 0x80) {
|
||||
coinStr += '[0x80]';
|
||||
} else {
|
||||
coinStr += `[0x${byte.toString(16).padStart(2, '0')}]`;
|
||||
}
|
||||
}
|
||||
return coinStr;
|
||||
}
|
||||
|
||||
function displayNewCoins() {
|
||||
const totalCoins = Module._get_found_coins_count();
|
||||
|
||||
if (totalCoins > lastDisplayedCoinCount) {
|
||||
const coinsDiv = document.getElementById('coins');
|
||||
|
||||
for (let i = lastDisplayedCoinCount; i < totalCoins; i++) {
|
||||
const coinPtr = Module._get_found_coin(i);
|
||||
if (coinPtr !== 0) {
|
||||
const coinStr = coinToString(coinPtr);
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
|
||||
const entry = document.createElement('div');
|
||||
entry.innerHTML = `<span class="coin-entry">[${timestamp}] Coin #${i + 1}:</span> <span class="coin-data">${coinStr}</span>`;
|
||||
coinsDiv.appendChild(entry);
|
||||
|
||||
coinsDiv.scrollTop = coinsDiv.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
lastDisplayedCoinCount = totalCoins;
|
||||
document.getElementById('coin-count').textContent = totalCoins;
|
||||
}
|
||||
}
|
||||
|
||||
function updateStats() {
|
||||
const attemptsPtr = Module._malloc(8);
|
||||
const coinsPtr = Module._malloc(4);
|
||||
const hashRatePtr = Module._malloc(8);
|
||||
const elapsedPtr = Module._malloc(8);
|
||||
|
||||
// Zero-initialize the memory before calling
|
||||
Module.setValue(attemptsPtr, 0, 'i32');
|
||||
Module.setValue(attemptsPtr + 4, 0, 'i32');
|
||||
|
||||
Module._get_statistics(attemptsPtr, coinsPtr, hashRatePtr, elapsedPtr);
|
||||
|
||||
const attempts = Module.getValue(attemptsPtr, 'i64');
|
||||
// Read 64-bit unsigned value correctly
|
||||
// On little-endian, low 32 bits come first
|
||||
const attemptsLowUnsigned = Module.getValue(attemptsPtr, 'i32') >>> 0;
|
||||
const attemptsHighUnsigned = Module.getValue(attemptsPtr + 4, 'i32') >>> 0;
|
||||
|
||||
// Combine - for display purposes, if high part is 0, just show low part
|
||||
let attempts;
|
||||
if (attemptsHighUnsigned === 0) {
|
||||
attempts = attemptsLowUnsigned;
|
||||
} else {
|
||||
// Use BigInt for values > 32 bits
|
||||
const low = BigInt(attemptsLowUnsigned);
|
||||
const high = BigInt(attemptsHighUnsigned);
|
||||
attempts = (high * BigInt(4294967296)) + low;
|
||||
}
|
||||
|
||||
const coins = Module.getValue(coinsPtr, 'i32');
|
||||
const hashRate = Module.getValue(hashRatePtr, 'double');
|
||||
const elapsed = Module.getValue(elapsedPtr, 'double');
|
||||
|
|
@ -103,20 +229,16 @@
|
|||
Attempts: ${attempts.toString()}<br>
|
||||
Coins Found: ${coins}<br>
|
||||
Hash Rate: ${(hashRate / 1e6).toFixed(2)} MH/s<br>
|
||||
Elapsed Time: ${elapsed.toFixed(2)} seconds<br>
|
||||
Elapsed Time: ${elapsed.toFixed(2)} seconds
|
||||
`;
|
||||
|
||||
const coinsFound = Module._get_found_coins_count();
|
||||
if (coinsFound > 0) {
|
||||
console.log(`Total coins found: ${coinsFound}`);
|
||||
}
|
||||
displayNewCoins();
|
||||
}
|
||||
|
||||
function startMining() {
|
||||
const batchSize = parseInt(document.getElementById('batchSize').value);
|
||||
const updateMs = parseInt(document.getElementById('updateInterval').value);
|
||||
|
||||
// Mine continuously using setInterval for larger batches
|
||||
miningInterval = setInterval(() => {
|
||||
if (!mining) {
|
||||
clearInterval(miningInterval);
|
||||
|
|
@ -125,7 +247,6 @@
|
|||
Module._mine_coins_wasm(batchSize);
|
||||
}, 0);
|
||||
|
||||
// Update stats periodically
|
||||
updateInterval = setInterval(updateStats, updateMs);
|
||||
}
|
||||
}).catch(err => {
|
||||
|
|
|
|||
3
makefile
3
makefile
|
|
@ -43,6 +43,7 @@ clean:
|
|||
rm -f sha1_tests
|
||||
rm -f sha1_cuda_test sha1_cuda_kernel.cubin
|
||||
rm -f coin_miner_cpu coin_miner_simd coin_miner_cuda coin_miner_cuda_kernel.cubin
|
||||
rm -f coin_miner_wasm.js coin_miner_wasm.wasm
|
||||
rm -f benchmark
|
||||
rm -f a.out
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ coin_miner_cuda: aad_coin_miner_cuda.c coin_miner_cuda_kernel.cubin aad_sha1.h a
|
|||
cc -march=native -Wall -Wshadow -Werror -O3 -I$(CUDA_DIR)/include $< -o $@ -lcuda
|
||||
|
||||
coin_miner_wasm: aad_coin_miner_wasm.c aad_sha1.h aad_sha1_cpu.h aad_sha1_wasm.h aad_data_types.h aad_utilities.h aad_vault.h makefile
|
||||
emcc -O3 -flto -o aad_coin_miner_wasm.js aad_coin_miner_wasm.c \
|
||||
emcc -O3 -flto -o coin_miner_wasm.js aad_coin_miner_wasm.c \
|
||||
-s WASM=1 \
|
||||
-s EXPORTED_FUNCTIONS='["_mine_coins_wasm","_get_statistics","_stop_mining","_reset_mining","_get_found_coin","_get_found_coins_count","_malloc","_free"]' \
|
||||
-s EXPORTED_RUNTIME_METHODS='["cwrap","ccall","getValue","setValue"]' \
|
||||
|
|
|
|||
Loading…
Reference in New Issue