Няма описание
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. vector_t v[2 * MAX_THREADS];
  2. // used to ensure print outs make sense
  3. pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
  4. void usage(char *prog) {
  5. fprintf(stderr, "usage: %s [-d (turn on deadlocking behavior)] [-l loops] [-n num_threads] [-t (do timing)] [-v (for verbose)]\n", prog);
  6. exit(1);
  7. }
  8. // only called by one thread (not thread-safe)
  9. void vector_init(vector_t *v, int value) {
  10. int i;
  11. for (i = 0; i < VECTOR_SIZE; i++) {
  12. v->values[i] = value;
  13. }
  14. Pthread_mutex_init(&v->lock, NULL);
  15. }
  16. // only called by one thread (not thread-safe)
  17. void vector_print(vector_t *v, char *str) {
  18. int i;
  19. for (i = 0; i < VECTOR_SIZE; i++) {
  20. printf("%s[%d] %d\n", str, i, v->values[i]);
  21. }
  22. }
  23. void print_info(int call_return, int thread_id, int v0, int v1) {
  24. if (verbose == 0)
  25. return;
  26. Pthread_mutex_lock(&print_lock);
  27. int j;
  28. for (j = 0; j < thread_id; j++) printf(" ");
  29. if (call_return)
  30. printf("<-add(%d, %d)\n", v0, v1);
  31. else
  32. printf("->add(%d, %d)\n", v0, v1);
  33. Pthread_mutex_unlock(&print_lock);
  34. }
  35. typedef struct __thread_arg_t {
  36. int tid;
  37. int vector_add_order;
  38. int vector_0;
  39. int vector_1;
  40. } thread_arg_t;
  41. void *worker(void *arg) {
  42. thread_arg_t *args = (thread_arg_t *) arg;
  43. int i, v0, v1;
  44. for (i = 0; i < loops; i++) {
  45. if (args->vector_add_order == 0) {
  46. v0 = args->vector_0;
  47. v1 = args->vector_1;
  48. } else {
  49. v0 = args->vector_1;
  50. v1 = args->vector_0;
  51. }
  52. print_info(0, args->tid, v0, v1);
  53. vector_add(&v[v0], &v[v1]);
  54. print_info(1, args->tid, v0, v1);
  55. }
  56. return NULL;
  57. }
  58. int main(int argc, char *argv[]) {
  59. opterr = 0;
  60. int c;
  61. while ((c = getopt (argc, argv, "l:n:vtdp")) != -1) {
  62. switch (c) {
  63. case 'l':
  64. loops = atoi(optarg);
  65. break;
  66. case 'n':
  67. num_threads = atoi(optarg);
  68. break;
  69. case 'v':
  70. verbose = 1;
  71. break;
  72. case 't':
  73. do_timing = 1;
  74. break;
  75. case 'd':
  76. cause_deadlock = 1;
  77. break;
  78. case 'p':
  79. enable_parallelism = 1;
  80. break;
  81. default:
  82. usage(argv[0]);
  83. }
  84. }
  85. assert(num_threads < MAX_THREADS);
  86. pthread_t pid[MAX_THREADS];
  87. thread_arg_t args[MAX_THREADS];
  88. int i;
  89. for (i = 0; i < num_threads; i++) {
  90. args[i].tid = i;
  91. if (enable_parallelism == 0) {
  92. args[i].vector_0 = 0;
  93. args[i].vector_1 = 1;
  94. } else {
  95. args[i].vector_0 = i * 2;
  96. args[i].vector_1 = i * 2 + 1;
  97. }
  98. if (cause_deadlock && i % 2 == 1)
  99. args[i].vector_add_order = 1;
  100. else
  101. args[i].vector_add_order = 0;
  102. }
  103. for (i = 0; i < 2 * MAX_THREADS; i++)
  104. vector_init(&v[i], i);
  105. double t1 = Time_GetSeconds();
  106. for (i = 0; i < num_threads; i++)
  107. Pthread_create(&pid[i], NULL, worker, (void *) &args[i]);
  108. for (i = 0; i < num_threads; i++)
  109. Pthread_join(pid[i], NULL);
  110. double t2 = Time_GetSeconds();
  111. fini();
  112. if (do_timing) {
  113. printf("Time: %.2f seconds\n", t2 - t1);
  114. }
  115. //vector_print(&v[0], "v1");
  116. //vector_print(&v[1], "v2");
  117. return 0;
  118. }