Exemplo n.º 1
0
static void sem_player(int fd1, int fd2) {
	fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
	xsem_post(fd1, 1);

	fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
	xsem_wait(fd2);

	fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
	xsem_post(fd1, 1);

	fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
	xsem_wait(fd2);

	fprintf(stdout, "[%u] posting 5 on %d\n", getpid(), fd1);
	xsem_post(fd1, 5);

	fprintf(stdout, "[%u] waiting 5 times on %d\n", getpid(), fd2);
	xsem_wait(fd2);
	xsem_wait(fd2);
	xsem_wait(fd2);
	xsem_wait(fd2);
	xsem_wait(fd2);
}
Exemplo n.º 2
0
static void *copy_thread_hashmap(void *_me)
{
	struct worker_thread *me = _me;

	while (1) {
		uint8_t buf[block_size];
		uint8_t hash[hash_size];
		off_t off;
		int ret;

		xsem_wait(&me->sem0);

		for (off = fd_off; off < sizeblocks; off++) {
			if (memcmp(srchashmap + off * hash_size,
				   dsthashmap + off * hash_size, hash_size)) {
				break;
			}
		}

		if (off == sizeblocks || check_signal()) {
			fd_off = sizeblocks;
			xsem_post(&me->next->sem0);
			break;
		}

		if (should_report_progress()) {
			char str[256];
			int ret;

			ret = sprintf(str, "%Ld/%Ld (%Ld/%Ld mismatches)",
				      (long long)off,
				      (long long)sizeblocks,
				      (long long)mismatch_idx,
				      (long long)mismatch_cnt);
			memset(str + ret, '\b', ret);
			str[2 * ret] = 0;

			fputs(str, stderr);
		}

		ret = xpread(fd_src, buf, block_size, off * block_size);

		fd_off = off + 1;
		mismatch_idx++;

		xsem_post(&me->next->sem0);

		if (ret < block_size && off != sizeblocks - 1) {
			fprintf(stderr, "short read\n");
			break;
		}

		gcry_md_hash_buffer(hash_algo, hash, buf, ret);

		if (memcmp(hash, srchashmap + off * hash_size, hash_size)) {
			fprintf(stderr, "warning: source image inconsistent "
					"with its hashmap at block %Ld\n",
				(long long)off);
		}

		xsem_wait(&me->sem1);

		xpwrite(fd_dst, buf, ret, off * block_size);

		memcpy(dsthashmap + off * hash_size, hash, hash_size);
		xpwrite(fd_dsthashmap, hash, hash_size, off * hash_size);

		xsem_post(&me->next->sem1);
	}

	return NULL;
}
Exemplo n.º 3
0
static void *copy_thread_no_hashmap(void *_me)
{
	struct worker_thread *me = _me;

	while (1) {
		uint8_t buf[block_size];
		uint8_t hash[hash_size];
		off_t off;
		int ret;

		xsem_wait(&me->sem0);

		off = fd_off;
		if (off == sizeblocks) {
			xsem_post(&me->next->sem0);
			break;
		}

		if (check_signal()) {
			fd_off = sizeblocks;
			xsem_post(&me->next->sem0);
			break;
		}

		fd_off++;

		posix_fadvise(fd_src, off * block_size, 4 * block_size,
				POSIX_FADV_WILLNEED);

		ret = xpread(fd_src, buf, block_size, off * block_size);

		xsem_post(&me->next->sem0);

		if (ret < block_size && off != sizeblocks - 1) {
			fprintf(stderr, "short read\n");
			break;
		}

		gcry_md_hash_buffer(hash_algo, hash, buf, ret);

		xsem_wait(&me->sem1);

		if (memcmp(dsthashmap + off * hash_size, hash, hash_size)) {
			xpwrite(fd_dst, buf, ret, off * block_size);
			xpwrite(fd_dsthashmap, hash,
				hash_size, off * hash_size);
			memcpy(dsthashmap + off * hash_size, hash, hash_size);

			fprintf(stderr, "%Ld ", (long long)off);
			progress_reported();

			again = 1;
		} else if (should_report_progress()) {
			char str[256];

			ret = sprintf(str, "%Ld/%Ld", (long long)off,
				      (long long)sizeblocks);
			memset(str + ret, '\b', ret);
			str[2 * ret] = 0;

			fputs(str, stderr);
		}

		xsem_post(&me->next->sem1);
	}

	return NULL;
}