示例#1
0
文件: sort.c 项目: inolen/redream
static void msort_r(uint8_t *in, uint8_t *out, size_t size, int l, int r,
                    sort_cmp cmp) {
  if ((r - l) < 2) {
    return;
  }

  int m = (l + r) / 2;
  msort_r(out, in, size, l, m, cmp);
  msort_r(out, in, size, m, r, cmp);
  merge(in, out, size, l, m, r, cmp);
}
示例#2
0
文件: sort.c 项目: inolen/redream
void msort_noalloc(void *data, void *tmp, int num, size_t size, sort_cmp cmp) {
  memcpy(tmp, data, num * size);
  msort_r(tmp, data, size, 0, num, cmp);
}
void *thread_run(void *ptr) {
  int retcode;
  struct thread_arg *arg = (struct thread_arg *) ptr;
  char **strings = arg->arr.strings;
  int len = arg->arr.len;
  int idx = arg->thread_idx;
  
  if (use_psort) {
    switch (selected_mt_sort_type) {
    case MT_HEAP_SORT:
      parallel_hsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, psort_internal_threads);
      break;
    case MT_TERNARY_HEAP_SORT:
      parallel_ternary_hsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, psort_internal_threads);
      break;
    case MT_QUICK_SORT:
      parallel_qsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, psort_internal_threads);
      break;
    case MT_FLASH_SORT:
      parallel_fsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, metric_str_full, (void *) NULL, psort_internal_threads);
      break;
    case MT_FLASH_SORT_BIN:
      parallel_fsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, metric_binary_printable_pref, (void *) NULL, psort_internal_threads);
      break;
    case MT_INSERTION_SORT:
      parallel_isort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, psort_internal_threads);
      break;
    case MT_MERGE_SORT:
      parallel_msort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, psort_internal_threads);
      break;
    default:
      /* should *never* happen: */
      handle_error_myerrno(-1, -1, "wrong mt_sort_type", PROCESS_EXIT);
    }
  } else {
    switch (selected_mt_sort_type) {
    case MT_HEAP_SORT:
      hsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL);
      break;
    case MT_TERNARY_HEAP_SORT:
      ternary_hsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL);
      break;
    case MT_QUICK_SORT:
      qsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL);
      break;
    case MT_FLASH_SORT:
      fsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, metric_str_full, (void *) NULL);
      break;
    case MT_FLASH_SORT_BIN:
      fsort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL, metric_binary_printable_pref, (void *) NULL);
      break;
    case MT_INSERTION_SORT:
      isort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL);
      break;
    case MT_MERGE_SORT:
      msort_r(strings, len, sizeof(char_ptr), compare_str_full, (void *) NULL);
      break;
    default:
      /* should *never* happen: */
      handle_error_myerrno(-1, -1, "wrong mt_sort_type", PROCESS_EXIT);
    }
  }

  for (int step = 1; step < thread_count; step *= 2) {
    retcode = pthread_barrier_wait(& barrier);
    if (retcode == PTHREAD_BARRIER_SERIAL_THREAD) {
      pthread_mutex_lock(&output_mutex);
      /* printf("thread %ld (%d) is PTHREAD_BARRIER_SERIAL_THREAD=%d\n", (long) id, tid, retcode); */
      pthread_mutex_unlock(&output_mutex);
    } else {
      handle_thread_error(retcode, "pthread_barrier_wait", THREAD_EXIT);
    }

    if (idx % (2*step) == 0) {
      int other_idx = idx + step;
      if (other_idx < thread_count) {
        int i = 0;
        int j = 0;
        int k = 0;
        int m = segments[idx].arr.len;
        int n = segments[other_idx].arr.len;
        int total_len = m + n;
        char_ptr *strings = malloc(total_len * sizeof(char_ptr));
        char_ptr *left = segments[idx].arr.strings;
        char_ptr *right = segments[other_idx].arr.strings;
        while (i+j < total_len) {
          if (i >= m) {
            while (j < n) {
              strings[k++] = right[j++];
            }
          } else if (j >= n) {
            while (i < m) {
              strings[k++] = left[i++];
            }
          } else {
            if (strcmp(left[i], right[j]) <= 0) {
              strings[k++] = left[i++];
            } else {
              strings[k++] = right[j++];
            }
          }
        }
        segments[idx].arr.len = total_len;
        segments[idx].arr.strings = strings;
        segments[other_idx].arr.len = 0;
        segments[other_idx].arr.strings = NULL;
      }
    }
  }
  return (void *) NULL;
}