2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use is subject to license terms.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdlib.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/errno.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <string.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <pthread.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <synch.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <tlm_buffers.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <tlm.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "tlm_proto.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_allocate_buffers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * build a set of buffers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffers_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_allocate_buffers(boolean_t write, long xfer_size)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffers_t *buffers = ndmp_malloc(sizeof (tlm_buffers_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (buffers == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (buf = 0; buf < TLM_TAPE_BUFFERS; buf++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_buffer_data =
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_malloc(xfer_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (buffers->tbs_buffer[buf].tb_buffer_data == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Memory allocation failed. Give everything back */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < buf; i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buffers->tbs_buffer[i].tb_buffer_data);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buffers);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_buffer_size = (write)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ? xfer_size : 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_full = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_eof = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_eot = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_errno = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_buffer[buf].tb_buffer_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_init(&buffers->tbs_mtx, 0, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_init(&buffers->tbs_in_cv, 0, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_init(&buffers->tbs_out_cv, 0, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_data_transfer_size = xfer_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buffers->tbs_ref = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (buffers);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_release_buffers
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * give all memory back to the OS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_release_buffers(tlm_buffers_t *buffers)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (buffers != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_release_in_buf(buffers);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_release_out_buf(buffers);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&buffers->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (--buffers->tbs_ref <= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < TLM_TAPE_BUFFERS; i++)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buffers->tbs_buffer[i].tb_buffer_data);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_destroy(&buffers->tbs_in_cv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_destroy(&buffers->tbs_out_cv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&buffers->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_destroy(&buffers->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(buffers);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_mark_empty
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Mark a buffer empty and clear its flags. No lock is take here:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the buffer should be marked empty before it is released for use
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * by another thread.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_mark_empty(tlm_buffer_t *buf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (buf == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf->tb_full = buf->tb_eof = buf->tb_eot = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar buf->tb_errno = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_advance_in_idx
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Advance the input index of the buffers(round-robin) and return pointer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to the next buffer in the buffer pool.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_advance_in_idx(tlm_buffers_t *bufs)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bufs == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (++bufs->tbs_buffer_in >= TLM_TAPE_BUFFERS)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_buffer_in = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (&bufs->tbs_buffer[bufs->tbs_buffer_in]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_advance_out_idx
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Advance the output index of the buffers(round-robin) and return pointer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to the next buffer in the buffer pool.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_advance_out_idx(tlm_buffers_t *bufs)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bufs == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (++bufs->tbs_buffer_out >= TLM_TAPE_BUFFERS)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_buffer_out = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (&bufs->tbs_buffer[bufs->tbs_buffer_out]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_in_buf
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return pointer to the next buffer in the buffer pool.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_in_buf(tlm_buffers_t *bufs, int *idx)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_t *ret;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bufs == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ret = &bufs->tbs_buffer[bufs->tbs_buffer_in];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (idx)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *idx = bufs->tbs_buffer_in;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (ret);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_out_buf
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return pointer to the next buffer in the buffer pool.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_out_buf(tlm_buffers_t *bufs, int *idx)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_t *ret;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (bufs == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ret = &bufs->tbs_buffer[bufs->tbs_buffer_out];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (idx)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *idx = bufs->tbs_buffer_out;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (ret);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_release_in_buf
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Another buffer is filled. Wake up the consumer if it's waiting for it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_release_in_buf(tlm_buffers_t *bufs)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_flags |= TLM_BUF_IN_READY;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_signal(&bufs->tbs_in_cv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_release_out_buf
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * A buffer is used. Wake up the producer to re-fill a buffer if it's waiting
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * for the buffer to be used.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_release_out_buf(tlm_buffers_t *bufs)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_flags |= TLM_BUF_OUT_READY;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_signal(&bufs->tbs_out_cv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_in_buf_wait
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Wait for the input buffer to get available.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_in_buf_wait(tlm_buffers_t *bufs)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((bufs->tbs_flags & TLM_BUF_IN_READY) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_wait(&bufs->tbs_in_cv, &bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_flags &= ~TLM_BUF_IN_READY;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_setup_timer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set up the time out value.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic inline void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_setup_timer(timestruc_t *timo, unsigned milli_timo)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (milli_timo == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar milli_timo = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (milli_timo / 1000)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar timo->tv_sec = (milli_timo / 1000);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar timo->tv_sec = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar timo->tv_nsec = (milli_timo % 1000) * 1000000L;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_in_buf_timed_wait
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Wait for the input buffer to get ready with a time out.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_in_buf_timed_wait(tlm_buffers_t *bufs, unsigned int milli_timo)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar timestruc_t timo;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_setup_timer(&timo, milli_timo);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_reltimedwait(&bufs->tbs_in_cv, &bufs->tbs_mtx, &timo);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TLM_BUF_IN_READY doesn't matter for timedwait but clear
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it here so that cond_wait doesn't get the wrong result.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_flags &= ~TLM_BUF_IN_READY;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_buffer_out_buf_timed_wait
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Wait for the output buffer to get ready with a time out.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_buffer_out_buf_timed_wait(tlm_buffers_t *bufs, unsigned int milli_timo)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar timestruc_t timo;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_buffer_setup_timer(&timo, milli_timo);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_reltimedwait(&bufs->tbs_out_cv, &bufs->tbs_mtx, &timo);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TLM_BUF_OUT_READY doesn't matter for timedwait but clear
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it here so that cond_wait doesn't get the wrong result.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bufs->tbs_flags &= ~TLM_BUF_OUT_READY;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&bufs->tbs_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_cmd_wait
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TLM command synchronization typically use by command
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * parent threads to wait for launched threads to initialize.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_cmd_wait(tlm_cmd_t *cmd, uint32_t event_type)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&cmd->tc_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((cmd->tc_flags & event_type) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_wait(&cmd->tc_cv, &cmd->tc_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cmd->tc_flags &= ~event_type;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&cmd->tc_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tlm_cmd_signal
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TLM command synchronization typically use by launched threads
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to unleash the parent thread.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartlm_cmd_signal(tlm_cmd_t *cmd, uint32_t event_type)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&cmd->tc_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cmd->tc_flags |= event_type;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) cond_signal(&cmd->tc_cv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&cmd->tc_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}