10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

158 APPENDIX B. SYNCHRONIZATION PRIMITIVESint smp_thread_id(void)thread_id_t create_thread(void *(*func)(void *), void *arg)for_each_thread(t)for_each_running_thread(t)void *wait_thread(thread_id_t tid)void wait_all_threads(void)Figure B.1: Thread APIB.2.1 create thread()The create_thread primitive creates a new thread,starting the new thread’s execution at the functionfunc specified by create_thread()’s first argument,and passing it the argument specified bycreate_thread()’s second argument. This newlycreated thread will terminate when it returns fromthe starting function specified by func. Thecreate_thread() primitive returns thethread_id_t corresponding to the newly created child thread.ThisprimitivewillaborttheprogramifmorethanNR_THREADS threads are created, counting the oneimplicitly created by running the program. NR_THREADS is a compile-time constant that may bemodified, though some systems may have an upperbound for the allowable number of threads.B.2.2 smp thread id()Because the thread_id_t returned from create_thread() is system-dependent, the smp_thread_id() primitive returns a thread index correspondingto the thread making the request. This index isguaranteed to be less than the maximum number ofthreads that have been in existence since the programstarted, and is therefore useful for bitmasks,array indices, and the like.B.2.3 for each thread()The for_each_thread() macro loops through allthreads that exist, including all threads that wouldexist if created. This macro is useful for handlingper-thread variables as will be seen in Section B.4.B.2.4 for each running thread()The for_each_running_thread() macro loopsthrough only those threads that currently exist. <strong>It</strong> isthe caller’s responsibility to synchronize with threadcreation and deletion if required.B.2.5 wait thread()The wait_thread() primitive waits for completionof the thread specified by the thread_id_t passedto it. This in no way interferes with the executionof the specified thread; instead, it merely waits forit. Note that wait_thread() returns the value thatwas returned by the corresponding thread.B.2.6 wait all threads()The wait_all_thread() primitive waits for completionof all currently running threads. <strong>It</strong> is thecaller’sresponsibilitytosynchronizewiththreadcreationand deletion if required. However, this primitiveis normally used to clean up and the end of arun, so such synchronization is normally not needed.B.2.7 Example UsageFigure B.2 shows an example hello-world-like childthread. As noted earlier, each thread is allocated itsown stack, so each thread has its own private argargument and myarg variable. Each child simplyprints its argument and its smp_thread_id() beforeexiting. Note that the return statement on line 7terminates the thread, returning a NULL to whoeverinvokes wait_thread() on this thread.1 void *thread_test(void *arg)2 {3 int myarg = (int)arg;45 printf("child thread %d: smp_thread_id() = %d\n",6 myarg, smp_thread_id());7 return NULL;8 }Figure B.2: Example Child ThreadThe parent program is shown in Figure B.3. <strong>It</strong>invokes smp_init() to initialize the threading systemon line 6, parse arguments on lines 7-14, andannounces its presence on line 15. <strong>It</strong> creates thespecified number of child threads on lines 16-17,and waits for them to complete on line 18. Notethat wait_all_threads() discards the threads returnvalues, as in this case they are all NULL, whichis not very interesting.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!