You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

98 lines
2.7 KiB

  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int is_prime(int n) {
  5. if (n <= 1)
  6. return 0;
  7. for (int d = 2; d * d <= n; d++)
  8. if (n % d == 0)
  9. return 0;
  10. return 1;
  11. }
  12. int primes_count_in_interval(int start, int finish) {
  13. int ret = 0;
  14. for (int i = start; i < finish; i++)
  15. if (is_prime(i) != 0)
  16. ret++;
  17. return ret;
  18. }
  19. // The structure that will be passed to the threads, corresponding to an
  20. // interval to count the number of primes in.
  21. typedef struct prime_counter_request {
  22. int start, finish;
  23. } prime_counter_request;
  24. void *prime_counter(void *arg) {
  25. /*
  26. TODO
  27. Complete this function. It takes a primes_counter_request as a parameter
  28. and returns the number of primes in the specified interval. Be careful how
  29. you return the return value.
  30. */
  31. prime_counter_request *req = arg;
  32. int *res = malloc(sizeof(int));
  33. *res = primes_count_in_interval(req->start, req->finish);
  34. return res;
  35. }
  36. int main(int argc, char *argv[]) {
  37. int n = atoi(argv[1]), n_threads = atoi(argv[2]);
  38. int segment_size = n / n_threads;
  39. pthread_t *threads = malloc(n_threads * sizeof(pthread_t));
  40. prime_counter_request *requests =
  41. malloc(n_threads * sizeof(prime_counter_request));
  42. void **results = malloc(n_threads * sizeof(void *));
  43. for (int i = 0; i < n_threads; i++) {
  44. /*
  45. TODO
  46. Complete this loop. You shall spawn <n_threads> threads, each of which
  47. computes the number of primes in a segment of length <segment_size>.
  48. The union of those intervals shall correspond to the interval [0, n).
  49. First, initialize the value of requests[i] with a simple mathematical
  50. computation. Be careful not to overrun the last interval. Second,
  51. spawn a thread that takes requests[i] as an argument. Be careful how
  52. you pass the arguments.
  53. */
  54. requests[i].start = i * segment_size;
  55. requests[i].finish = requests[i].start + segment_size;
  56. if (requests[i].finish > n)
  57. requests[i].finish = n;
  58. pthread_create(&threads[i], NULL, &prime_counter, (void*) &requests[i]);
  59. }
  60. for (int i = 0; i < n_threads; i++) {
  61. /*
  62. TODO
  63. Join the results of threads into the results array.
  64. */
  65. pthread_join(threads[i], (void**) &results[i]);
  66. }
  67. int total_result = 0;
  68. for (int i = 0; i < n_threads; i++)
  69. total_result += *(int *)results[i];
  70. /*
  71. TODO
  72. Free the allocated memory.
  73. */
  74. for (int i = 0; i < n_threads; ++i) {
  75. free(results[i]);
  76. }
  77. free(threads);
  78. free(results);
  79. free(requests);
  80. printf("%d\n", total_result);
  81. exit(EXIT_SUCCESS);
  82. }