|
|
@ -39,10 +39,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include <ck_pr.h>
|
|
|
|
#include <ck_pr.h>
|
|
|
|
#include <ck_cohort.h>
|
|
|
|
#include <ck_cohort.h>
|
|
|
|
|
|
|
|
#include <ck_md.h>
|
|
|
|
#include <ck_spinlock.h>
|
|
|
|
#include <ck_spinlock.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "../../common.h"
|
|
|
|
#include "../../common.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
|
|
|
|
|
|
|
|
|
|
|
static struct affinity a;
|
|
|
|
static struct affinity a;
|
|
|
|
static unsigned int ready;
|
|
|
|
static unsigned int ready;
|
|
|
|
|
|
|
|
|
|
|
@ -58,24 +61,24 @@ static unsigned int barrier;
|
|
|
|
int critical __attribute__((aligned(64)));
|
|
|
|
int critical __attribute__((aligned(64)));
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
ck_spinlock_ticket_lock_with_context(ck_spinlock_ticket_t *lock, void *context)
|
|
|
|
ck_spinlock_lock_with_context(ck_spinlock_t *lock, void *context)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)context;
|
|
|
|
(void)context;
|
|
|
|
ck_spinlock_ticket_lock(lock);
|
|
|
|
ck_spinlock_lock(lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
ck_spinlock_ticket_unlock_with_context(ck_spinlock_ticket_t *lock, void *context)
|
|
|
|
ck_spinlock_unlock_with_context(ck_spinlock_t *lock, void *context)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)context;
|
|
|
|
(void)context;
|
|
|
|
ck_spinlock_ticket_unlock(lock);
|
|
|
|
ck_spinlock_unlock(lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CK_COHORT_PROTOTYPE(ticket_ticket,
|
|
|
|
CK_COHORT_PROTOTYPE(basic,
|
|
|
|
ck_spinlock_ticket_t, ck_spinlock_ticket_lock_with_context, ck_spinlock_ticket_unlock_with_context,
|
|
|
|
ck_spinlock_t, ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context,
|
|
|
|
ck_spinlock_ticket_t, ck_spinlock_ticket_lock_with_context, ck_spinlock_ticket_unlock_with_context)
|
|
|
|
ck_spinlock_t, ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context)
|
|
|
|
static CK_COHORT_INSTANCE(ticket_ticket) *cohorts;
|
|
|
|
static CK_COHORT_INSTANCE(basic) *cohorts;
|
|
|
|
static ck_spinlock_ticket_t global_ticket_lock = CK_SPINLOCK_TICKET_INITIALIZER;
|
|
|
|
static ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;
|
|
|
|
|
|
|
|
|
|
|
|
struct block {
|
|
|
|
struct block {
|
|
|
|
unsigned int tid;
|
|
|
|
unsigned int tid;
|
|
|
@ -89,7 +92,7 @@ fairness(void *null)
|
|
|
|
volatile int j;
|
|
|
|
volatile int j;
|
|
|
|
long int base;
|
|
|
|
long int base;
|
|
|
|
unsigned int core;
|
|
|
|
unsigned int core;
|
|
|
|
CK_COHORT_INSTANCE(ticket_ticket) *cohort;
|
|
|
|
CK_COHORT_INSTANCE(basic) *cohort;
|
|
|
|
|
|
|
|
|
|
|
|
if (aff_iterate_core(&a, &core)) {
|
|
|
|
if (aff_iterate_core(&a, &core)) {
|
|
|
|
perror("ERROR: Could not affine thread");
|
|
|
|
perror("ERROR: Could not affine thread");
|
|
|
@ -104,7 +107,7 @@ fairness(void *null)
|
|
|
|
while (ck_pr_load_uint(&barrier) != nthr);
|
|
|
|
while (ck_pr_load_uint(&barrier) != nthr);
|
|
|
|
|
|
|
|
|
|
|
|
while (ready) {
|
|
|
|
while (ready) {
|
|
|
|
CK_COHORT_LOCK(ticket_ticket, cohort, NULL, NULL);
|
|
|
|
CK_COHORT_LOCK(basic, cohort, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
count[i].value++;
|
|
|
|
count[i].value++;
|
|
|
|
if (critical) {
|
|
|
|
if (critical) {
|
|
|
@ -112,7 +115,7 @@ fairness(void *null)
|
|
|
|
for (j = 0; j < base; j++);
|
|
|
|
for (j = 0; j < base; j++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CK_COHORT_UNLOCK(ticket_ticket, cohort, NULL, NULL);
|
|
|
|
CK_COHORT_UNLOCK(basic, cohort, NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
return (NULL);
|
|
|
@ -125,7 +128,7 @@ main(int argc, char *argv[])
|
|
|
|
unsigned int i;
|
|
|
|
unsigned int i;
|
|
|
|
pthread_t *threads;
|
|
|
|
pthread_t *threads;
|
|
|
|
struct block *context;
|
|
|
|
struct block *context;
|
|
|
|
ck_spinlock_ticket_t *local_fas_locks;
|
|
|
|
ck_spinlock_t *local_lock;
|
|
|
|
|
|
|
|
|
|
|
|
if (argc != 5) {
|
|
|
|
if (argc != 5) {
|
|
|
|
ck_error("Usage: ck_cohort <number of cohorts> <threads per cohort> "
|
|
|
|
ck_error("Usage: ck_cohort <number of cohorts> <threads per cohort> "
|
|
|
@ -157,18 +160,12 @@ main(int argc, char *argv[])
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cohorts = malloc(sizeof(CK_COHORT_INSTANCE(ticket_ticket)) * n_cohorts);
|
|
|
|
cohorts = malloc(sizeof(CK_COHORT_INSTANCE(basic)) * n_cohorts);
|
|
|
|
if (cohorts == NULL) {
|
|
|
|
if (cohorts == NULL) {
|
|
|
|
ck_error("ERROR: Could not allocate cohort structures\n");
|
|
|
|
ck_error("ERROR: Could not allocate cohort structures\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
local_fas_locks = calloc(n_cohorts, sizeof(ck_spinlock_ticket_t));
|
|
|
|
|
|
|
|
if (local_fas_locks == NULL) {
|
|
|
|
|
|
|
|
ck_error("ERROR: Could not allocate local lock structures\n");
|
|
|
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context = malloc(sizeof(struct block) * nthr);
|
|
|
|
context = malloc(sizeof(struct block) * nthr);
|
|
|
|
if (context == NULL) {
|
|
|
|
if (context == NULL) {
|
|
|
|
ck_error("ERROR: Could not allocate thread contexts\n");
|
|
|
|
ck_error("ERROR: Could not allocate thread contexts\n");
|
|
|
@ -187,8 +184,14 @@ main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "Creating cohorts...");
|
|
|
|
fprintf(stderr, "Creating cohorts...");
|
|
|
|
for (i = 0 ; i < n_cohorts ; i++) {
|
|
|
|
for (i = 0 ; i < n_cohorts ; i++) {
|
|
|
|
CK_COHORT_INIT(ticket_ticket, cohorts + i, &global_ticket_lock, local_fas_locks + i,
|
|
|
|
local_lock = malloc(max(CK_MD_CACHELINE, sizeof(ck_spinlock_t)));
|
|
|
|
|
|
|
|
if (local_lock == NULL) {
|
|
|
|
|
|
|
|
ck_error("ERROR: Could not allocate local lock\n");
|
|
|
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_COHORT_INIT(basic, cohorts + i, &global_lock, local_lock,
|
|
|
|
CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);
|
|
|
|
CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);
|
|
|
|
|
|
|
|
local_lock = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fprintf(stderr, "done\n");
|
|
|
|
fprintf(stderr, "done\n");
|
|
|
|
|
|
|
|
|
|
|
|