/** * @brief Function to sit on the bottom of the thread stack * * @param in_data is a thrgrp_data_t, with tmp loaded with the function * the user wants to run, the argument to call the function on, and * the thread group this new thread is to be spawned in * @return doesn't */ static void *thrgrp_bottom(void *in_data){ thrgrp_data_t *data = (thrgrp_data_t *) in_data; void *(*func)(void *) = data->tmp.func; void *arg = data->tmp.arg; thrgrp_group_t *tg = data->tmp.tg; void * ret; /* now that we have all of the data out of data, we'll use it as our queueing element */ data->qel.next = NULL; data->qel.tid = thr_getid(); /* runthe code we were asked to run */ ret = func(arg); /* insert ourselves into the zombie queue */ mutex_lock(&(tg->lock)); if(tg->zombie_in) tg->zombie_in->next = &(data->qel); tg->zombie_in = &(data->qel); if(tg->zombie_out == NULL) tg->zombie_out = &(data->qel); /* signal a waiter to come clean up our zombie */ cond_signal(&(tg->cv)); mutex_unlock(&(tg->lock)); /* if we return with ret, should exit with ret */ return ret; }
void _pthread_rt() { PTHREAD_LOG("initializing POSIX thread runtime (debug build)"); _pthread_initialized = TRUE; thread0 = malloc( sizeof(struct pthread) ); thread0->pth_id = thr_getid(); pthread_spin_init(&_pthread_slock, PTHREAD_PROCESS_PRIVATE); }
int main() { thr_init(16 * PAGE_SIZE); (void) thr_create(waiter, (void *) thr_getid()); //sleep(10); /* optional, of course!! */ thr_exit((void *)'!'); while(1) continue; /* placate compiler portably */ }