int main(int argc, char **argv) { int checks; printf("Testing sthread_mutex_*, impl: %s\n", (sthread_get_impl() == STHREAD_PTHREAD_IMPL) ? "pthread" : "user"); sthread_init(); mutex = sthread_mutex_init(); sthread_mutex_lock(mutex); if (sthread_create(thread_start, (void*)1, 1) == NULL) { printf("sthread_create failed\n"); exit(1); } /* Wait until the other thread has at least started, * to give it a chance at getting through the mutex incorrectly. */ while (ran_thread == 0) { sthread_yield(); } sthread_dump(); /* The other thread has run, but shouldn't have been * able to affect counter (note that this is not a great test * for preemptive scheduler, since the other thread's sequence * is not atomic). */ assert(counter == 0); /* This should let the other thread run at some point. */ sthread_mutex_unlock(mutex); /* Allow up to 100 checks in case the scheduler doesn't * decide to run the other thread for a really long time. */ checks = 100; while (checks > 0) { sthread_mutex_lock(mutex); if (counter != 0) { /* The other thread ran, got the lock, * and incrmented the counter: test passes. */ checks = -1; } else { checks--; } sthread_mutex_unlock(mutex); /* Nudge the scheduler to run the other thread: */ sthread_yield(); } if (checks == -1) { printf("sthread_mutex passed\n"); } else { printf("*** sthread_mutex failed\n"); } sthread_mutex_free(mutex); return 0; }
/* Consumer thread - remove items from the "buffer" * until they've all been transfered. */ void *thread_start(void *arg) { sthread_mutex_lock(mutex); while (transfered < max_transfer) { /* Wait for main() to put something up for us to take */ while (transfered < max_transfer && waiting == 0) { sthread_cond_wait(avail_cond, mutex); /* This isn't part of using cond vars, but * helps the test fail quickly if they aren't * working properly: */ sthread_mutex_unlock(mutex); sthread_yield(); sthread_mutex_lock(mutex); } /* Either there is something waiting, or we've finished */ if (waiting != 0) { /* Take it */ waiting--; transfered++; } } sthread_mutex_unlock(mutex); return 0; }
void* thread_producer() { req_t req_d; while(1) { // wait for a free buffer slot sthread_monitor_enter(mon); while (available_reqs == RING_SIZE) sthread_monitor_wait(mon); sthread_monitor_exit(mon); // create and clean request req_d = (req_t) malloc(sizeof(struct _req)); memset(req_d,0,sizeof(struct _req)); if ((req_d->reqsz = srv_recv_request(&(req_d->req),&(req_d->cliaddr),&(req_d->clilen))) == 0) continue; sthread_monitor_enter(mon); // send to buffer put_req(req_d); available_reqs++; sthread_monitor_signalall(mon); sthread_monitor_exit(mon); sthread_yield(); } }
/* Takes loop counter as input. */ static void test(void *arg) { int *n = (int *)arg; int i; for (i = 0; i < *n; i++) { printf("Thread %d is running.\n", *n); sthread_yield(); } printf("Thread %d is terminating.\n", *n); }
/* TESTES DE MONITORES * verifica se o consumo de CPU baixa a prioridade e * se a cedencia do CPU sobe a prioridade. * * Joao Garcia, 2008 */ void * thread_start(void * arg) { int i; //dump_stats("dump0.tsv"); for (i = 0; i < 3000000; i++) {} //dump_stats("dump1.tsv"); for (i = 0; i < 3000000; i++) {} //dump_stats("dump2.tsv"); for (i = 0; i < 3000000; i++) {} //dump_stats("dump3.tsv"); for (i = 0; i < 3000000; i++) {} //dump_stats("dump4.tsv"); sthread_yield(); //dump_stats("dump5.tsv"); sthread_yield(); //dump_stats("dump6.tsv"); sthread_yield(); //dump_stats("dump7.tsv"); return NULL; }
int my_recvfrom(snfs_msg_req_t* req, struct sockaddr_un* cliaddr, socklen_t* clilen) { int reqsz; *clilen = sizeof(*cliaddr); do { sthread_yield(); errno = 0; reqsz = recvfrom(sockfd, (void*)req, sizeof(*req), MSG_DONTWAIT, (struct sockaddr *)cliaddr, clilen); } while(errno == EAGAIN); return reqsz; }
int main(int argc, char **argv) { void *ret; int i; printf("Testing sthreads, impl: %s\n", (sthread_get_impl() == STHREAD_PTHREAD_IMPL) ? "pthread" : "user"); sthread_init(); mon1 = sthread_monitor_init(); mon2 = sthread_monitor_init(); if (sthread_create(thread0, (void*)1, 10) == NULL) { printf("sthread_create failed\n"); exit(-1); } sthread_monitor_enter(mon1); for (i = 0; i < NUMBER; i++){ if ((thr[i] = sthread_create(thread1, (void*)i, 10)) == NULL) { printf("sthread_create failed\n"); exit(-1); } sthread_yield(); } for (i = 0; i < NUMBER; i++){ sthread_monitor_wait(mon1); } printf("in main\n"); sthread_monitor_exit(mon1); sthread_sleep(10000); sthread_monitor_enter(mon2); sthread_monitor_signalall(mon2); sthread_monitor_exit(mon2); for (i = 0; i < NUMBER; i++){ sthread_join(thr[i], &ret); } printf("\nSUCCESS in creating %i threads\n", NUMBER); printf("out main\n"); return 0; }
void* thread_consumer() { req_t req_d; int ressz, req_i; snfs_msg_res_t res; while(1) { sthread_monitor_enter(mon); // get request from queue while (!available_reqs) sthread_monitor_wait(mon); req_d = get_req(); available_reqs--; sthread_monitor_signal(mon); sthread_monitor_exit(mon); // clean response memset(&res,0,sizeof(res)); // find request handler req_i = -1; for (int i = 0; i < NUM_REQ_HANDLERS; i++) { if (req_d->req.type == Service[i].type) { req_i = i; break; } } // serve the request if (req_i == -1) { res.status = RES_UNKNOWN; ressz = sizeof(res) - sizeof(res.body); printf("[snfs_srv] unknown request.\n"); } else { Service[req_i].handler(&(req_d->req),req_d->reqsz,&res,&ressz); } // send response to client srv_send_response(&res,ressz,&(req_d->cliaddr),req_d->clilen); // free stuff free(req_d); req_d = NULL; // force request processing sthread_yield(); } }
int main(int argc, char **argv) { sthread_mutex_t mutex = NULL; int i = 0; printf("Testing sthread_mutex_*, impl: %s\n", (sthread_get_impl() == STHREAD_PTHREAD_IMPL) ? "pthread" : "user"); sthread_init(); mutex = sthread_mutex_init(); while (i < 10) { sthread_mutex_lock(mutex); printf("i=%i\n",i); i++; sthread_yield(); sthread_mutex_unlock(mutex); } printf("\nSUCESSO!\n"); return 1; }
int main(int argc, char **argv) { int i; int *arg = (int *)malloc(sizeof(int)); if (!arg) { printf("error: malloc failed\n"); exit(1); } *arg = 1; printf("Testing sthread_create, impl: %s\n", (sthread_get_impl() == STHREAD_PTHREAD_IMPL) ? "pthread" : "user"); sthread_init(); if (sthread_create(thread_start, (void *)arg, 0) == NULL) { printf("sthread_create failed\n"); exit(1); } /* Without using other thread primitives (which we don't want to * rely on for this first test), we can't know for sure that the * child thread runs and completes if we yield just once (in fact, * with x86_64 pthreads the child almost never completes after the * main thread yields just once). So, we yield an arbitrary number * of times here before exiting (100 isn't always enough, but 1000 * seems to be). Even if the child thread doesn't finish running by * the time we're done looping, the success/fail of this test shouldn't * change, but the output may appear in an unexpected order. */ for (i = 0; i < 1000; i++) { sthread_yield(); } printf("back in main\n"); free(arg); return 0; }
int main(int argc, char **argv) { int sent, checks, i; sthread_t child[MAXTHREADS]; printf("Testing sthread_cond_*, impl: %s\n", (sthread_get_impl() == STHREAD_PTHREAD_IMPL) ? "pthread" : "user"); assert(num_threads <= MAXTHREADS); sthread_init(); mutex = sthread_mutex_init(); avail_cond = sthread_cond_init(); sthread_mutex_lock(mutex); for (i = 0; i < num_threads; i++) { child[i] = sthread_create(thread_start, NULL, 1); if (child[i] == NULL) { printf("sthread_create %d failed\n", i); exit(1); } } assert(transfered == 0); /* This should let the other thread run at some point. */ sthread_mutex_unlock(mutex); /* Send a bunch of things for the other threads to take */ sent = 0; while (sent < max_transfer) { sthread_mutex_lock(mutex); waiting++; sent++; sthread_cond_signal(avail_cond); sthread_mutex_unlock(mutex); sthread_yield(); } printf("Sent %d\n", sent); /* Now give the other threads 100 tries to get * them all across. We assume that's enough * for the sake of not running this test forever. */ checks = 10000; //arbitrary?? while (checks > 0) { sthread_mutex_lock(mutex); if (transfered != max_transfer) checks--; else { /* broadcast to let the consumers know we've * finished, so they can exit * (othrewise, they may still be holding the lock * when we try to free it below) */ sthread_cond_broadcast(avail_cond); checks = -1; } sthread_mutex_unlock(mutex); sthread_yield(); } if (checks == -1) { /* Wait for child threads to finish, otherwise we could try to * free the mutex before they've unlocked it! */ printf("joining on children\n"); for (i = 0; i < num_threads; i++) { sthread_join(child[i]); printf("joined with child %d\n", i); } printf("sthread_cond passed\n"); } else { printf("*** sthread_cond failed\n"); /* If we failed, don't bother joining on threads. */ } sthread_mutex_free(mutex); sthread_cond_free(avail_cond); return 0; }