// XXX: we want something faster than this // and maybe want to recover from failure char *new_buf(thread_t *thread, int size) { buf_t *buf = malloc(sizeof(buf_t) + size); if (!buf) fail(1, "allocating buffer"); Q_INIT_ELEM(buf, gc_link); Q_INSERT_TAIL(&thread->bufs, buf, gc_link); return buf->buffer; }
/** @brief Function to construct tcb * * A tcb is allocated for the thread with execution state as * blocked. The TCB is intiatlised so that it can be inserted * into a thread list. * * @param none * @return a tcb data structure */ tcb_t* construct_tcb() { tcb_t *new_thr = (tcb_t *) malloc(sizeof(tcb_t)); new_thr->state = BLOCKED; new_thr->join_tid = DEFAULT_JOIN_TID; new_thr->exit_status = NULL; Q_INIT_ELEM(new_thr, tcb_link); return new_thr; }
/** @brief Function that implements the wait for the condition variable * * Put the thread in the waiting list of the condition variable and * block the thread until it receives a signal to wake up. * * @param cv condition variable that is waited on * @param mp the mutex variable be acquired when signalled * @return void */ void cond_wait (cond_t * cv, mutex_t * mp) { int status = 0; assert (cv != NULL); assert (mp != NULL); /* If cond_variable has been destroyed, do nothing and return */ if (cv->status == COND_DESTORY) { lprintf ("The cond_variable has been destroyed already"); return; } /* Allocate memory for condition variable */ cond_t *node_ptr = malloc (sizeof (cond_t)); /* Initialize the struct to store the thread's it and * prepare to insert */ Q_INIT_ELEM (node_ptr, cond_link); node_ptr->tid = gettid (); /* Lock the queue to store the thread info */ spin_lock_request (&cv->spinlock); /* Insert into the tail of the waiting list */ Q_INSERT_TAIL (&cv->waiting_list, node_ptr, cond_link); /* Release the mutex mp passed in */ mutex_unlock (mp); /* Release the lock of the queue */ spin_lock_release (&cv->spinlock); /* Deschedule the thread who has inserted into the queue */ deschedule (&status); /* Lock the passed mutex mp again */ mutex_lock (mp); return; }