#!/usr/local/bin/rune -x # # Demonstrate synchronous threads vs asynchronous threads. A threaded # procedure is synchronous by default, meaning that it executes in an # ultra-light-weight fashion using the machine context of the caller # and only switching away if it blocks. For example, if you have a # ton of GUI gadgets, each implemented as a thread, you may desire to # implement them as synchronous entities within a single asynchronous # container to reduce machine overhead. # # An asynchronous thread creates an actual machine thread to manage # the thread. import "sys"; import ; alias stdio.File @stdout = stdio.stdout; int totalCount = 0; int *totalCountP = &totalCount; int main(int ac, string_p *av) { int i; stdout->setmode(stdio.File.M_FULL); stdout->show(dosync("this is td=0000", 0)); stdout->show(dosync("this is td=0001", 1)); stdout->show(dosync("this is td=0002", 2)); stdout->show(dosync("this is td=0003", 3)); stdout->show(dosync("this is td=0004", 4)); stdout->show(dosync("this is td=0005", 5)); stdout->show(dosync("this is td=0006", 6)); stdout->show(dosync("this is td=0007", 7)); stdout->show(dosync("this is td=0008", 8)); stdout->show(dosync("this is td=0009", 9)); stdout->show(doasync("this is atd=0000", 0)); stdout->show(doasync("this is atd=0001", 1)); stdout->show(doasync("this is atd=0002", 2)); stdout->show(doasync("this is atd=0003", 3)); stdout->show(doasync("this is atd=0004", 4)); stdout->show(doasync("this is atd=0005", 5)); stdout->show(doasync("this is atd=0006", 6)); stdout->show(doasync("this is atd=0007", 7)); stdout->show(doasync("this is atd=0008", 8)); stdout->show(doasync("this is atd=0009", 9)); Thread.waitThreads(); stdout->show(dosync("this is td=0000", 0)); stdout->show(dosync("this is td=0001", 1)); stdout->show(dosync("this is td=0002", 2)); stdout->show(dosync("this is td=0003", 3)); stdout->show(dosync("this is td=0004", 4)); stdout->show(dosync("this is td=0005", 5)); stdout->show(dosync("this is td=0006", 6)); stdout->show(dosync("this is td=0007", 7)); stdout->show(dosync("this is td=0008", 8)); stdout->show(dosync("this is td=0009", 9)); stdout->show(doasync("this is atd=0000", 0)); stdout->show(doasync("this is atd=0001", 1)); stdout->show(doasync("this is atd=0002", 2)); stdout->show(doasync("this is atd=0003", 3)); stdout->show(doasync("this is atd=0004", 4)); stdout->show(doasync("this is atd=0005", 5)); stdout->show(doasync("this is atd=0006", 6)); stdout->show(doasync("this is atd=0007", 7)); stdout->show(doasync("this is atd=0008", 8)); stdout->show(doasync("this is atd=0009", 9)); Thread.waitThreads(); # Thread.mssleep(1000); stdout->format("TotalCount %d\n", *totalCountP); stdout->fflush(); } thread int dosync(const char *str, int x) { int i; int copyx = x; const char *copy = str; stdout->fflush(); result(x + 1); for (i = 0; i < 10000; ++i) { # stdout->show(copy, i); thread_schedule immediate; } # stdout->fflush(); } preempt thread int doasync(const char *str, int x) { int i; int copyx = x; const char *copy = str; char buf[32]; char *pp = &buf[0]; stdout->fflush(); result(x + 1); for (i = 0; i < 10000; ++i) { doasync2(); # stdout->show(copy, i); } # stdout->fflush(); # Thread.mssleep(1000); } preempt thread int doasync2(void) { result; ++*totalCountP; # ++totalCount; }