1// This is a simple test of the THC runtime system. 2 3/* 4 * Copyright (c) 2011, ETH Zurich. 5 * All rights reserved. 6 * 7 * This file is distributed under the terms in the attached LICENSE file. 8 * If you do not find this file, copies can be found by writing to: 9 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 10 */ 11 12#include <stdio.h> 13#include "thc/thc.h" 14 15static void foo(int x) { 16 for (int i = 0; i < 5; i++) { 17 fprintf(stderr, "x=%d\n", x); 18 x++; 19 THCYield(); 20 fprintf(stderr, "x=%d\n", x); 21 } 22} 23 24static int caller(int a, ...) 25{ 26 // Test do..finish and async 27 int x = 42; 28 fprintf(stderr, "Before finish\n"); 29 DO_FINISH({ 30 fprintf(stderr, "Start of finish\n"); 31 for (int i = 0; i < 4; i ++) { 32 ASYNC({foo(100);}); 33 ASYNC({foo(200);}); 34 ASYNC({ 35 int my_i = i; 36 THCYield(); 37 THCYield(); 38 printf("my_i=%d i=%d x=%d\n", my_i, i, x); 39 x++; 40 }); 41 } 42 fprintf(stderr, "End of finish\n"); 43 }); 44 fprintf(stderr, "After finish\n"); 45 46 // Test basic cancellation 47 thc_sem_t sem; 48 thc_sem_init(&sem, 0); 49 for (int i = 0; i < 2; i++) { 50 fprintf(stderr, "\nFirst case: cancellation does not fire\n"); 51 fprintf(stderr, "Entering cancel block at outer level\n"); 52 DO_FINISH_(cb1, { 53 ASYNC({ 54 fprintf(stderr, " Blocking on semaphore at inner level\n"); 55 int canceled = thc_sem_p_x(&sem); 56 fprintf(stderr, " Resumed after blocking on semaphore at inner level %s\n", 57 canceled ? "CANCELED" : "OK"); 58 }); 59 fprintf(stderr, "Signaling semaphore at outer level\n"); 60 thc_sem_v(&sem); 61 fprintf(stderr, "Triggering cancellation at outer level\n"); 62 CANCEL(cb1); 63 }); 64 fprintf(stderr, "Finished cancellation at outer level\n"); 65 66 fprintf(stderr, "\nSecond case: cancellation fires\n"); 67 fprintf(stderr, "Entering cancel block at outer level\n"); 68 DO_FINISH_(cb2, { 69 ASYNC({ 70 fprintf(stderr, " Blocking on semaphore at inner level\n"); 71 int canceled = thc_sem_p_x(&sem); 72 fprintf(stderr, " Resumed after blocking on semaphore at inner level %s\n", 73 canceled ? "CANCELED" : "OK"); 74 }); 75 fprintf(stderr, "Triggering cancellation at outer level\n"); 76 CANCEL(cb2); 77 }); 78 fprintf(stderr, "Finished cancellation at outer level\n"); 79 } 80 81 82 // Test cancellation using CVs 83 thc_lock_t l; 84 thc_condvar_t cv; 85 thc_lock_init(&l); 86 thc_condvar_init(&cv); 87 for (int i = 0; i < 2; i++) { 88 fprintf(stderr, "\nFirst case: cancellation does not fire\n"); 89 fprintf(stderr, "Entering cancel block at outer level\n"); 90 DO_FINISH_(cb3, { 91 ASYNC({ 92 fprintf(stderr, " Blocking on condvar at inner level\n"); 93 thc_lock_acquire(&l); 94 int canceled = thc_condvar_wait_x(&cv, &l); 95 thc_lock_release(&l); 96 fprintf(stderr, " Resumed after blocking on condvar at inner level %s\n", 97 canceled ? "CANCELED" : "OK"); 98 }); 99 fprintf(stderr, "Signaling condition variable at outer level\n"); 100 thc_lock_acquire(&l); 101 thc_condvar_signal(&cv); 102 thc_lock_release(&l); 103 fprintf(stderr, "Triggering cancellation at outer level\n"); 104 CANCEL(cb3); 105 }); 106 fprintf(stderr, "Finished cancellation at outer level\n"); 107 108 fprintf(stderr, "\nSecond case: cancellation fires\n"); 109 fprintf(stderr, "Entering cancel block at outer level\n"); 110 DO_FINISH_(cb4, { 111 ASYNC({ 112 fprintf(stderr, " Blocking on condvar at inner level\n"); 113 thc_lock_acquire(&l); 114 int canceled = thc_condvar_wait_x(&cv, &l); 115 thc_lock_release(&l); 116 fprintf(stderr, " Resumed after blocking on condition variable at inner level %s\n", 117 canceled ? "CANCELED" : "OK"); 118 }); 119 fprintf(stderr, "Triggering cancellation at outer level\n"); 120 CANCEL(cb4); 121 }); 122 fprintf(stderr, "Finished cancellation at outer level\n"); 123 } 124 125 fprintf(stderr, "Done!\n"); 126 return 0; 127} 128 129 130int main(void) { 131 return caller(0, 1, 2, 3); 132} 133