Esempio n. 1
0
static void *miner_thread(void *thr_id_int)
{
	int thr_id = (unsigned long) thr_id_int;
	int failures = 0;
	uint32_t max_nonce = 0xffffff, max_nonce2;
	CURL *curl;

	if (opt_randomize) {
		srandom(time(0));
	}

	curl = curl_easy_init();
	if (!curl) {
		fprintf(stderr, "CURL initialization failed\n");
		return NULL;
	}

	while (1) {
		struct work work __attribute__((aligned(128)));
		unsigned long hashes_done;
		struct timeval tv_start, tv_end, diff;
		bool rc;

		/* obtain new work from bitcoin */
		if (!get_work(curl, &work)) {
			fprintf(stderr, "json_rpc_call failed, ");

			if ((opt_retries >= 0) && (++failures > opt_retries)) {
				fprintf(stderr, "terminating thread\n");
				return NULL;	/* exit thread */
			}

			/* pause, then restart work loop */
			fprintf(stderr, "retry after %d seconds\n",
				opt_fail_pause);
			sleep(opt_fail_pause);
			continue;
		}

		if (!validate_midstate(work.data, work.midstate)) {
			printf("SERVER PROBLEM: work.midstate does not equal SHA256 state after first 64-byte chunk\n");
		}

		hashes_done = 0;
		gettimeofday(&tv_start, NULL);

		if (opt_randomize) {
			max_nonce2 = max_nonce*(1.0 + (double)random()/(RAND_MAX+1.0) - 0.5);
		} else {
			max_nonce2 = max_nonce;
		}

		/* scan nonces for a proof-of-work hash */
		switch (opt_algo) {
		case ALGO_C:
			rc = scanhash_c(work.midstate, work.data + 64,
				        work.hash1, work.hash, work.target,
					max_nonce2, &hashes_done);
			break;

#ifdef WANT_SSE2_4WAY
		case ALGO_4WAY: {
			unsigned int rc4 =
				ScanHash_4WaySSE2(work.midstate, work.data + 64,
						  work.hash1, work.hash,
						  work.target,
						  max_nonce2, &hashes_done);
			rc = (rc4 == -1) ? false : true;
			}
			break;
#endif

#ifdef WANT_VIA_PADLOCK
		case ALGO_VIA:
			rc = scanhash_via(work.data, work.target,
					  max_nonce2, &hashes_done);
			break;
#endif
		case ALGO_CRYPTOPP:
			rc = scanhash_cryptopp(work.midstate, work.data + 64,
				        work.hash1, work.hash, work.target,
					max_nonce2, &hashes_done);
			break;

#ifdef WANT_CRYPTOPP_ASM32
		case ALGO_CRYPTOPP_ASM32:
			rc = scanhash_asm32(work.midstate, work.data + 64,
				        work.hash1, work.hash, work.target,
					max_nonce2, &hashes_done);
			break;
#endif

		default:
			/* should never happen */
			return NULL;
		}

		/* record scanhash elapsed time */
		gettimeofday(&tv_end, NULL);
		timeval_subtract(&diff, &tv_end, &tv_start);

		hashmeter(thr_id, &diff, hashes_done);

		/* adjust max_nonce to meet target scan time */
		if (diff.tv_sec > (opt_scantime * 2))
			max_nonce /= 2;			/* large decrease */
		else if ((diff.tv_sec > opt_scantime) &&
			 (max_nonce > 1500000))
			max_nonce -= 1000000;		/* small decrease */
		else if ((diff.tv_sec < opt_scantime) &&
			 (max_nonce < 0xffffec76))
			max_nonce += 100000;		/* small increase */

		/* if nonce found, submit work */
		if (rc)
			submit_work(curl, &work);

		failures = 0;
	}

	curl_easy_cleanup(curl);

	return NULL;
}
Esempio n. 2
0
static void *miner_thread(void *userdata)
{
	struct thr_info *mythr = userdata;
	int thr_id = mythr->id;
	uint32_t max_nonce = 0xffffff;

	/* Set worker threads to nice 19 and then preferentially to SCHED_IDLE
	 * and if that fails, then SCHED_BATCH. No need for this to be an
	 * error if it fails */
	setpriority(PRIO_PROCESS, 0, 19);
	drop_policy();

	/* Cpu affinity only makes sense if the number of threads is a multiple
	 * of the number of CPUs */
	if (!(opt_n_threads % num_processors))
		affine_to_cpu(mythr->id, mythr->id % num_processors);

	while (1) {
		struct work work __attribute__((aligned(128)));
		uint64_t hashes_done;
		struct timeval tv_start, tv_end, diff;
		uint64_t max64;
		bool rc;

		/* obtain new work from internal workio thread */
		if (unlikely(!get_work(mythr, &work))) {
			applog(LOG_ERR, "work retrieval failed, exiting "
				"mining thread %d", mythr->id);
			goto out;
		}

		hashes_done = 0;
		gettimeofday(&tv_start, NULL);

		rc = scanhash(thr_id, work.data, work.target, max_nonce, &hashes_done);

		/* record scanhash elapsed time */
		gettimeofday(&tv_end, NULL);
		timeval_subtract(&diff, &tv_end, &tv_start);

		hashmeter(thr_id, &diff, hashes_done);

		/* adjust max_nonce to meet target scan time */
		if (diff.tv_usec > 500000)
			diff.tv_sec++;
		if (diff.tv_sec > 0) {
			max64 =
			   (hashes_done / 65536 * opt_scantime) / diff.tv_sec;
			if (max64 > 0xfffffffaULL)
				max64 = 0xfffffffaULL;
			max_nonce = max64;
		}

		/* if nonce found, submit work */
		if (rc && !submit_work(mythr, &work))
			break;
	}

out:
	tq_freeze(mythr->q);

	return NULL;
}