예제 #1
0
파일: pe_workers.c 프로젝트: sasw/opflex
void *pe_workers_fetch_flow(void *arg) {
    static char mod[] = "pe_workers_fetch_flow";
    pe_worker_t *this_worker = (pe_worker_t *) arg;
    void *work_item = NULL;

    DBUG_ENTER(mod);

    VLOG_INFO("Thread %i (%p) going to work.\n",this_worker->index,
                                                &this_worker->thread); 

    /* infinite loop to process work items */
    for(;;) {
        DBUG_PRINT("\nDEBUG ",("Thread %i (%d) calling ring_buffer_pop\n",
                               this_worker->index,
                               &this_worker->thread));
        work_item = ring_buffer_pop();
        DBUG_PRINT("\nDEBUG ",("Thread %i (%d) popped %p\n",
                               this_worker->index,
                               &this_worker->thread,
                               work_item)); 
        if (pe_get_crew_quit_status() == true) {
            VLOG_INFO("Thread %i got quit\n",this_worker->index);
            break;
        }
        pe_translate(work_item);
    }

    VLOG_INFO("Thread %i (%p) leaving work.\n",this_worker->index,
                                                this_worker->thread); 
    DBUG_LEAVE;
    pthread_exit((void *) NULL);
}
예제 #2
0
파일: test.c 프로젝트: chris1287/RingBuffer
int main(int argc, const char *argv[])
{
	t_ring_buffer *r = NULL;
	int elem1 = 4;
	int elem2 = 6;
	int elem3 = 2;
	int elem4 = 3;
	gpointer oldelem = NULL;
	gpointer popelem = NULL;

	g_message("Test RingBuffer");
	
	r = ring_buffer_new(2);
	g_assert(NULL != r);

	oldelem = ring_buffer_push(r, &elem1);
	g_assert(NULL == oldelem);
	g_assert(1 == ring_buffer_stored_elements(r));

	oldelem = ring_buffer_push(r, &elem2);
	g_assert(NULL == oldelem);
	g_assert(2 == ring_buffer_stored_elements(r));
	
	oldelem = ring_buffer_push(r, &elem3);
	g_assert(NULL != oldelem && *((int *)oldelem) == elem1);
	g_assert(2 == ring_buffer_stored_elements(r));
	
	oldelem = ring_buffer_push(r, &elem4);
	g_assert(NULL != oldelem && *((int *)oldelem) == elem2);

	popelem = ring_buffer_pop(r);
	g_assert(NULL != popelem && *((int *)popelem) == elem4);

	popelem = ring_buffer_pop(r);
	g_assert(NULL != popelem && *((int *)popelem) == elem3);

	popelem = ring_buffer_pop(r);
	g_assert(NULL == popelem);
	g_assert(0 == ring_buffer_stored_elements(r));

	r = ring_buffer_free(r);
	g_assert(NULL == r);

	g_message("Test RingBuffer complete");

	return 0;
}
예제 #3
0
static void
test_pop_from_empty_buffer()
{
  RingBuffer rb;

  _ringbuffer_init(&rb);
  assert_true(ring_buffer_pop(&rb) == NULL, "cannot pop from empty buffer");

  ring_buffer_free(&rb);
}
예제 #4
0
static void
test_tail()
{
  RingBuffer rb;
  TestData *td_tail;

  ring_buffer_alloc(&rb, sizeof(TestData), 103);
  _ringbuffer_fill2(&rb, 103, 0, TRUE);

  ring_buffer_pop(&rb);

  td_tail = ring_buffer_tail(&rb);
  td_tail->idx = 103;

  assert_true(ring_buffer_push(&rb) == td_tail, "Push should return last tail.");

  assert_test_data_idx_range_in(&rb, 1, 103);

  ring_buffer_free(&rb);
}
예제 #5
0
static void
test_elements_ordering()
{
  RingBuffer rb;
  TestData *td;
  int start_from = 10;
  int cnt = 0;

  _ringbuffer_init(&rb);

  _ringbuffer_fill(&rb, capacity, start_from, TRUE);

  while ( (td = ring_buffer_pop(&rb)) )
    {
      assert_true((cnt + start_from) == td->idx, "wrong order; %d != %d", cnt, td->idx);
      ++cnt;
    }

  ring_buffer_free(&rb);
}
예제 #6
0
int main (int argc, const char* argv[])
{
	ring_buffer_t ring;
	ring_buffer_init(&ring, buf, sizeof(buf));

	while (1) {
		printf("av: %d/%d\nhead=%ld, tail=%ld\n\n> ",
			ring_buffer_av_data(&ring), ring_buffer_av_space(&ring),
			ring.head - ring.buffer, ring.tail - ring.buffer
		);

		size_t sz = 128;
		char* str = malloc(sz);
		int bytes = getline(&str, &sz, stdin);

		bytes--; // remove '\n'

		if (bytes > 0) {

			uint32_t pushed = ring_buffer_push(&ring, str, bytes);
			printf("push(%d) %d\n", bytes, pushed);

		} else if (bytes == 0) {

			uint32_t to_pop = 10;
			uint32_t popped = ring_buffer_pop(&ring, str, to_pop);
			printf("pop(%d) %d\n", to_pop, popped);
			if (popped > 0) {
				for (int i = 0; i < popped; i++) {
					printf("%c", str[i]);
				}
				printf("\n");
			}

		} else if (bytes < 0) {
			return -1;
		}
	}

	return 0;
}
예제 #7
0
static void
test_pop_all_pushed_element_in_correct_order()
{
  RingBuffer rb;
  int cnt = 0;
  const int start_from = 1;
  TestData *td = NULL;

  _ringbuffer_init(&rb);

  _ringbuffer_fill(&rb, capacity, 1, TRUE);

  while ((td = ring_buffer_pop(&rb)))
    {
      assert_true((cnt+start_from) == td->idx, "wrong order; %d != %d", td->idx, cnt);
      ++cnt;
    }

  assert_true(cnt == capacity, "cannot read all element, %d < %d", cnt, capacity);

  ring_buffer_free(&rb);
}
/** read from beginning of queue (and remove that element) */
int pop(struct buffer *buffer)
/*@ requires
  [?f]buffer(buffer, ?id_text, ?id_progress_read, ?id_progress_write)
  &*& token(id_progress_read, ?t1)
  &*& op(id_text, id_progress_read, t1, ?c, ?t2);
@*/
/*@ ensures
  [f]buffer(buffer, id_text, id_progress_read, id_progress_write)
  &*& token(id_progress_read, t2)
  &*& result == c;
@*/
{
  //@ open buffer(buffer, _, _, _);
  //@ assert [f]buffer->mutex |-> ?mutex;
  mutex_acquire(buffer->mutex);
  //@ open buffer_protected(buffer, id_text, id_progress_read, id_progress_write)();
  //@ open token(id_progress_read, ?n_read);
  //@ assert [_]ghost_cell<list<int> >(id_text, ?alltext);
  while (ring_buffer_is_empty(buffer->ring_buffer))
  /*@ invariant
      
      buffer->ring_buffer |-> ?ring_buffer
      &*& [f]buffer->mutex |-> mutex
      &*& ring_buffer(ring_buffer, ?size, ?contents)
      &*& [f]buffer->cond_can_pop |-> ?cond_can_pop
      &*& [f]mutex_cond(cond_can_pop, mutex)
      &*& mutex_held(mutex, (buffer_protected)(buffer, id_text, id_progress_read, id_progress_write), currentThread, f)
      
      &*& [_]ghost_cell<list<int> >(id_text, alltext)
      &*& [1/2]ghost_cell<int>(id_progress_write, ?n_write)
      &*& [1/2]ghost_cell<int>(id_progress_read, n_read)
      &*& [1/2]ghost_cell<int>(id_progress_read, n_read)
      &*& take(n_write - n_read, drop(n_read, alltext)) == contents
      ;
  @*/
  {
    //@ close buffer_protected(buffer, id_text, id_progress_read, id_progress_write)();
    mutex_cond_wait(buffer->cond_can_pop, buffer->mutex);
    //@ open buffer_protected(buffer, id_text, id_progress_read, id_progress_write)();
  }
  
  bool was_full = ring_buffer_is_full(buffer->ring_buffer);
  
  int x = ring_buffer_pop(buffer->ring_buffer);
  
  if (was_full){
    mutex_cond_signal(buffer->cond_can_push);
  }
  
  //@ ghost_cell_mutate(id_progress_read, t2);
  //@ close token(id_progress_read, t2);
  //@ open op(_, _, _, c, _);
  
  //@ assert c == nth(t1, alltext);
  //@ assert x == head(contents);
  //@ assert x == head(take(n_write - n_read, drop(n_read, alltext)));
  //@ assume (x == nth(n_read, alltext));
  //@ assert c == x;
  
  //@ assert take(n_write - n_read, drop(n_read, alltext)) == contents;
  //@ assume (take(n_write - (n_read + 1), drop((n_read+1), alltext)) == tail(contents));
  
  //@ close buffer_protected(buffer, id_text, id_progress_read, id_progress_write)();
  mutex_release(buffer->mutex);
  //@ close [f]buffer(buffer, id_text, id_progress_read, id_progress_write);
  return x;
}
예제 #9
0
/**
 * Reads one integer from the given queue.
 * 
 * This is blocking. If the queue is empty, this function waits until the queue is not empty anymore.
 */
int getchar/*@<u> @*/(struct queue *queue, struct proph_tree *tree)
//@ requires [?f_queue]queue(?queue_id, queue) &*& getchar_io<u>(queue_id, ?t1, ?c, ?t2, tree) &*& token(t1);
//@ ensures  [f_queue]queue(queue_id, queue) &*& token(t2) &*& result == c;
{
  //@ open [f_queue]queue(_,_);
  //@ assert [f_queue]queue->mutex |-> ?mutex; // bind mutex so we know it won't change.
  mutex_acquire(queue->mutex);
  //@ open queue_invariant(queue_id, queue)();
  
  //@ open token(t1);
   
  while (ring_buffer_is_empty(queue->ring_buffer))
  /*@ invariant
    // from queue:
    [f_queue]queue->mutex |-> mutex
    &*& [f_queue]queue->cond_can_pop |-> ?cond_can_pop
    &*& [f_queue]mutex_cond(cond_can_pop, mutex)
    
    // from the mutex:
    &*& queue->ring_buffer |-> ?buffer
    &*& ring_buffer(buffer, _, ?buffer_contents)
    &*& [1/2]ghost_cell<list<int> >(queue_id, buffer_contents)
    &*& mutex_held(mutex, (queue_invariant)(queue_id, queue), currentThread, f_queue);
  @*/
  {
    //@ close queue_invariant(queue_id, queue)();
    mutex_cond_wait(queue->cond_can_pop, queue->mutex);
    //@ open queue_invariant(queue_id, queue)();
  }
  
  bool was_full = ring_buffer_is_full(queue->ring_buffer);
  
  //@ open getchar_io(queue_id, t1, c, t2, _);
  
  int ret = ring_buffer_pop(queue->ring_buffer);
  //@ open proph_tree(_, _, _, _, _);
  prophecy_assign(tree->id, ret);
  free(tree);
  
  if (was_full){
    mutex_cond_signal(queue->cond_can_push);
  }
  
  /*@
  {
    predicate pre() =
      [1/2]ghost_cell<list<int> >(queue_id, buffer_contents)
      &*& c == head(buffer_contents)
      &*& token_without_invar(t1)
      &*& is_getchar_invar_updatable(?invar_updater, queue_id, t1, c, t2);
    predicate post() =
      [1/2]ghost_cell(queue_id, tail(buffer_contents))
      &*& token_without_invar(t2);
    
    close pre();
    produce_lemma_function_pointer_chunk(empty_lemma) : ghost_mutex_critical_section_t(place_io_invar(t1), pre, post)()
    {
      open pre();
      assert is_getchar_invar_updatable(?invar_updater, queue_id, t1, c, t2);
      close exists(place_io_invar(t1));
      open token_without_invar(t1);
      invar_updater();
      close token_without_invar(t2);
      close post();
      leak is_getchar_invar_updatable(_, _, _, _, _);
      call();
    }
    {
      ghost_mutex_use(place_mutex(t1), pre, post);
    }
    open post();
  }
  @*/
  
  //@ close queue_invariant(queue_id, queue)();
  mutex_release(queue->mutex);
  //@ close [f_queue]queue(queue_id, queue);
  
  return ret;
}