void AES128_Encrypt_Impl::add(const void *_data, int size) { if (calculated) reset(); if (!initialisation_vector_set) throw Exception("AES-128 initialisation vector has not been set"); if (!cipher_key_set) throw Exception("AES-128 cipher key has not been set"); const unsigned char *data = (const unsigned char *) _data; int pos = 0; while (pos < size) { int data_left = size - pos; int buffer_space = aes128_block_size_bytes - chunk_filled; int data_used = min(buffer_space, data_left); memcpy(chunk + chunk_filled, data + pos, data_used); chunk_filled += data_used; pos += data_used; if (chunk_filled == aes128_block_size_bytes) { process_chunk(); chunk_filled = 0; } } }
static ret_t do_read_chunked (cherokee_post_t *post, cherokee_socket_t *sock_in, cherokee_buffer_t *buffer) { ret_t ret; /* Try to read */ ret = do_read_plain (post, sock_in, &post->chunked.buffer, POST_READ_SIZE); switch(ret) { case ret_ok: break; case ret_eagain: return ret_eagain; default: RET_UNKNOWN(ret); return ret_error; } /* Process the buffer */ ret = process_chunk (post, &post->chunked.buffer, buffer); if (unlikely (ret != ret_ok)) { return ret_error; } if (post->chunked.last) { cherokee_buffer_mrproper (&post->chunked.buffer); } return ret_ok; }
void AES192_Decrypt_Impl::add(const void *_data, int size) { if (calculated) reset(); if (!initialisation_vector_set) throw Exception("AES-192 initialisation vector has not been set"); if (!cipher_key_set) throw Exception("AES-192 cipher key has not been set"); const unsigned char *data = (const unsigned char *) _data; int pos = 0; while (pos < size) { int data_left = size - pos; int buffer_space = aes192_block_size_bytes - chunk_filled; int data_used = min(buffer_space, data_left); memcpy(chunk + chunk_filled, data + pos, data_used); chunk_filled += data_used; pos += data_used; if (chunk_filled == aes192_block_size_bytes) { if ((!padding_enabled) || (pos < size) ) // Do not process chunk on the last block if padding is enabled, as calculate() must process it { process_chunk(); chunk_filled = 0; } } } }
/* Returns the checksum of the file */ uint32_t split_file(char* filename, long chunk_size) { int fd; int chunk_num = 1; uint32_t global_checksum = 0; char chunk_fname[MAX_FILENAME_LENGTH]; fd = open(filename, 0, 0666); if(fd < 0) { fprintf(stderr, "Error opening file"); exit(EXIT_FAILURE); } eof = 0; while(!eof) { int e = snprintf(chunk_fname, MAX_FILENAME_LENGTH, "%s.%02d", filename, chunk_num); if(e < 0 || e >= MAX_FILENAME_LENGTH) { printf("Filename is too long\n"); exit(EXIT_FAILURE); } global_checksum ^= process_chunk(fd, chunk_size, chunk_fname); ++chunk_num; } close(fd); return global_checksum; }
void read_all_frames(int fd, int channel) { unsigned int num_samples; char buf[BUF_SIZE]; while ((num_samples=read_one_frame(fd, (struct buffer_h *) buf))) { fprintf(stderr, "read %d samples\n", num_samples); process_chunk((struct buffer_h *) buf, channel); } }
static PyObject* cross_correlate(PyObject* self, PyObject* args) { // Parse the args const char* my_spc_filename; if (!PyArg_ParseTuple(args, "sii", &my_spc_filename, &start_channel, &stop_channel)) { return NULL; } printf("Cross-correlating on %s (START: %d / STOP: %d)\n", my_spc_filename, start_channel, stop_channel); // Reset count rates, etc int i; fifo_gap=0; histogram = malloc(sizeof(int)*histogram_bins); for (i=0; i<histogram_bins; i+=1) { histogram[i]=0; } // Open the file spc_file=fopen(my_spc_filename, "rb"); if (spc_file==0) { return NULL; } // Examine all of the photons in the file. int finished=0; grab_chunk(); while (nrecords>0 && finished!=-1) { finished=split_channels(); process_chunk(0); process_chunk(1); if (finished!=-1) { grab_chunk(); } } // Close the SPC file, prepare the data, free memory and return fclose(spc_file); PyObject* output = build_output_dict(); free(histogram); return output; }
/** * tracker_read_text_from_fd: * @fd: input fd to read from * @max_bytes: max number of bytes to read from @fd * * Reads up to @max_bytes from @fd, and validates the read text as proper * UTF-8. Will also properly close the FD when finishes. * * If the input text is not UTF-8 it will also try to decode it based on the * current locale, or windows-1252, or UTF-16. * * Returns: newly-allocated NUL-terminated UTF-8 string with the read text. **/ gchar * tracker_read_text_from_fd (gint fd, gsize max_bytes) { FILE *fz; GString *s = NULL; gsize n_bytes_remaining = max_bytes; g_return_val_if_fail (max_bytes > 0, NULL); if ((fz = fdopen (fd, "r")) == NULL) { g_warning ("Cannot read from FD... could not extract text"); close (fd); return NULL; } /* Reading in chunks of BUFFER_SIZE * Loop is halted whenever one of this conditions is met: * a) Read bytes reached the maximum allowed (max_bytes) * b) No more bytes to read * c) Error reading * d) Stream has less than 3 bytes * e) Stream has a single line of BUFFER_SIZE bytes with no EOL */ while (n_bytes_remaining > 0) { gchar buf[BUFFER_SIZE]; gsize n_bytes_read; /* Read bytes */ n_bytes_read = fread (buf, 1, MIN (BUFFER_SIZE, n_bytes_remaining), fz); /* Process read bytes, and halt loop if needed */ if (!process_chunk (buf, n_bytes_read, BUFFER_SIZE, &n_bytes_remaining, &s)) { break; } } /* Close the file here */ #ifdef HAVE_POSIX_FADVISE posix_fadvise (fd, 0, 0, POSIX_FADV_DONTNEED); #endif /* HAVE_POSIX_FADVISE */ fclose (fz); /* Validate UTF-8 if something was read, and return it */ return s ? process_whole_string (s) : NULL; }
/** * tracker_read_text_from_stream: * @stream: input stream to read from * @max_bytes: max number of bytes to read from @stream * * Reads up to @max_bytes from @stream, and validates the read text as proper * UTF-8. * * If the input text is not UTF-8 it will also try to decode it based on the * current locale, or windows-1252, or UTF-16. * * Returns: newly-allocated NUL-terminated UTF-8 string with the read text. **/ gchar * tracker_read_text_from_stream (GInputStream *stream, gsize max_bytes) { GString *s = NULL; gsize n_bytes_remaining = max_bytes; g_return_val_if_fail (stream, NULL); g_return_val_if_fail (max_bytes > 0, NULL); /* Reading in chunks of BUFFER_SIZE * Loop is halted whenever one of this conditions is met: * a) Read bytes reached the maximum allowed (max_bytes) * b) No more bytes to read * c) Error reading * d) Stream has less than 3 bytes * e) Stream has a single line of BUFFER_SIZE bytes with no EOL */ while (n_bytes_remaining > 0) { gchar buf[BUFFER_SIZE]; GError *error = NULL; gsize n_bytes_read; /* Read bytes from stream */ if (!g_input_stream_read_all (stream, buf, MIN (BUFFER_SIZE, n_bytes_remaining), &n_bytes_read, NULL, &error)) { g_message ("Error reading from stream: '%s'", error->message); g_error_free (error); break; } /* Process read bytes, and halt loop if needed */ if (!process_chunk (buf, n_bytes_read, BUFFER_SIZE, &n_bytes_remaining, &s)) { break; } } /* Validate UTF-8 if something was read, and return it */ return s ? process_whole_string (s) : NULL; }
static int _read_wav_header(QSP_ARG_DECL Image_File *ifp) { Wav_Chunk_Hdr *ch_p; if( read_wav_header_chunk(ifp) < 0 ) return -1; fprintf(stderr,"read_wav_header: size is %d (0x%x)\n", HDR_P(ifp)->wh_whc.whc_wch.wch_size, HDR_P(ifp)->wh_whc.whc_wch.wch_size); while( (ch_p=read_next_chunk_header(ifp)) != NULL ){ int status; status = process_chunk(ifp,ch_p); if( status < 0 ) return -1; // some error if( status == 1 ) return 0; // data chunk // if status is 0, read next chunk... } return -1; // error return, null chunk }
int unyaffs(int argc, char **argv) { if (argc != 2) { printf("Usage: unyaffs image_file_name\n"); exit(1); } img_file = open(argv[1], O_RDONLY); if (img_file == -1) { printf("open image file failed\n"); exit(1); } obj_list[YAFFS_OBJECTID_ROOT] = "."; while(1) { if (read_chunk() == -1) break; process_chunk(); } close(img_file); return 0; }
void AES192_Encrypt_Impl::calculate() { if (calculated) reset(); if (padding_enabled) { // Note, chunk_filled is never equal to aes192_block_size_bytes at this point, so we can process an empty block if (padding_pkcs7) { // PKCS#7 unsigned char pad_size = aes192_block_size_bytes - chunk_filled; memset(chunk + chunk_filled, pad_size, pad_size); process_chunk(); chunk_filled = 0; } else { // rfc2246 std::vector<unsigned char> buffer; unsigned int pad_size = aes192_block_size_bytes - chunk_filled; pad_size += aes128_block_size_bytes * padding_num_additional_padded_blocks; buffer.resize(pad_size, pad_size-1); add(&buffer[0], pad_size); } } else { if (chunk_filled >0) throw Exception("You must provide data with a block size of 16 when padding is disabled"); } calculated = true; initialisation_vector_set = false; // Force to reset after each call cipher_key_set = false; // Force to reset after each call (to avoid keeping the cipher key in memory) memset(key_expanded, 0, sizeof(key_expanded)); // Remove the key from memory }
void process_file(void *ptr) { char *filename = (char *) ptr; fprintf(stderr,"%s: processing log file %s\n", program_name, filename); FILE *file_to_process = fopen(filename,"r"); if (file_to_process == NULL) { err_sys("Cannot open file %s\n", filename); exit(1); } long file_size = get_size_of_file(file_to_process); // if (is_trivial_file(file_size)) // { // process((void*)file_to_process); // } // else { long num_threads = get_number_of_threads(); long chunk_size = get_chunk_size(file_size, num_threads); pthread_t threads[num_threads]; long byte_endings[num_threads]; long indices[2]; int i; for (i = 0; i < num_threads; ++i) { get_indices(file_to_process, i, chunk_size, byte_endings, indices); // validate_chunk(file_to_process, "validation.txt", indices[0], indices[1], i); process_chunk(file_to_process, i, threads, indices[0], indices[1]); } for (i = 0; i < num_threads; ++i) pthread_join(threads[i], NULL); } }
static int sparse_file_read_sparse(struct sparse_file *s, int fd, bool crc) { int ret; unsigned int i; sparse_header_t sparse_header; chunk_header_t chunk_header; uint32_t crc32 = 0; uint32_t *crc_ptr = 0; unsigned int cur_block = 0; off64_t offset; if (!copybuf) { copybuf = malloc(COPY_BUF_SIZE); } if (!copybuf) { return -ENOMEM; } if (crc) { crc_ptr = &crc32; } ret = read_all(fd, &sparse_header, sizeof(sparse_header)); if (ret < 0) { return ret; } if (sparse_header.magic != SPARSE_HEADER_MAGIC) { return -EINVAL; } if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) { return -EINVAL; } if (sparse_header.file_hdr_sz < SPARSE_HEADER_LEN) { return -EINVAL; } if (sparse_header.chunk_hdr_sz < sizeof(chunk_header)) { return -EINVAL; } if (sparse_header.file_hdr_sz > SPARSE_HEADER_LEN) { /* Skip the remaining bytes in a header that is longer than * we expected. */ lseek64(fd, sparse_header.file_hdr_sz - SPARSE_HEADER_LEN, SEEK_CUR); } for (i = 0; i < sparse_header.total_chunks; i++) { ret = read_all(fd, &chunk_header, sizeof(chunk_header)); if (ret < 0) { return ret; } if (sparse_header.chunk_hdr_sz > CHUNK_HEADER_LEN) { /* Skip the remaining bytes in a header that is longer than * we expected. */ lseek64(fd, sparse_header.chunk_hdr_sz - CHUNK_HEADER_LEN, SEEK_CUR); } offset = lseek64(fd, 0, SEEK_CUR); ret = process_chunk(s, fd, offset, sparse_header.chunk_hdr_sz, &chunk_header, cur_block, crc_ptr); if (ret < 0) { return ret; } cur_block += ret; } if (sparse_header.total_blks != cur_block) { return -EINVAL; } return 0; }
int main(int argc, char **argv) { int ch; char *ep; int opt_detect; int opt_bad; int opt_chunk; int opt_spare; /* handle command line options */ opt_detect = 0; opt_bad = 0; opt_chunk = 0; opt_spare = 0; opt_list = 0; opt_verbose = 0; while ((ch = getopt(argc, argv, "dbc:s:tvVh?")) > 0) { switch (ch) { case 'd': opt_detect = 1; break; case 'b': opt_bad = 1; break; case 'c': opt_chunk = strtol(optarg, &ep, 0); if (*ep != '\0' || opt_chunk < 0 || opt_chunk > (MAX_CHUNK_SIZE / 1024) ) usage(); break; case 's': opt_spare = strtol(optarg, &ep, 0); if (*ep != '\0' || opt_spare < 0 || opt_spare > MAX_SPARE_SIZE) usage(); break; case 't': opt_list = 1; break; case 'v': opt_verbose = 1; break; case 'V': printf("V%s\n", VERSION); exit(0); break; case 'h': case '?': default: usage(); break; } } /* extract rest of command line parameters */ if ((argc - optind) < 1 || (argc - optind) > 2) usage(); if (strcmp(argv[optind], "-") == 0) { /* image file from stdin ? */ img_file = 0; } else { img_file = open(argv[optind], O_RDONLY); if (img_file < 0) prt_err(1, errno, "Open image file failed"); } if (opt_detect) { detect_flash_layout(1, 0); return 0; } if (opt_chunk == 0 || opt_spare == 0) { detect_flash_layout(0, 1); if (opt_verbose) prt_err(0, 0, "Header check OK, chunk size = %dK, spare size = %d, %sbad block info.", chunk_size/1024, spare_size, spare_off ? "" : "no "); } else { chunk_size = opt_chunk * 1024; spare_size = opt_spare; spare_off = opt_bad ? 2 : 0; } spare_data = data + chunk_size; if ((argc - optind) == 2 && !opt_list) { if (mkdirpath(argv[optind+1], 0755) < 0) prt_err(1, errno, "Can't mkdir %s", argv[optind+1]); if (chdir(argv[optind+1]) < 0) prt_err(1, errno, "Can't chdir to %s", argv[optind+1]); } umask(0); init_obj_list(); saved_chunk.objectId = 0; while (read_chunk()) { process_chunk(); } set_dirs_utime(); close(img_file); if (warn_chown) #ifdef __CYGWIN__ prt_err(0, 0, "Warning: Can't restore owner/group attribute (limitation of Cygwin/Windows)"); #else prt_err(0, 0, "Warning: Can't restore owner/group attribute, run unyaffs as root"); #endif return 0; }
int parse_bamfile_fosmid(char* bamfile, HASHTABLE* ht, CHROMVARS* chromvars, VARIANT* varlist, REFLIST* reflist) { fprintf(stderr, "reading sorted bamfile %s for fosmid pool\n", bamfile); int reads = 0; int MAX_READS = 5000000; // 10 million for now //struct alignedread* read = (struct alignedread*)malloc(sizeof(struct alignedread)); struct alignedread** readlist = calloc(MAX_READS, sizeof (struct alignedread*)); for (reads = 0; reads < MAX_READS; reads++) readlist[reads] = calloc(1, sizeof (struct alignedread)); struct alignedread* read_pt; FRAGMENT fragment; fragment.variants = 0; fragment.alist = (allele*) malloc(sizeof (allele)*10000); FRAGMENT* flist = (FRAGMENT*) malloc(sizeof (FRAGMENT) * MAX_READS / 5); int fragments = 0; int chrom = 0; int r = 0, i = 0; int prevchrom = -1; int prevtid = -1; //int prevposition = -1; // position of previous read in sorted bam file int lastread = 0; samfile_t *fp; if ((fp = samopen(bamfile, "rb", 0)) == 0) { fprintf(stderr, "Fail to open BAM file %s\n", bamfile); return -1; } bam1_t *b = bam_init1(); while (samread(fp, b) >= 0) { //readlist[r] = calloc(1,sizeof(struct alignedread)); fetch_func(b, fp, readlist[r]); if ((readlist[r]->flag & (BAM_FUNMAP | BAM_FSECONDARY | BAM_FQCFAIL | BAM_FDUP))) // unmapped reads, PCR/optical dups are ignored { free_readmemory(readlist[r]); continue; } // find the chromosome in reflist that matches read->chrom if the previous chromosome is different from current chromosome // if too many reads, break off when distance between adjacent reads is large if (readlist[r]->tid != prevtid || r >= MAX_READS - 1) { if (r >= MAX_READS - 1) fprintf(stderr, "limit on max reads %d exceeded.. need to clean up buffer \n", MAX_READS); if (prevtid >= 0) { fprintf(stderr, "reads in buffer %d \n", r); process_chunk(readlist, lastread, r, flist, varlist, reflist); // free up reads in list and move up index for (i = lastread; i < r; i++) free_readmemory(readlist[i]); read_pt = readlist[0]; readlist[0] = readlist[r]; readlist[r] = read_pt; r = 0; for (i = 0; i < fragments; i++) { free(flist[i].alist); free(flist[i].id); } fprintf(stderr, "free memory for reads from chrom %d cleaning up of fragment list %d\n", prevtid, fragments); fragments = 0; } chrom = getindex(ht, readlist[r]->chrom); get_chrom_name(readlist[r], ht, reflist); // reflist->current has chromosome index, -1 if no reflist lastread = r; } else chrom = prevchrom; fragment.variants = 0; //fragment.id = readlist[r]->readid; if (chrom >= 0) extract_variants_read(readlist[r], ht, chromvars, varlist, 1, &fragment, chrom, reflist); if (fragment.variants > 0) { add_fragment(flist, &fragment, readlist[r], fragments); readlist[r]->findex = fragments++; } else readlist[r]->findex = -1; reads += 1; if (reads % 2000000 == 0) fprintf(stderr, "processed %d reads, useful fragments \n", reads); prevchrom = chrom; prevtid = readlist[r]->tid; //if (readlist[r]->IS == 0) prevposition = readlist[r]->position; //else if (readlist[r]->IS > 0) prevposition = readlist[r]->position + readlist[r]->IS; // outer end of fragment r1....r2 r++; } process_chunk(readlist, lastread, r, flist, varlist, reflist); for (i = lastread; i < r; i++) free_readmemory(readlist[i]); for (reads = 0; reads < MAX_READS; reads++) free(readlist[reads]); free(readlist); bam_destroy1(b); return 1; }
int main(int argc, char **argv) { int ch; int layout = 0; /* handle command line options */ opt_list = 0; opt_verbose = 0; opt_skip = 0; while ((ch = getopt(argc, argv, "l:tsvVh?")) > 0) { switch (ch) { case 'l': if (optarg[0] < '0' || optarg[0] > '0' + max_layout || optarg[1] != '\0') usage(); layout = optarg[0] - '0'; break; case 't': opt_list = 1; break; case 'v': opt_verbose = 1; break; case 's': opt_skip = 1; break; case 'V': printf("V%s\n", VERSION); exit(0); break; case 'h': case '?': default: usage(); break; } } /* extract rest of command line parameters */ if ((argc - optind) < 1 || (argc - optind) > 2) usage(); if (strcmp(argv[optind], "-") == 0) { /* image file from stdin ? */ img_file = 0; } else { img_file = open(argv[optind], O_RDONLY); if (img_file < 0) prt_err(1, errno, "Open image file failed"); } if (layout == 0) { detect_chunk_size(); } else { chunk_size = possible_layouts[layout-1].chunk_size; spare_size = possible_layouts[layout-1].spare_size; } spare_data = data + chunk_size; // Skip first chunk if (opt_skip) lseek(img_file, chunk_size+spare_size, SEEK_SET); if ((argc - optind) == 2 && !opt_list) { if (mkdirpath(argv[optind+1]) < 0) prt_err(1, errno, "Can't mkdir %s", argv[optind+1]); if (chdir(argv[optind+1]) < 0) prt_err(1, errno, "Can't chdir to %s", argv[optind+1]); } umask(0); init_obj_list(); while (read_chunk()) { process_chunk(); } set_dirs_utime(); close(img_file); return 0; }
/* Returns the checksum of the file */ uint32_t split_file(char* filename, long chunk_size, int max_child_processes) { FILE* fp; uint32_t global_checksum = 0; char chunk_fname[MAX_FILENAME_LENGTH]; long filesize = get_file_size(filename); long num_chunks = (filesize + (chunk_size-4) - 1) / (chunk_size-4); int my_chunk = 0; int num_active_children = 0; while(my_chunk < num_chunks) { while(num_active_children >= max_child_processes) { if(wait(0) == -1) { perror("Error waiting for child to finish"); } num_active_children--; } pid_t child; child = fork(); if(child == -1) { perror("Error forking child"); exit(EXIT_FAILURE); } else if(child == 0) { /* Child */ int e = snprintf(chunk_fname, MAX_FILENAME_LENGTH, "%s.%02d", filename, my_chunk+1); if(e < 0 || e >= MAX_FILENAME_LENGTH) { printf("Filename is too long\n"); exit(EXIT_FAILURE); } fp = fopen(filename, "rb"); if(!fp) { perror("Error opening file"); exit(EXIT_FAILURE); } if(fseek(fp, my_chunk * chunk_size, SEEK_SET) == -1) { perror("Error seeking"); exit(EXIT_FAILURE); } process_chunk(fp, chunk_size, chunk_fname); fclose(fp); exit(0); } /* Parent */ num_active_children++; my_chunk++; } for(my_chunk = 0; my_chunk < num_active_children; ++my_chunk) { if(wait(0) == -1) { perror("Error waiting for child"); } } return global_checksum; }
bool AES192_Decrypt_Impl::calculate() { if (calculated) reset(); bool return_code = true; if (padding_enabled) { if (chunk_filled == aes192_block_size_bytes) { process_chunk(); chunk_filled = 0; int current_size = databuffer.get_size(); if (current_size > 0) { unsigned char *dest_ptr = (unsigned char *) databuffer.get_data(); unsigned int pad_byte = dest_ptr[current_size - 1]; if (padding_pkcs7) { if ( (pad_byte == 0) || (pad_byte > aes192_block_size_bytes) ) { return_code = false; // Invalid pad byte } else { databuffer.set_size(current_size - pad_byte); } } else { pad_byte += 1; // Include the pad length if ((current_size - pad_byte) < 0) { return_code = false; // Not enough data available } else { databuffer.set_size(current_size - pad_byte); } } } else { return_code = false; // Unknown error, for some reason the databuffer does not contain any data } } else { return_code = false; // Input data was not a multiple of the block size. Do not attempt to decode it. } } else { if (chunk_filled) // Input data was not a multiple of the block size. Do not attempt to decode it. return_code = false; } calculated = true; initialisation_vector_set = false; // Force to reset after each call cipher_key_set = false; // Force to reset after each call (to avoid keeping the cipher key in memory) memset(key_expanded, 0, sizeof(key_expanded)); return true; }
void parallel_partial_sum(Iterator first, Iterator last) { typedef typename Iterator::value_type value_type; struct process_chunk { void operator()(Iterator begin, Iterator last, std::future<value_type>* previous_end_value, std::promise<value_type>* end_value) { try { Iterator end = last; ++end; std::partial_sum(begin, end, begin); if (previous_end_value) { value_type& addend = previous_end_value->get(); *last += addend; if (end_value) { end_value->set_value(*last); } std::for_each(begin, last, [addend](value_type & item) { item += addend; }); } else if (end_value) { end_value->set_value(*last); } } catch (...) { if (end_value) { end_value->set_exception(std::current_exception()); } else { throw; } } } }; unsigned long const length = std::distance(first, last); if (!length) { return last; } unsigned long const min_per_thread = 25; unsigned long const max_threads = (length + min_per_thread - 1) / min_per_thread; unsigned long const hardware_threads = std::thread::hardware_concurrency(); unsigned long const num_threads = std::min(hardware_threads != 0 ? hardware_threads : 2, max_threads); unsigned long const block_size = length / num_threads; typedef typename Iterator::value_type value_type; std::vector<std::thread> threads(num_threads - 1); std::vector<std::promise<value_type> > end_values(num_threads - 1); std::vector<std::future<value_type> > previous_end_values; previous_end_values.reserve(num_threads - 1); join_threads joiner(threads); Iterator block_start = first; for (unsigned long i = 0; i < (num_threads - 1); ++i) { Iterator block_last = block_start; std::advance(block_last, block_size - 1); threads[i] = std::thread(process_chunk(), block_start, block_last, (i != 0) ? &previous_end_values[i - 1] : 0, &end_values[i]); block_start = block_last; ++block_start; previous_end_values.push_back(end_values[i].get_future()); } Iterator final_element = block_start; std::advance(final_element, std::distance(block_start, last) - 1); process_chunk()(block_start, final_element, (num_threads > 1) ? &previous_end_values.back() : 0, 0); }