Пример #1
0
static void queue_jlog_enqueue(fqd_queue_impl_data f, fq_msg *m) {
  struct queue_jlog *d = (struct queue_jlog *)f;
  size_t wlen;
  wlen = offsetof(fq_msg, payload) + m->payload_len;
  if(jlog_ctx_write(d->writer, m, wlen) != 0) {
    ck_pr_inc_uint(&d->errors);
  }
  ck_pr_inc_uint(&d->nenqueued);
}
Пример #2
0
static void *
fq_data_worker(void *u) {
  int backoff = 0;
  bool zero;
  fq_conn_s *conn_s = (fq_conn_s *)u;

  ck_pr_inc_uint(&conn_s->thrcnt);

  while(conn_s->stop == 0) {
    if(conn_s->data_ready) {
      if(fq_client_data_connect_internal(conn_s) == 0) {
        backoff = 0; /* we're good, restart our backoff */
      }
      fq_debug(FQ_DEBUG_IO, "[data] connected\n");
      fq_data_worker_loop(conn_s);
      fq_debug(FQ_DEBUG_IO, "[data] connection failed: %s\n", conn_s->error);
    }
    if(backoff) usleep(backoff + (4096 - (lrand48()%8192)));  /* +/- 4ms */
    else backoff = 16384;
    if(backoff < 1000000) backoff += (backoff >> 4);
  }
  if(conn_s->data_fd >= 0) {
    int toclose = conn_s->data_fd;
    conn_s->data_fd = -1;
    fq_debug(FQ_DEBUG_CONN, "close(data_fd)\n");
    close(toclose);
  }

  ck_pr_dec_uint_zero(&conn_s->thrcnt, &zero);
  if(zero) fq_conn_free(conn_s);
  return (void *)NULL;
}
Пример #3
0
static void *
test(void *c)
{
	struct context *context = c;
	struct entry *entry;
	ck_fifo_spsc_entry_t *fifo_entry;
	int i, j;

        if (aff_iterate(&a)) {
                perror("ERROR: Could not affine thread");
                exit(EXIT_FAILURE);
        }

#ifdef DEBUG
	fprintf(stderr, "%p %u: %u -> %u\n", fifo+context->tid, context->tid, context->previous, context->tid);
#endif

	if (context->tid == 0) {
		struct entry *entries;

		entries = malloc(sizeof(struct entry) * size);
		assert(entries != NULL);

		for (i = 0; i < size; i++) {
			entries[i].value = i;
			entries[i].tid = 0;

			fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t));
			ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entries + i);
		}
	}

	ck_pr_inc_uint(&barrier);
	while (ck_pr_load_uint(&barrier) < (unsigned int)nthr);

	for (i = 0; i < ITERATIONS; i++) {
		for (j = 0; j < size; j++) {
			while (ck_fifo_spsc_dequeue(fifo + context->previous, &entry) == false);
			if (context->previous != (unsigned int)entry->tid) {
				ck_error("T [%u:%p] %u != %u\n",
					context->tid, (void *)entry, entry->tid, context->previous);
			}

			if (entry->value != j) {
				ck_error("V [%u:%p] %u != %u\n",
					context->tid, (void *)entry, entry->value, j);
			}

			entry->tid = context->tid;
			fifo_entry = ck_fifo_spsc_recycle(fifo + context->tid);
			if (fifo_entry == NULL)
				fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t));

			ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entry);
		}
	}

	return (NULL);
}
Пример #4
0
static void *
test(void *c)
{
	struct context *context = c;
	struct entry *entry;
	ck_hp_fifo_entry_t *fifo_entry;
	ck_hp_record_t record;
	int i, j;

        if (aff_iterate(&a)) {
                perror("ERROR: Could not affine thread");
                exit(EXIT_FAILURE);
        }

	ck_hp_register(&fifo_hp, &record, malloc(sizeof(void *) * 2));
	ck_pr_inc_uint(&barrier);
	while (ck_pr_load_uint(&barrier) < (unsigned int)nthr);

	for (i = 0; i < ITERATIONS; i++) {
		for (j = 0; j < size; j++) {
			fifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));
			entry = malloc(sizeof(struct entry));
			entry->tid = context->tid;
			ck_hp_fifo_enqueue_mpmc(&record, &fifo, fifo_entry, entry);

			fifo_entry = ck_hp_fifo_dequeue_mpmc(&record, &fifo, &entry);
			if (fifo_entry == NULL) {
				fprintf(stderr, "ERROR [%u] Queue should never be empty.\n", context->tid);
				exit(EXIT_FAILURE);
			}

			if (entry->tid < 0 || entry->tid >= nthr) {
				fprintf(stderr, "ERROR [%u] Incorrect value in entry.\n", entry->tid);
				exit(EXIT_FAILURE);
			}

			ck_hp_free(&record, &fifo_entry->hazard, fifo_entry, fifo_entry);
		}
	}

	ck_pr_inc_uint(&e_barrier);
	while (ck_pr_load_uint(&e_barrier) < (unsigned int)nthr);

	return (NULL);
}
Пример #5
0
Файл: order.c Проект: binque/ck
static void *
writer_thread(void *unused)
{
	unsigned int i;
	unsigned int iteration = 0;

	(void)unused;

	for (;;) {
		iteration++;
		ck_epoch_write_begin(&epoch_wr);
		for (i = 1; i <= writer_max; i++) {
			if (ck_bag_put_spmc(&bag, (void *)(uintptr_t)i) == false) {
				perror("ck_bag_put_spmc");
				exit(EXIT_FAILURE);
			}

			if (ck_bag_member_spmc(&bag, (void *)(uintptr_t)i) == false) {
				fprintf(stderr, "ck_bag_put_spmc [%u]: %u\n", iteration, i);
				exit(EXIT_FAILURE);
			}
		}

		if (ck_pr_load_int(&leave) == 1)
			break;

		for (i = 1; i < writer_max; i++) {
			void *replace = (void *)(uintptr_t)i;
			if (ck_bag_set_spmc(&bag, (void *)(uintptr_t)i, replace) == false) {
				fprintf(stderr, "ERROR: set %ju != %ju",
						(uintmax_t)(uintptr_t)replace, (uintmax_t)i);
				exit(EXIT_FAILURE);
			}
		}

		for (i = writer_max; i > 0; i--) {
			if (ck_bag_member_spmc(&bag, (void *)(uintptr_t)i) == false) {
				fprintf(stderr, "ck_bag_member_spmc [%u]: %u\n", iteration, i);
				exit(EXIT_FAILURE);
			}

			if (ck_bag_remove_spmc(&bag, (void *)(uintptr_t)i) == false) {
				fprintf(stderr, "ck_bag_remove_spmc [%u]: %u\n", iteration, i);
				exit(EXIT_FAILURE);
			}
		}

		ck_epoch_write_end(&epoch_wr);
	}

	fprintf(stderr, "Writer %u iterations, %u writes per iteration.\n", iteration, writer_max);
	while (ck_pr_load_uint(&barrier) != NUM_READER_THREADS)
		ck_pr_stall();

	ck_pr_inc_uint(&barrier);
	return NULL;
}
Пример #6
0
static void *
test(void *c)
{
#ifdef CK_F_FIFO_MPMC
	struct context *context = c;
	struct entry *entry;
	ck_fifo_mpmc_entry_t *fifo_entry, *garbage;
	int i, j;

        if (aff_iterate(&a)) {
                perror("ERROR: Could not affine thread");
                exit(EXIT_FAILURE);
        }

	ck_pr_inc_uint(&barrier);
	while (ck_pr_load_uint(&barrier) < (unsigned int)nthr);

	for (i = 0; i < ITERATIONS; i++) {
		for (j = 0; j < size; j++) {
			fifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t));
			entry = malloc(sizeof(struct entry));
			entry->tid = context->tid;
			ck_fifo_mpmc_enqueue(&fifo, fifo_entry, entry);
			if (ck_fifo_mpmc_dequeue(&fifo, &entry, &garbage) == false) {
				fprintf(stderr, "ERROR [%u] Queue should never be empty.\n", context->tid);
				exit(EXIT_FAILURE);
			}

			if (entry->tid < 0 || entry->tid >= nthr) {
				fprintf(stderr, "ERROR [%u] Incorrect value in entry.\n", entry->tid);
				exit(EXIT_FAILURE);
			}
		}
	}

	for (i = 0; i < ITERATIONS; i++) {
		for (j = 0; j < size; j++) {
			fifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t));
			entry = malloc(sizeof(struct entry));
			entry->tid = context->tid;
			while (ck_fifo_mpmc_tryenqueue(&fifo, fifo_entry, entry) == false)
				ck_pr_stall();

			while (ck_fifo_mpmc_trydequeue(&fifo, &entry, &garbage) == false)
				ck_pr_stall();

			if (entry->tid < 0 || entry->tid >= nthr) {
				fprintf(stderr, "ERROR [%u] Incorrect value in entry when using try interface.\n", entry->tid);
				exit(EXIT_FAILURE);
			}
		}
	}
#endif

	return (NULL);
}
Пример #7
0
void
fq_client_publish(fq_client conn, fq_msg *msg) {
  fq_conn_s *conn_s = conn;
  ck_fifo_mpmc_entry_t *fifo_entry;
  while(conn_s->qlen > conn_s->qmaxlen) {
    if(conn_s->q_stall_time > 0) usleep(conn_s->q_stall_time);
    else ck_pr_stall();
  }
  fifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t));
  fq_msg_ref(msg);
  ck_fifo_mpmc_enqueue(&conn_s->q, fifo_entry, msg);
  ck_pr_inc_uint(&conn_s->qlen);
}
Пример #8
0
static CK_CC_INLINE void
rwlock_read_lock(rwlock_t *rw)
{

        for (;;) {
                while (ck_pr_load_uint(&rw->writer.value) != 0)
                        ck_pr_stall();

                ck_pr_inc_uint(&rw->readers);
                if (ck_pr_load_uint(&rw->writer.value) == 0)
                        break;
                ck_pr_dec_uint(&rw->readers);
        }

        return;
}
Пример #9
0
static void *
fairness(void *null)
{
	struct block *context = null;
	unsigned int i = context->tid;
	volatile int j;
	long int base;
	unsigned int core;
	CK_COHORT_INSTANCE(basic) *cohort;


	if (aff_iterate_core(&a, &core)) {
		perror("ERROR: Could not affine thread");
		exit(EXIT_FAILURE);
	}

	cohort = &((cohorts + (core / (int)(a.delta)) % n_cohorts)->cohort);

	while (ck_pr_load_uint(&ready) == 0);

	ck_pr_inc_uint(&barrier);
	while (ck_pr_load_uint(&barrier) != nthr);

	while (ready) {
		CK_COHORT_LOCK(basic, cohort, NULL, NULL);

		count[i].value++;
		if (critical) {
			base = common_lrand48() % critical;
			for (j = 0; j < base; j++);
		}

		CK_COHORT_UNLOCK(basic, cohort, NULL, NULL);
	}

	return NULL;
}
Пример #10
0
static void *
fq_conn_worker(void *u) {
  int backoff = 0, i;
  bool zero;
  fq_conn_s *conn_s = (fq_conn_s *)u;
  cmd_instr *last_entries[MAX_PENDING] = { NULL };
  int last_entry_idx = 0;
  int next_entry_idx = 0;

#define SAVE_ENTRY(e) do { \
  if(last_entries[next_entry_idx] != NULL) { \
    CONNERR(conn_s, "exceed max cmd pipeline"); \
    goto restart; \
  } \
  last_entries[next_entry_idx++] = e; \
  next_entry_idx = next_entry_idx % MAX_PENDING; \
} while(0)
#define last_entry last_entries[last_entry_idx]
#define PROCESS_ENTRY(e, should_free) do { \
  fq_assert(last_entries[last_entry_idx] == e); \
  if(should_free) free(last_entries[last_entry_idx]); \
  last_entries[last_entry_idx++] = NULL; \
  last_entry_idx = last_entry_idx % MAX_PENDING; \
} while(0)

  cmd_instr *entry;

  ck_pr_inc_uint(&conn_s->thrcnt);

  while(conn_s->stop == 0) {
    int wait_ms = 50;
    if(fq_client_connect_internal(conn_s) == 0) {
      backoff = 0; /* we're good, restart our backoff */
    }
    while(conn_s->data_ready && conn_s->stop == 0) {
      hrtime_t t;
      unsigned long long hb_us;
      struct timeval tv;
      int rv;

      ck_fifo_spsc_dequeue_lock(&conn_s->cmdq);
      while(ck_fifo_spsc_dequeue(&conn_s->cmdq, &entry) == true) {
#ifdef DEBUG
        fq_debug(FQ_DEBUG_CONN, "client acting on user req 0x%04x\n", entry->cmd);
#endif
        switch(entry->cmd) {
          case FQ_PROTO_STATUSREQ:
            fq_debug(FQ_DEBUG_CONN, "sending status request\n");
            if(fq_write_uint16(conn_s->cmd_fd, entry->cmd)) {
              free(entry);
              CONNERR(conn_s, "write failed (statusreq)");
              goto restart;
            }
            SAVE_ENTRY(entry);
            break;
          case FQ_PROTO_HBREQ:
            fq_debug(FQ_DEBUG_CONN, "sending heartbeat request\n");
            if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
               fq_write_uint16(conn_s->cmd_fd, entry->data.heartbeat.ms)) {
              free(entry);
              CONNERR(conn_s, "write failed (hbreq)");
              goto restart;
            }
            conn_s->cmd_hb_ms = entry->data.heartbeat.ms;
            tv.tv_sec = (unsigned long)entry->data.heartbeat.ms / 1000;
            tv.tv_usec = 1000UL * (entry->data.heartbeat.ms % 1000);
            if(setsockopt(conn_s->cmd_fd, SOL_SOCKET, SO_RCVTIMEO,
                          &tv, sizeof(tv)))
              CONNERR(conn_s, strerror(errno));
            tv.tv_sec = (unsigned long)entry->data.heartbeat.ms / 1000;
            tv.tv_usec = 1000UL * (entry->data.heartbeat.ms % 1000);
            if(setsockopt(conn_s->cmd_fd, SOL_SOCKET, SO_SNDTIMEO,
                          &tv, sizeof(tv)))
              CONNERR(conn_s, strerror(errno));
            conn_s->cmd_hb_last = fq_gethrtime();
            free(entry);
            break;
          case FQ_PROTO_BINDREQ:
            {
              unsigned short flags = entry->data.bind->flags;
              if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
                 fq_write_uint16(conn_s->cmd_fd, flags) ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    entry->data.bind->exchange.len,
                                    entry->data.bind->exchange.name) < 0 ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    strlen(entry->data.bind->program),
                                    entry->data.bind->program) < 0) {
	CONNERR(conn_s, "write failed (bindreq)");
                goto restart;
              }
              SAVE_ENTRY(entry);
            }
            break;
          case FQ_PROTO_UNBINDREQ:
            {
              if(fq_write_uint16(conn_s->cmd_fd, entry->cmd) ||
                 fq_write_uint32(conn_s->cmd_fd, entry->data.unbind->route_id) ||
                 fq_write_short_cmd(conn_s->cmd_fd,
                                    entry->data.unbind->exchange.len,
                                    entry->data.unbind->exchange.name) < 0) {
	CONNERR(conn_s, "write failed (unbindreq)");
                goto restart;
              }
              SAVE_ENTRY(entry);
            }
            break;
          default:
            CONNERR(conn_s, "unknown user-side cmd");
            free(entry);
        }
      }
      ck_fifo_spsc_dequeue_unlock(&conn_s->cmdq);

      if(conn_s->cmd_hb_needed) {
#ifdef DEBUG
          fq_debug(FQ_DEBUG_CONN, "-> heartbeat\n");
#endif
        if(fq_write_uint16(conn_s->cmd_fd, FQ_PROTO_HB)) {
          CONNERR(conn_s, "write failed (hb)");
          break;
        }
        conn_s->cmd_hb_needed = 0;
      }

      rv = fq_client_wfrw_internal(conn_s->cmd_fd, 1, 0, wait_ms, NULL);
      if(rv == 0) {
        wait_ms = (wait_ms >> 2) + wait_ms;
        if(conn_s->cmd_hb_ms && wait_ms > conn_s->cmd_hb_ms)
          wait_ms = conn_s->cmd_hb_ms;
        if(wait_ms > 1000) wait_ms = 1000;
      }
      else wait_ms = 50;
      fq_debug(FQ_DEBUG_CONN, "fq_client_wfrw_internal(cmd:%d) -> %d\n", conn_s->cmd_fd, rv);
      t = fq_gethrtime();
      hb_us = (unsigned long long)conn_s->cmd_hb_ms * 3 * 1000000ULL;
      if(conn_s->cmd_hb_last && hb_us &&
         conn_s->cmd_hb_last < (unsigned int) (t - hb_us)) {
        char errbuf[256];
        snprintf(errbuf, sizeof(errbuf), "heartbeat failed [%llu - %llu = %llu]",
                 (unsigned long long)t, (unsigned long long)conn_s->cmd_hb_last,
                 (unsigned long long)(t - conn_s->cmd_hb_last));
        CONNERR(conn_s, errbuf);
        break;
      }
      if(rv < 0) {
        CONNERR(conn_s, strerror(errno));
        break;
      }
      if(rv > 0) {
        bool handled = false;
        uint16_t hb;
        if(fq_read_uint16(conn_s->cmd_fd, &hb)) break;
        switch(hb) {
          case FQ_PROTO_HB:
#ifdef DEBUG
            fq_debug(FQ_DEBUG_CONN, "<- heartbeat\n");
#endif
            conn_s->cmd_hb_last = fq_gethrtime();
            conn_s->cmd_hb_needed = 1;
            break;
          case FQ_PROTO_STATUS:
            if(!last_entry || last_entry->cmd != FQ_PROTO_STATUSREQ) {
              CONNERR(conn_s, "protocol violation (status unexpected)");
              goto restart;
            }
            if(fq_read_status(conn_s->cmd_fd,
                              last_entry->data.status.callback,
                              last_entry->data.status.closure))
              goto restart;
            PROCESS_ENTRY(last_entry, 1);
            break;
          case FQ_PROTO_BIND:
            if(!last_entry || last_entry->cmd != FQ_PROTO_BINDREQ) {
              CONNERR(conn_s, "protocol violation (bind unexpected)");
              goto restart;
            }
            if(fq_read_uint32(conn_s->cmd_fd,
                              &last_entry->data.bind->out__route_id)) {
              if(conn_s->bind_hook) {
                if(conn_s->sync_hooks) {
                  enqueue_cmd_hook_req(conn_s, last_entry);
	  PROCESS_ENTRY(last_entry, 0);
	  handled = true;
                }
                else conn_s->bind_hook((fq_client)conn_s, last_entry->data.bind);
              }
              CONNERR(conn_s, "read failed (bind)");
              goto restart;
            }
            if(conn_s->bind_hook) {
              if(conn_s->sync_hooks) {
                enqueue_cmd_hook_req(conn_s, last_entry);
	PROCESS_ENTRY(last_entry, 0);
	handled = true;
              }
              else conn_s->bind_hook((fq_client)conn_s, last_entry->data.bind);
            }
            if(!handled) PROCESS_ENTRY(last_entry, 1);
            break;
          case FQ_PROTO_UNBIND:
            if(!last_entry || last_entry->cmd != FQ_PROTO_UNBINDREQ) {
              CONNERR(conn_s, "protocol violation (unbind unexpected)");
              goto restart;
            }
            if(fq_read_uint32(conn_s->cmd_fd,
                              &last_entry->data.unbind->out__success)) {
              if(conn_s->unbind_hook) {
                if(conn_s->sync_hooks) {
                  enqueue_cmd_hook_req(conn_s, last_entry);
                  PROCESS_ENTRY(last_entry, 0);
	  handled = true;
                }
                conn_s->unbind_hook((fq_client)conn_s, last_entry->data.unbind);
              }
              CONNERR(conn_s, "read failed (unbind)");
              goto restart;
            }
            if(conn_s->unbind_hook) {
              if(conn_s->sync_hooks) {
                enqueue_cmd_hook_req(conn_s, last_entry);
                PROCESS_ENTRY(last_entry, 0);
	handled = true;
                last_entry = NULL;
              }
              conn_s->unbind_hook((fq_client)conn_s, last_entry->data.unbind);
            }
            if(!handled) PROCESS_ENTRY(last_entry,1);
            break;
          default:
            CONNERR(conn_s, "protocol violation");
            goto restart;
            break;
        }
      }
    }
Пример #11
0
static void *
thread(void *null)
{
	struct block *context = null;
	int i = ITERATE;
	unsigned int l;

        if (aff_iterate(&a)) {
                perror("ERROR: Could not affine thread");
                exit(EXIT_FAILURE);
        }

	if (context->tid == (unsigned int)nthr - 1)
		context->tid = sizeof(lock.readers) + 1;

	while (i--) {
		ck_bytelock_write_lock(&lock, context->tid);
		{
			l = ck_pr_load_uint(&locked);
			if (l != 0) {
				ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
			}

			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);
			ck_pr_inc_uint(&locked);

			l = ck_pr_load_uint(&locked);
			if (l != 8) {
				ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
			}

			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);
			ck_pr_dec_uint(&locked);

			l = ck_pr_load_uint(&locked);
			if (l != 0) {
				ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
			}
		}
		ck_bytelock_write_unlock(&lock);

		ck_bytelock_read_lock(&lock, context->tid);
		{
			l = ck_pr_load_uint(&locked);
			if (l != 0) {
				ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
			}
		}
		ck_bytelock_read_unlock(&lock, context->tid);
	}

	return (NULL);
}
Пример #12
0
void
fqd_remote_client_ref(remote_client *r) {
  ck_pr_inc_uint(&r->refcnt);
}
Пример #13
0
int
main(int argc, char** argv)
{
        ck_hp_fifo_entry_t *stub;
        unsigned long element_count, i;
	pthread_t *thr;

        if (argc != 3) {
        	ck_error("Usage: cktest <thread_count> <element_count>\n");
        }

        /* Get element count from argument */
        element_count = atoi(argv[2]);

	/* Get element count from argument */
        thread_count = atoi(argv[1]);

	/* pthread handles */
	thr = malloc(sizeof(pthread_t) * thread_count);

	/* array for local operation count */
	count = malloc(sizeof(unsigned long *) * thread_count);
	
        /*
         * Initialize global hazard pointer safe memory reclamation to execute free()
         * when a fifo_entry is safe to be deleted.
         * Hazard pointer scan routine will be called when the thread local intern plist's
         * size exceed 100 entries.
         */

	/* FIFO queue needs 2 hazard pointers */
	ck_hp_init(&fifo_hp, CK_HP_FIFO_SLOTS_COUNT, 100, destructor);

        /* The FIFO requires one stub entry on initialization. */
        stub = malloc(sizeof(ck_hp_fifo_entry_t));

        /* Behavior is undefined if stub is NULL. */
        if (stub == NULL) {
                exit(EXIT_FAILURE);
	}

        /* This is called once to initialize the fifo. */
        ck_hp_fifo_init(&fifo, stub);

	/* Create threads */
	for (i = 0; i < thread_count; i++) {
		count[i] = (element_count + i) / thread_count;
		if (pthread_create(&thr[i], NULL, queue_50_50, (void *) &count[i]) != 0) {
                	exit(EXIT_FAILURE);
                }
	}

	/* start barrier */
	ck_pr_inc_uint(&start_barrier);
	while (ck_pr_load_uint(&start_barrier) < thread_count + 1);

	/* end barrier */
	ck_pr_inc_uint(&end_barrier);
	while (ck_pr_load_uint(&end_barrier) < thread_count + 1);

	/* Join threads */
	for (i = 0; i < thread_count; i++)
		pthread_join(thr[i], NULL);

        return 0;
}
Пример #14
0
Файл: order.c Проект: binque/ck
static void *
reader(void *arg)
{
	void *curr_ptr;
	intptr_t curr, prev, curr_max, prev_max;
	unsigned long long n_entries = 0, iterations = 0;
	ck_epoch_record_t epoch_record;
	ck_bag_iterator_t iterator;
	struct ck_bag_block *block = NULL;

	(void)arg;

	ck_epoch_register(&epoch_bag, &epoch_record);

	/*
	 * Check if entries within a block are sequential. Since ck_bag inserts
	 * newly occupied blocks at the beginning of the list, there is no ordering
	 * guarantee across the bag.
	 */
	for (;;) {
		ck_epoch_read_begin(&epoch_record);
		ck_bag_iterator_init(&iterator, &bag);
		curr_max = prev_max = prev = -1;
		block = NULL;

		while (ck_bag_next(&iterator, &curr_ptr) == true) {
			if (block != iterator.block) {
				prev = -1;
				curr = 0;
				prev_max = curr_max;
				curr_max = 0;
				block = iterator.block;
			}

			curr = (uintptr_t)(curr_ptr);
			if (curr < prev) {
				/* Ascending order within block violated */
				fprintf(stderr, "%p: %p: %ju\n", (void *)&epoch_record, (void *)iterator.block, (uintmax_t)curr);
				fprintf(stderr, "ERROR: %ju < %ju \n",
				    (uintmax_t)curr, (uintmax_t)prev);
				exit(EXIT_FAILURE);
			} else if (prev_max != -1 && curr > prev_max) {
				/* Max of prev block > max of current block */
				fprintf(stderr, "%p: %p: %ju\n", (void *)&epoch_record, (void *)iterator.block, (uintmax_t)curr);
				fprintf(stderr, "ERROR: %ju > prev_max: %ju\n",
				    (uintmax_t)curr, (uintmax_t)prev_max);
				exit(EXIT_FAILURE);
			}

			curr_max = curr;

			prev = curr;
			n_entries++;
		}

		ck_epoch_read_end(&epoch_record);

		iterations++;
		if (ck_pr_load_int(&leave) == 1)
			break;
	}

	fprintf(stderr, "Read %llu entries in %llu iterations.\n", n_entries, iterations);

	ck_pr_inc_uint(&barrier);
	while (ck_pr_load_uint(&barrier) != NUM_READER_THREADS + 1)
		ck_pr_stall();

	return NULL;

}
Пример #15
0
void
fq_msg_ref(fq_msg *msg) {
  ck_pr_inc_uint(&msg->refcnt);
}
Пример #16
0
static fq_msg *queue_jlog_dequeue(fqd_queue_impl_data f) {
  struct queue_jlog *d = (struct queue_jlog *)f;
  jlog_message msg;
  fq_msg *m;
  if(d->count == 0 && d->last_seen_nenqueued == d->nenqueued) return NULL;
 retry:
  if(d->count <= 0) {
    d->count = jlog_ctx_read_interval(d->reader, &d->start, &d->finish);
    fq_debug(FQ_DEBUG_IO, "jlog read batch count -> %d\n", d->count);
    if(d->count < 0) {
      char idxfile[PATH_MAX];
      fq_debug(FQ_DEBUG_IO, "jlog_ctx_read_interval: %s\n",
               jlog_ctx_err_string(d->reader));
      switch (jlog_ctx_err(d->reader)) {
        case JLOG_ERR_FILE_CORRUPT:
        case JLOG_ERR_IDX_CORRUPT:
          jlog_repair_datafile(d->reader, d->start.log);
          jlog_repair_datafile(d->reader, d->start.log + 1);
          fq_debug(FQ_DEBUG_IO,
                "jlog reconstructed, deleting corresponding index.\n");
          STRSETDATAFILE(d->reader, idxfile, d->start.log);
          strncpy(idxfile + strlen(idxfile), INDEX_EXT, sizeof(idxfile) - strlen(idxfile));
          unlink(idxfile);
          STRSETDATAFILE(d->reader, idxfile, d->start.log + 1);
          strncpy(idxfile + strlen(idxfile), INDEX_EXT, sizeof(idxfile) - strlen(idxfile));
          unlink(idxfile);
          break;
        default:
          break;
      }
    }
    if(d->count <= 0) return NULL;
  }
  if(jlog_ctx_read_message(d->reader, &d->start, &msg) == -1) {
    d->count = 0;
    return NULL;
  }
  if(d->last_dequeued.log > d->start.log ||
     (d->last_dequeued.log == d->start.log &&
      d->last_dequeued.marker > d->start.marker)) {
    d->count--;
    JLOG_ID_ADVANCE(&d->start);
    goto retry;
  }
  if(msg.mess_len < sizeof(fq_msg)-1)
    m = NULL;
  else {
    off_t expected_len;
    uint32_t payload_len;
    m = (fq_msg *)msg.mess;
    memcpy(&payload_len, &m->payload_len, sizeof(m->payload_len));
    expected_len = offsetof(fq_msg, payload) + payload_len;
    if(expected_len != msg.mess_len) m = NULL;
    else {
      m = malloc(expected_len);
      memcpy(m, msg.mess, expected_len);
      m->sender_msgid.id.u32.p3 = d->start.log;
      m->sender_msgid.id.u32.p4 = d->start.marker;
    }
  }
  d->count--;
  fq_debug(FQ_DEBUG_IO, "jlog batch count -> %d\n", d->count);
  if(d->count == 0) {
    if(d->auto_chkpt) {
      jlog_ctx_read_checkpoint(d->reader, &d->start);
    }
  }
  d->last_dequeued = d->start;
  JLOG_ID_ADVANCE(&d->start);
  ck_pr_inc_uint(&d->last_seen_nenqueued);
  return m;
}
Пример #17
0
/* function for thread */
static void *
queue_50_50(void *elements)
{
        struct entry *entry;
        ck_hp_fifo_entry_t *fifo_entry;
	ck_hp_record_t *record;
	void *slots;
        unsigned long j, element_count = *(unsigned long *)elements;
	unsigned int seed;

	record = malloc(sizeof(ck_hp_record_t));
	assert(record);
	
	slots = malloc(CK_HP_FIFO_SLOTS_SIZE);
	assert(slots);
	
        /* different seed for each thread */
	seed = 1337; /*(unsigned int) pthread_self(); */

        /*
         * This subscribes the thread to the fifo_hp state using the thread-owned
         * record.
         * FIFO queue needs 2 hazard pointers.
         */
        ck_hp_register(&fifo_hp, record, slots);

	/* start barrier */
	ck_pr_inc_uint(&start_barrier);
	while (ck_pr_load_uint(&start_barrier) < thread_count + 1)
		ck_pr_stall();

	/* 50/50 enqueue-dequeue */
	for(j = 0; j < element_count; j++) {
		/* rand_r with thread local state should be thread safe */
		if( 50 < (1+(int) (100.0*common_rand_r(&seed)/(RAND_MAX+1.0)))) {
			/* This is the container for the enqueued data. */
        		fifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));

        		if (fifo_entry == NULL) {
        	        	exit(EXIT_FAILURE);
			}

        		/* This is the data. */
        		entry = malloc(sizeof(struct entry));
        		if (entry != NULL) {
        	        	entry->value = j;
			}

        	       /*
        	 	* Enqueue the value of the pointer entry into FIFO queue using the
        	 	* container fifo_entry.
        	 	*/
        		ck_hp_fifo_enqueue_mpmc(record, &fifo, fifo_entry, entry);
		} else {
			/*
        		 * ck_hp_fifo_dequeue_mpmc will return a pointer to the first unused node and store
        		 * the value of the first pointer in the FIFO queue in entry.
        		 */
  		      	fifo_entry = ck_hp_fifo_dequeue_mpmc(record, &fifo, &entry);
        		if (fifo_entry != NULL) {
               		 	/*
               		 	 * Safely reclaim memory associated with fifo_entry.
                		 * This inserts garbage into a local list. Once the list (plist) reaches
      			       	 * a length of 100, ck_hp_free will attempt to reclaim all references
                		 * to objects on the list.
        		       	 */
                		ck_hp_free(record, &fifo_entry->hazard, fifo_entry, fifo_entry);
        		}
		}
	}

	/* end barrier */
	ck_pr_inc_uint(&end_barrier);
	while (ck_pr_load_uint(&end_barrier) < thread_count + 1)
		ck_pr_stall();

       	return NULL;
}