/* * tjoin - Interface for users to call join on their threads in SCAM * * @args - The thread ID to join on */ int tjoin (int args) { int tid = ival(car(args)); // Might garbage collect and then wait with pthread_join T_P(); --WorkingThreads; T_V(); pthread_join(Thread[tid], NULL); // I can now garbage collect again T_P(); ++WorkingThreads; T_V(); return newInteger(tid); }
/* thread - start up a pthread to evaluate an expression * - car(args) := captured calling environment * - cadr(args) := expression to be evaluated * * - the calling environment gets extended, and then the expression is evaluated * under the extended environment */ int thread(int args) { T_P(); ++CreatedThreads; ++WorkingThreads; P(); ENSURE_MEMORY(MAKE_ENVIRONMENT_SIZE+INTEGER_SIZE, &args , (int *) 0); /* Extend the environment and create the pseudo-tid */ int env = makeEnvironment(car(args),0,0,0); int expr = cadr(args); int tid = ++ScamThreadID; /* fatal if we exceed the thread limit */ if (tid > MAX_THREADS - 1) { V(); T_V(); Fatal("You have reached the max thread limit of %d\n", MAX_THREADS); } int ret = newIntegerUnsafe(tid); ThreadQueue[tid].env = env; ThreadQueue[tid].expr = expr; ThreadQueue[tid].tid = tid; V(); int *arg = malloc(sizeof(int)); *arg = tid; int p_ret = pthread_create(&Thread[CreatedThreads-1], NULL, (void *)InternalThread,(void *)arg); T_V(); if(p_ret) { Fatal("Error creating threads.\n"); } return ret; }
int main() { struct timespec tstart, tend; int m; int DIM=10000+1; int MM=4000; #ifdef try_TS if ( clock_gettime(CLOCK_MONOTONIC, &tstart)!=0 ) exit(1); TS_make(DIM,MM,0.5); if ( clock_gettime(CLOCK_MONOTONIC, &tend)!=0 ) exit(1); printf("TS_make(%d,%d) took %lf ms\n", DIM, MM, timespecDiff(&tend, &tstart)/1.0e6); #endif if ( clock_gettime(CLOCK_MONOTONIC, &tstart)!=0 ) exit(1); S_make(DIM,MM,0.5); if ( clock_gettime(CLOCK_MONOTONIC, &tend)!=0 ) exit(1); printf("S_make(%d,%d) took %lf ms\n", DIM, MM, timespecDiff(&tend, &tstart)/1.0e6); fS_make(0.5); if ( clock_gettime(CLOCK_MONOTONIC, &tstart)!=0 ) exit(1); T_make(DIM,MM,0.5); if ( clock_gettime(CLOCK_MONOTONIC, &tend)!=0 ) exit(1); printf("T_make(%d,%d) took %lf ms\n", DIM, MM, timespecDiff(&tend, &tstart)/1.0e6); fT_make(DIM,MM,0.5); for (m=10; m<MM; m+=10) printf("(%d,%d): S=%10lg fS=%10g T=%10lg fT=%10g\n", DIM-1, m, exp(S_safe(DIM-1,m)-S_safe(DIM-1,m-1)), exp(fS_safe(DIM-1,m)-fS_safe(DIM-1,m-1)), T_V(DIM-1,m), fT_V(DIM-1,m) ); #ifdef try_TS for (m=10; m<MM; m+=10) printf("(%d,%d): S=%10lg TS=%10lg tbl=%10lg\n", DIM-1, m, S_safe(DIM-1,m), TS_safe(DIM-1,m), TStbl[m-2][DIM-2] ); #endif return 1; }