コード例 #1
0
/*
 * Add an integer to the buffer.  Yield control to another
 * thread if the buffer is full.
 */
void bounded_buffer_add(BoundedBuffer *bufp, const BufferElem *elem) {
    // We only want one thread modifying the buffer at a time
    __sthread_lock();
    // Decrement the count of available space (we're adding)
    // Blocks when available count = 0 (buffer is full)
    semaphore_wait(bufp->avail);
    bufp->buffer[(bufp->first + bufp->count) % bufp->length] = *elem;
    bufp->count++;
    // Increment the count of used space
    semaphore_signal(bufp->used);
    __sthread_unlock();
}
コード例 #2
0
/*
 * Get an integer from the buffer.  Yield control to another
 * thread if the buffer is empty.
 */
void bounded_buffer_take(BoundedBuffer *bufp, BufferElem *elem) {
    // We only want one thread modifying the buffer at a time
    __sthread_lock();
    // Decrement count of used space (we're freeing)
    // Blocks when there are no used elements (buffer is empty)
    semaphore_wait(bufp->used);
    /* Copy the element from the buffer, and clear the record */
    *elem = bufp->buffer[bufp->first];
    bufp->buffer[bufp->first] = empty;
    bufp->count--;
    bufp->first = (bufp->first + 1) % bufp->length;
    // Increment count of available space
    semaphore_signal(bufp->avail);
    __sthread_unlock();
}
コード例 #3
0
ファイル: semaphore.c プロジェクト: mishraritvik/personal
/*
 * Decrement the semaphore.
 * This operation must be atomic, and it blocks iff the semaphore is zero.
 */
void semaphore_wait(Semaphore *semp) {
    /* This must be atomic, so make sure no other threads interfere. */
    __sthread_lock();

    while (semp->i == 0) {
        /* Semaphore cannot handle another thread, so block current one. */

        /* Add to queue of blocked threads. */
        struct thread_node * current =
            (struct thread_node *) malloc(sizeof(struct thread_node));

        /* The thread to be held is the currently executing one. */
        current->thread = sthread_current();

        /* Will be at the end of queue so next is NULL. */
        current->next = NULL;

        /* Add to queue. */
        if (semp->head == NULL) {
            /* Empty queue, head and tail are the new thread_node. */
            semp->head = current;
            semp->tail = semp->head;
        }
        else {
            /* This will be the next of tail, and new tail. */
            semp->tail->next = current;
            semp->tail = semp->tail->next;
        }

        /* Block it. */
        sthread_block();
    }

    /* Decrement semaphore count, should still be non-negative. */
    semp->i--;
    assert(semp->i >= 0);

    /* Can unlock now that operations are done. */
    __sthread_unlock();
}
コード例 #4
0
ファイル: semaphore.c プロジェクト: mishraritvik/personal
/*
 * Increment the semaphore.
 * This operation must be atomic.
 */
void semaphore_signal(Semaphore *semp) {
    /* This must be atomic, so make sure no other threads interfere. */
    __sthread_lock();

    /* Incrememnt semaphore count. */
    semp->i++;

    /* Get next in queue to run. */
    if (semp->head == NULL) {
        /* Queue empty! Do nothing. */
    }
    else {
        /* Save the current head to free it later. */
        struct thread_node * old_head = semp->head;

        /* Unblock the head. */
        sthread_unblock(semp->head->thread);

        /* Remove from queue and free. */
        if (semp->head->next == NULL) {
            /* If this has no next them queue is empty now. */
            semp->head = NULL;
            semp->tail = NULL;
        }
        else {
            /* Move head to the next. */
            semp->head = semp->head->next;
        }

        /* Free it. */
        free(old_head);
    }

    /* Can unlock now that operations are done. */
    __sthread_unlock();
}