Beispiel #1
0
void
pb_flush (pb_t *pb)
{
        pb_node_t *curr, *next, *stop;
        uint16_t i, n_iterators;

	pb_validate(pb);
        stop  = pb->psentinel;
        curr  = stop->next; /* next = head */

        while(curr != stop) {
                next = curr->next;
                curr->next->prev = curr->prev;
                curr->prev->next = curr->next;
                pb->freeproc(&curr->data, curr->data_len);
                pb->n_nodes--;
                assert(curr->data == NULL);
                block_free(curr, sizeof(pb_node_t));
                curr = next;
        }
        
        assert(stop->next  == stop);
        assert(stop->prev  == stop);
        assert(pb->n_nodes == 0);

        /* Reset all iterators */
        n_iterators = pb->n_iterators;
        for(i = 0; i < n_iterators; i++) {
                pb->iterators[i].node = stop;
        }
	pb_validate(pb);
}
Beispiel #2
0
void
pb_shift_units_back_after(pb_t *pb, timestamp_t ref_ts, timestamp_t delta)
{
        pb_node_t *stop, *curr;

	pb_validate(pb);
        stop = pb->psentinel;
        curr = pb->psentinel->prev;
        while(curr != stop && ts_gt(curr->playout, ref_ts)) {
                curr->playout = ts_add(curr->playout, delta);
                curr = curr->prev;
        }
	pb_validate(pb);
}
Beispiel #3
0
void
pb_shift_forward(pb_t *pb, timestamp_t delta)
{
        pb_node_t *stop, *curr;

	pb_validate(pb);
        stop = pb->psentinel;
        curr = pb->psentinel->next;

        while(curr != stop) {
                curr->playout = ts_sub(curr->playout, delta);
                curr = curr->next;
        }
	pb_validate(pb);
}
Beispiel #4
0
int
pb_iterator_detach_at (pb_iterator_t *pi,
                       u_char       **data,
                       uint32_t      *data_len,
                       timestamp_t          *playout)
{
        pb_iterator_t  *iterators;
        pb_node_t      *curr_node, *next_node;
        uint16_t         i, n_iterators;

	pb_validate(pi->buffer);
        if (pb_iterator_get_at(pi, data, data_len, playout) == FALSE) {
                /* There is no data to get */
                return FALSE;
        }

        /* Check we are not attempting to remove
         * data that another iterator is pointing to
         */
        iterators   = &pi->buffer->iterators[0]; 
        n_iterators = pi->buffer->n_iterators;
        for(i = 0; i < n_iterators; i++) {
                if (iterators[i].node == pi->node && iterators + i != pi) {
                        debug_msg("Eek removing node that another iterator is using...danger!\n");
                        iterators[i].node = iterators[i].node->prev;
                }
        }

        /* Relink list of nodes */
        curr_node = pi->node;
        next_node = curr_node->next;
        
        curr_node->next->prev = curr_node->prev;
        curr_node->prev->next = curr_node->next;
        
#ifdef DEBUG
	curr_node->next     = NULL;
	curr_node->prev     = NULL;
	curr_node->magic    = 0;
	curr_node->data     = NULL;
	curr_node->data_len = 0;
#endif
        block_free(curr_node, sizeof(pb_node_t));
        pi->node = next_node;
        pi->buffer->n_nodes--;
	pb_validate(pi->buffer);
        return TRUE;
}
Beispiel #5
0
int
pb_iterator_get_at(pb_iterator_t *pi,
                   u_char       **data,
                   uint32_t       *data_len,
                   timestamp_t          *playout)
{
        pb_node_t *sentinel = pi->buffer->psentinel;
       /* This can be rewritten in fewer lines, but the obvious way is not as efficient. */
	pb_validate(pi->buffer);
        if (pi->node != sentinel) {
                *data     = pi->node->data;
                *data_len = pi->node->data_len;
                *playout  = pi->node->playout;
                return TRUE;
        } else {
                /* We are at the start of the list so maybe we haven't tried reading before */
                pi->node = sentinel->next;
                if (pi->node != sentinel) {
                        *data     = pi->node->data;
                        *data_len = pi->node->data_len;
                        *playout  = pi->node->playout;
                        return TRUE;
                } 
        }
        /* There is data on the list */
        *data     = NULL;
        *data_len = 0;
        memset(playout, 0, sizeof(timestamp_t));
        return FALSE;
}
Beispiel #6
0
static enum pipe_error 
pb_cache_buffer_validate(struct pb_buffer *_buf, 
                         struct pb_validate *vl,
                         unsigned flags)
{
   struct pb_cache_buffer *buf = pb_cache_buffer(_buf);
   return pb_validate(buf->buffer, vl, flags);
}
Beispiel #7
0
enum pipe_error
pb_validate_validate(struct pb_validate *vl) 
{
   unsigned i;
   
   for(i = 0; i < vl->used; ++i) {
      enum pipe_error ret;
      ret = pb_validate(vl->entries[i].buf, vl, vl->entries[i].flags);
      if(ret != PIPE_OK) {
         while(i--)
            pb_validate(vl->entries[i].buf, NULL, 0);
         return ret;
      }
   }

   return PIPE_OK;
}
static enum pipe_error 
mm_buffer_validate(struct pb_buffer *buf, 
                   struct pb_validate *vl,
                   unsigned flags)
{
   struct mm_buffer *mm_buf = mm_buffer(buf);
   struct mm_pb_manager *mm = mm_buf->mgr;
   return pb_validate(mm->buffer, vl, flags);
}
Beispiel #9
0
static enum pipe_error 
pool_buffer_validate(struct pb_buffer *buf, 
                     struct pb_validate *vl,
                     unsigned flags)
{
   struct pool_buffer *pool_buf = pool_buffer(buf);
   struct pool_pb_manager *pool = pool_buf->mgr;
   return pb_validate(pool->buffer, vl, flags);
}
Beispiel #10
0
int
pb_iterators_equal(pb_iterator_t *pi1,
                   pb_iterator_t *pi2)
{
        assert(pi1 != NULL);
        assert(pi2 != NULL);

	pb_validate(pi1->buffer);
	pb_validate(pi2->buffer);
        /* Move nodes off of sentinel if necessary and possible */
        if (pi1->node == pi1->buffer->psentinel) {
                pi1->node = pi1->buffer->psentinel->next; /* yuk */
        }
        if (pi2->node == pi2->buffer->psentinel) {
                pi2->node = pi2->buffer->psentinel->next; /* yuk */
        }

        return (pi1->node == pi2->node);
}
Beispiel #11
0
int
pb_iterator_dup(pb_iterator_t **pb_dst,
                pb_iterator_t  *pb_src)
{
	pb_validate(pb_src->buffer);
        if (pb_iterator_create(pb_src->buffer, pb_dst)) {
                (*pb_dst)->node = pb_src->node;
                return TRUE;
        }
        return FALSE;
}
Beispiel #12
0
int
pb_iterator_get_ts(pb_iterator_t *pbi, timestamp_t *ts)
{
        pb_validate(pbi->buffer);
        assert(ts);
        if (pbi->node != pbi->buffer->psentinel) {
                *ts = pbi->node->playout;
                return TRUE;
        }
        return FALSE;
}
Beispiel #13
0
int
pb_iterator_rwd(pb_iterator_t *pi)
{
        pb_node_t *sentinel = pi->buffer->psentinel;

	pb_validate(pi->buffer);
        if (sentinel->next != sentinel) {
                pi->node = sentinel->next;
                return TRUE;
        }
        return FALSE;
}
Beispiel #14
0
int
pb_get_end_ts(pb_t *pb, timestamp_t *ts)
{
        pb_validate(pb);
        assert(ts);

        if (pb->sentinel.prev != pb->psentinel) {
                *ts = pb->sentinel.prev->playout;
                return TRUE;
        }
        return FALSE;
}
Beispiel #15
0
int
pb_iterator_retreat(pb_iterator_t *pi)
{
        pb_node_t *sentinel = pi->buffer->psentinel;

	pb_validate(pi->buffer);
        if (pi->node->prev != sentinel) {
                pi->node = pi->node->prev;
                return TRUE;
        }
        return FALSE;
}
Beispiel #16
0
int 
pb_add (pb_t *pb, u_char *data, uint32_t data_len, timestamp_t playout)
{
        pb_node_t *curr, *stop, *made;
        
	assert(data != NULL);
	assert(data_len > 0);
	pb_validate(pb);

        /* Assuming that addition will be at the end of list (or near it) */
        stop = pb->psentinel;
        curr = stop->prev;    /* list tail */
        while (curr != stop && ts_gt(curr->playout, playout)) {
                curr = curr->prev;
        }

        /* Check if unit already exists */
        if (curr != stop && ts_eq(curr->playout, playout)) {
                debug_msg("Add failed - unit already exists\n");
                return FALSE;
        }

        made = (pb_node_t*)block_alloc(sizeof(pb_node_t));
        if (made) {
                made->playout  = playout;
                made->data     = data;
                made->data_len = data_len;
                made->prev = curr;                
                made->next = curr->next;
                made->next->prev = made;
                made->prev->next = made;
		made->magic      = PB_NODE_MAGIC;
                pb->n_nodes++;
		pb_validate(pb);
                return TRUE;
        } 
        debug_msg("Insufficient memory\n");
        return FALSE;
}
Beispiel #17
0
int
pb_iterator_ffwd(pb_iterator_t *pi)
{
        pb_node_t *sentinel = pi->buffer->psentinel;

	pb_validate(pi->buffer);
        /* Sentinel prev is tail of buffer */
        if (sentinel->prev != sentinel) {
                pi->node = sentinel->prev;
                return TRUE;
        }
        return FALSE;
}
Beispiel #18
0
int
pb_iterator_create(pb_t           *pb,
                   pb_iterator_t **ppi) 
{
        pb_iterator_t *pi;
        if (pb->n_iterators == PB_MAX_ITERATORS) {
                debug_msg("Too many iterators\n");
                *ppi = NULL;
                return FALSE;
        }
	pb_validate(pb);

        /* Link the playout buffer to the iterator */
        pi = &pb->iterators[pb->n_iterators];
        pb->n_iterators++;
        /* Set up node and buffer references */
        pi->node   = &pb->sentinel;
        pi->buffer = pb;
        *ppi = pi;

	pb_validate(pi->buffer);
        return TRUE;
}
static enum pipe_error
fenced_buffer_validate(struct pb_buffer *buf,
                       struct pb_validate *vl,
                       unsigned flags)
{
   struct fenced_buffer *fenced_buf = fenced_buffer(buf);
   struct fenced_manager *fenced_mgr = fenced_buf->mgr;
   enum pipe_error ret;

   pipe_mutex_lock(fenced_mgr->mutex);

   if(!vl) {
      /* invalidate */
      fenced_buf->vl = NULL;
      fenced_buf->validation_flags = 0;
      ret = PIPE_OK;
      goto done;
   }

   assert(flags & PB_USAGE_GPU_READ_WRITE);
   assert(!(flags & ~PB_USAGE_GPU_READ_WRITE));
   flags &= PB_USAGE_GPU_READ_WRITE;

   /* Buffer cannot be validated in two different lists */
   if(fenced_buf->vl && fenced_buf->vl != vl) {
      ret = PIPE_ERROR_RETRY;
      goto done;
   }

   if(fenced_buf->vl == vl &&
      (fenced_buf->validation_flags & flags) == flags) {
      /* Nothing to do -- buffer already validated */
      ret = PIPE_OK;
      goto done;
   }

   ret = pb_validate(fenced_buf->buffer, vl, flags);
   if (ret != PIPE_OK)
      goto done;

   fenced_buf->vl = vl;
   fenced_buf->validation_flags |= flags;

done:
   pipe_mutex_unlock(fenced_mgr->mutex);

   return ret;
}
Beispiel #20
0
static enum pipe_error 
pb_ondemand_buffer_validate(struct pb_buffer *_buf, 
                            struct pb_validate *vl,
                            unsigned flags)
{
   struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf);
   enum pipe_error ret; 

   assert(!buf->mapcount);
   if(buf->mapcount)
      return PIPE_ERROR;

   ret = pb_ondemand_buffer_instantiate(buf);
   if(ret != PIPE_OK)
      return ret;
   
   return pb_validate(buf->buffer, vl, flags);
}
Beispiel #21
0
int
pb_iterator_audit(pb_iterator_t *pi, timestamp_t history_len)
{
        timestamp_t cutoff;
        int  removed;
        pb_node_t *stop, *curr, *next;
        pb_t      *pb;

#ifdef DEBUG
        /* If we are debugging we check we are not deleting
         * nodes pointed to by other iterators since this *BAD*
         */
        uint16_t        i, n_iterators;
        pb_iterator_t *iterators = pi->buffer->iterators;
        n_iterators = pi->buffer->n_iterators;
#endif

	pb_validate(pi->buffer);

        pb   = pi->buffer;
        stop = pi->node;
        removed = 0;
        if (pi->node != pb->psentinel) {
                curr = pb->psentinel->next; /* head */;
                cutoff = ts_sub(pi->node->playout, history_len);
                while(ts_gt(cutoff, curr->playout)) {
                        /* About to erase a block an iterator is using! */
#ifdef DEBUG
                        for(i = 0; i < n_iterators; i++) {
                                assert(iterators[i].node != curr);
                        }
#endif
                        next = curr->next; 
                        curr->next->prev = curr->prev;
                        curr->prev->next = curr->next;
                        pb->freeproc(&curr->data, curr->data_len);
                        pb->n_nodes--;
                        block_free(curr, sizeof(pb_node_t));
                        curr = next;
                        removed ++;
                }
        }
        return removed;
}
Beispiel #22
0
static enum pipe_error 
pb_debug_buffer_validate(struct pb_buffer *_buf, 
                         struct pb_validate *vl,
                         unsigned flags)
{
   struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
   
   pipe_mutex_lock(buf->mutex);
   if(buf->map_count) {
      debug_printf("%s: attempting to validate a mapped buffer\n", __FUNCTION__);
      debug_printf("last map backtrace is\n");
      debug_backtrace_dump(buf->map_backtrace, PB_DEBUG_MAP_BACKTRACE);
   }
   pipe_mutex_unlock(buf->mutex);

   pb_debug_buffer_check(buf);

   return pb_validate(buf->buffer, vl, flags);
}
Beispiel #23
0
int 
pb_create(pb_t **ppb, void (*datafreeproc)(u_char **data, uint32_t data_len))
{
        pb_t *pb;

        assert(datafreeproc  != NULL);

        pb = (pb_t*)xmalloc(sizeof(pb_t));
        if (pb != NULL) {
                memset(pb, 0, sizeof(pb_t));
                *ppb = pb;
                pb->sentinel.next = pb->sentinel.prev = &pb->sentinel;
                pb->psentinel     = &pb->sentinel;
                pb->freeproc      = datafreeproc;
		pb->magic         = PB_MAGIC;
		pb_validate(pb);
                return TRUE;
        }
        return FALSE;
}
Beispiel #24
0
int 
pb_destroy (pb_t **ppb)
{
        pb_t *pb = *ppb;
	pb_validate(pb);
        pb_flush(pb);

#ifdef DEBUG
        if (pb->n_iterators != 0) {
                debug_msg("Iterators dangling from buffer.  Release first.\n");
		abort();
        }
#endif

        assert(pb->n_iterators == 0);
        xfree(pb);
        *ppb = NULL;

        return TRUE;
}
Beispiel #25
0
void
pb_iterator_destroy(pb_t           *pb,
                    pb_iterator_t **ppi)
{
        uint16_t i, j;
        pb_iterator_t *pi;
        
	pb_validate(pb);
        pi = *ppi;
        assert(pi->buffer == pb);
        
        /* Remove iterator from buffer's list of iterators and
         * compress list in one pass */
        for(j = 0, i = 0; j < pb->n_iterators; i++,j++) {
                if (&pb->iterators[i] == pi) {
                        j++;
                }
                pb->iterators[i] = pb->iterators[j];
        }
        pb->n_iterators--;

        /* Empty pointer */
        *ppi = NULL;
}
Beispiel #26
0
int
pb_is_empty(pb_t *pb)
{
	pb_validate(pb);
        return (pb->psentinel->next == pb->psentinel);
}
Beispiel #27
0
uint32_t
pb_node_count(pb_t *pb)
{
	pb_validate(pb);
        return pb->n_nodes;
}
static enum pipe_error
fenced_buffer_validate(struct pb_buffer *buf,
                       struct pb_validate *vl,
                       unsigned flags)
{
   struct fenced_buffer *fenced_buf = fenced_buffer(buf);
   struct fenced_manager *fenced_mgr = fenced_buf->mgr;
   enum pipe_error ret;

   pipe_mutex_lock(fenced_mgr->mutex);

   if(!vl) {
      /* invalidate */
      fenced_buf->vl = NULL;
      fenced_buf->validation_flags = 0;
      ret = PIPE_OK;
      goto done;
   }

   assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
   assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE));
   flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE;

   /* Buffer cannot be validated in two different lists */
   if(fenced_buf->vl && fenced_buf->vl != vl) {
      ret = PIPE_ERROR_RETRY;
      goto done;
   }

   if(fenced_buf->vl == vl &&
      (fenced_buf->validation_flags & flags) == flags) {
      /* Nothing to do -- buffer already validated */
      ret = PIPE_OK;
      goto done;
   }

   /*
    * Create and update GPU storage.
    */
   if(!fenced_buf->buffer) {
      assert(!fenced_buf->mapcount);

      ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, TRUE);
      if(ret != PIPE_OK) {
         goto done;
      }

      ret = fenced_buffer_copy_storage_to_gpu_locked(fenced_buf);
      if(ret != PIPE_OK) {
         fenced_buffer_destroy_gpu_storage_locked(fenced_buf);
         goto done;
      }

      if(fenced_buf->mapcount) {
         debug_printf("warning: validating a buffer while it is still mapped\n");
      }
      else {
         fenced_buffer_destroy_cpu_storage_locked(fenced_buf);
      }
   }

   ret = pb_validate(fenced_buf->buffer, vl, flags);
   if (ret != PIPE_OK)
      goto done;

   fenced_buf->vl = vl;
   fenced_buf->validation_flags |= flags;

done:
   pipe_mutex_unlock(fenced_mgr->mutex);

   return ret;
}