int rms_shutdown(void) { rms_channel *channel; rmsb->active = 0; uthread_destroy(&(rmsb->rms_rcv_thr)); uthread_destroy(&(rmsb->rms_snd_thr)); uthread_destroy(&(rmsb->rms_mgr_thr)); if(rmsb->listening) { shutdown(rmsb->sock); close(rmsb->sock); } while( (channel = (rms_channel*)mqueue_remove(rmsb->mq_channels))) { rms_channel_close(channel); } mqueue_destroy( rmsb->mq_channels); uthread_mutex_lock(&rmsb->mutx_rmscb); while( (channel = (rms_channel*)mqueue_deq(rmsb->mq_channel_tmp))) { rms_channel_close(channel); } mqueue_destroy( rmsb->mq_channels_tmp); uthread_mutex_unlock(&rmsb->mutx_rmscb); uthread_mutex_destroy(&rmsb->mutx_rmscb); rmsb->state = 0; free(rmsb->hostname); rmsb->initialized = -1; return 0; }
/** * This is the agent procedure. It is complete and you shouldn't change it in * any material way. You can re-write it if you like, but be sure that all it does * is choose 2 random reasources, signal their condition variables, and then wait * wait for a smoker to smoke. */ void* agent (void* av) { struct Agent* a = av; static const int choices[] = {MATCH|PAPER, MATCH|TOBACCO, PAPER|TOBACCO}; static const int matching_smoker[] = {TOBACCO, PAPER, MATCH}; uthread_mutex_lock (a->mutex); for (int i = 0; i < NUM_ITERATIONS; i++) { int r = random() % 3; signal_count [matching_smoker [r]] ++; int c = choices [r]; if (c & MATCH) { VERBOSE_PRINT ("match available\n"); uthread_cond_signal (a->match); } if (c & PAPER) { VERBOSE_PRINT ("paper available\n"); uthread_cond_signal (a->paper); } if (c & TOBACCO) { VERBOSE_PRINT ("tobacco available\n"); uthread_cond_signal (a->tobacco); } VERBOSE_PRINT ("agent is waiting for smoker to smoke\n"); uthread_cond_wait (a->smoke); } uthread_mutex_unlock (a->mutex); return NULL; }
void recordWaitingTime (int waitingTime) { uthread_mutex_lock (waitingHistogrammutex); if (waitingTime < WAITING_HISTOGRAM_SIZE) waitingHistogram [waitingTime] ++; else waitingHistogramOverflow ++; uthread_mutex_unlock (waitingHistogrammutex); }
void consume() { uthread_mutex_lock(mx); while (items <= 0) { consumer_wait_count++; uthread_cond_wait(not_empty); } items--; histogram[items]++; assert (items >= 0); uthread_cond_signal(not_full); uthread_mutex_unlock(mx); }
void produce() { uthread_mutex_lock(mx); while (items >= MAX_ITEMS) { producer_wait_count++; uthread_cond_wait(not_full); } items++; histogram[items]++; assert(items <= MAX_ITEMS); uthread_cond_signal(not_empty); uthread_mutex_unlock(mx); }
void consume(struct Pool* pool) { uthread_mutex_lock(pool->mutex); while (pool->items == 0) { consumer_wait_count++; uthread_cond_wait(pool->notEmpty); } assert (pool->items > 0); pool->items--; histogram [pool->items]++; uthread_cond_signal (pool->notFull); uthread_mutex_unlock (pool->mutex); }
void produce(struct Pool* pool) { uthread_mutex_lock(pool->mutex); while (pool->items == MAX_ITEMS) { producer_wait_count++; uthread_cond_wait(pool->notFull); } assert (pool->items < MAX_ITEMS); pool->items++; histogram [pool->items]++; uthread_cond_signal (pool->notEmpty); uthread_mutex_unlock (pool->mutex); }
void* agent() { srand(time(NULL)); uthread_mutex_lock(mx); for (int i = 0; i < NUM_ITERATIONS; i++) { int random = rand() % 3; histo_expected[(random+2) % 3]++; uthread_cond_signal(resource[random]); uthread_cond_signal(resource[(random+1) % 3]); uthread_cond_wait(done_smoking); } uthread_mutex_unlock(mx); return NULL; }
void* match(void* aa) { struct Agent* a = aa; uthread_mutex_lock(a->mutex); while(1) { uthread_cond_wait(a->match_ready); smoke_count[1]++; a->t--; a->p--; uthread_cond_signal(a->smoke); } uthread_mutex_unlock(a->mutex); return NULL; }
int main (int argc, char** argv) { // setup mutex and condition variables mx = uthread_mutex_create(); smoker_waiting = uthread_cond_create(mx); for (int i = 0; i < 3; i++) { resource[i] = uthread_cond_create(mx); } done_smoking = uthread_cond_create(mx); // setup threads and start agent uthread_init(1); uthread_mutex_lock(mx); for (int i = 0; i < 3; i++) { threads[i] = uthread_create(smoker, (void*)(intptr_t) i); uthread_cond_wait(smoker_waiting); } uthread_mutex_unlock(mx); threads[3] = uthread_create(agent, NULL); // wait for threads to finish for (int i = 3; i >= 0; i--) { uthread_join(threads[i], NULL); } // verify that the histograms of actual/expected match for (int i = 0; i < 3; i++) { assert(histo_expected[i] == histo_actual[i]); } // print histograms of expected and actual smoke counts int sum; printf("Expected: [ "); sum = 0; for (int i = 0; i < 3; i++) { sum += histo_expected[i]; printf("%d ", histo_expected[i]); } printf("]\tSum: %d\n", sum); sum = 0; printf("Actual: [ "); for (int i = 0; i < 3; i++) { sum += histo_actual[i]; printf("%d ", histo_actual[i]); } printf("]\tSum: %d\n", sum); }
void* match_track(void* aa) { struct Agent* a = aa; uthread_mutex_lock(a->mutex); while(1) { uthread_cond_wait(a->match); a->m++; if (a->p > 0) { uthread_cond_signal(a->tobacco_ready); } if (a->t > 0) { uthread_cond_signal(a->paper_ready); } } uthread_mutex_unlock(a->mutex); return NULL; }
void* producer (void* pv) { struct Pool* p = pv; for (int i=0; i<NUM_ITERATIONS; i++) { // TODO uthread_mutex_lock(p->mutex); while (p->items == MAX_ITEMS){ producer_wait_count++; uthread_cond_wait(p->notFull); } p->items++; histogram[p->items]++; uthread_cond_signal(p->notEmpty); uthread_mutex_unlock(p->mutex); } return NULL; }
void* thread1(void *arg) { long i; uthread_mutex_lock(&mut); for (i = 0; i < 1000; ++ i) { while (!have) { uthread_cond_wait(&c1, &mut); } cnt += buf; have = 0; uthread_cond_signal(&c2); } uthread_mutex_unlock(&mut); return NULL; }
void* thread2(void *arg) { long t = (long) arg; long i; uthread_mutex_lock(&mut); for (i = t; i < t + 1000; ++ i) { while (have) { uthread_cond_wait(&c2, &mut); } buf = i; have = 1; uthread_cond_signal(&c1); } uthread_mutex_unlock(&mut); return NULL; }
void* smoker(void* resource_type_vp) { int resource_type = (intptr_t) resource_type_vp; uthread_mutex_lock(mx); uthread_cond_signal(smoker_waiting); for (int i = 0; i < NUM_ITERATIONS; i++) { uthread_cond_wait(resource[resource_type]); switch (num_woken) { case 0: num_woken++; resource_of_first = resource_type; break; case 1: num_woken++; switch(resource_of_first * 10 + resource_type) { case 01: case 10: uthread_cond_signal(resource[2]); break; case 02: case 20: uthread_cond_signal(resource[1]); break; case 12: case 21: uthread_cond_signal(resource[0]); break; } break; case 2: num_woken = 0; resource_of_first = -1; smoke(resource_type); uthread_cond_signal(done_smoking); break; } } uthread_mutex_unlock(mx); return NULL; }