1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/* File: "pthread.c", Time-stamp: <2007-11-13 17:49:37 feeley> */
/* Copyright (c) 2006-2007 by Marc Feeley, All Rights Reserved. */
#include <stdio.h>
#include <pthread.h>
/*
* ___VERSION must match the version number of the Gambit header file.
*/
#define ___VERSION 402008
#include "gambit.h"
/*
* Include declarations exported by mylib.scm.
*/
#include "mylib.h"
/*
* Define SCHEME_LIBRARY_LINKER as the name of the Scheme library
* prefixed with "____20_" and suffixed with "__". This is the
* function that initializes the Scheme library.
*/
#define SCHEME_LIBRARY_LINKER ____20_mylib__
___BEGIN_C_LINKAGE
extern ___mod_or_lnk SCHEME_LIBRARY_LINKER (___global_state_struct*);
___END_C_LINKAGE
#define N 5 /* number of threads */
___SCMOBJ counter; /* the Scheme counter record to increment */
pthread_mutex_t mut; /* to implement critical section for incrementation */
void increment (void)
{
int got_throw = 0;
/*
* At most one thread at a time can execute Scheme code.
* So call Scheme in a critical section.
*/
pthread_mutex_lock (&mut);
/* call Scheme to increment counter */
___ON_THROW(increment_counter (counter), got_throw=1);
pthread_mutex_unlock (&mut);
if (got_throw)
{
printf ("thread %p is terminating\n", pthread_self ());
pthread_exit (NULL); /* exit if Scheme threw an exception */
}
}
void increment_loop (void)
{
int i;
for (i = 0; i<20000; i++)
increment ();
}
void* thread_main (void* param)
{
increment_loop ();
return NULL;
}
int main (int argc, char **argv)
{
/*
* Setup the Scheme library by calling "___setup" with appropriate
* parameters. The call to "___setup_params_reset" sets all parameters
* to their default setting.
*/
___setup_params_struct setup_params;
___setup_params_reset (&setup_params);
setup_params.version = ___VERSION;
setup_params.linker = SCHEME_LIBRARY_LINKER;
___setup (&setup_params);
/* Main part of program: start N threads that increment a counter */
counter = new_counter (); /* create a new counter */
pthread_mutex_init (&mut, NULL); /* initialize mutex */
{
int i;
pthread_t tid[N];
void* results[N];
for (i = 0; i<N; i++)
pthread_create (&tid[i], NULL, thread_main, NULL);
for (i = 0; i<N; i++)
pthread_join (tid[i], &results[i]);
}
{
int got_throw = 0;
int count = 0;
___ON_THROW(count = get_counter (counter), got_throw=1);
if (got_throw)
printf ("Scheme threw an exception\n");
else
printf ("final count = %d\n", count);
}
/* we don't need the counter anymore */
___ON_THROW(release_counter (counter),);
/* Cleanup the Scheme library */
___cleanup ();
return 0;
}
|