Commit 3f6b65e7 authored by Geoff Simmons's avatar Geoff Simmons

replace the state fields in the tx, record and chunk structs with

one-bit wide occupied fields (makes the structs smaller)
parent ec7e8c66
......@@ -52,7 +52,7 @@
VSTAILQ_INIT((head2)); \
} while (0)
static const char *statename[3] = { "EMPTY", "DONE" };
static const char *statename[3] = { "EMPTY", "OCCUPIED" };
static pthread_mutex_t freetx_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t freeline_lock = PTHREAD_MUTEX_INITIALIZER;
......@@ -87,19 +87,19 @@ DATA_Clear_Tx(tx_t * const tx, txhead_t * const freetx,
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
tx->state = TX_EMPTY;
tx->occupied = 0;
tx->vxid = -1;
tx->type = VSL_t_unknown;
tx->t = 0.;
while ((rec = VSTAILQ_FIRST(&tx->lines)) != NULL) {
CHECK_OBJ(rec, LOGLINE_MAGIC);
rec->state = DATA_EMPTY;
rec->occupied = 0;
rec->tag = SLT__Bogus;
rec->len = 0;
while ((chunk = VSTAILQ_FIRST(&rec->chunks)) != NULL) {
CHECK_OBJ(chunk, CHUNK_MAGIC);
chunk->state = DATA_EMPTY;
chunk->occupied = 0;
*chunk->data = '\0';
VSTAILQ_REMOVE_HEAD(&rec->chunks, chunklist);
VSTAILQ_INSERT_HEAD(freechunk, chunk, freelist);
......@@ -146,7 +146,7 @@ DATA_Init(void)
VSTAILQ_INIT(&freechunkhead);
for (int i = 0; i < nchunks; i++) {
chunks[i].magic = CHUNK_MAGIC;
chunks[i].state = DATA_EMPTY;
chunks[i].occupied = 0;
chunks[i].data = &bufptr[bufidx++ * config.chunk_size];
VSTAILQ_INSERT_TAIL(&freechunkhead, &chunks[i], freelist);
}
......@@ -163,7 +163,7 @@ DATA_Init(void)
VSTAILQ_INIT(&freelinehead);
for (int i = 0; i < nrecords; i++) {
lines[i].magic = LOGLINE_MAGIC;
lines[i].state = DATA_EMPTY;
lines[i].occupied = 0;
lines[i].tag = SLT__Bogus;
lines[i].len = 0;
VSTAILQ_INIT(&lines[i].chunks);
......@@ -182,7 +182,7 @@ DATA_Init(void)
VSTAILQ_INIT(&freetxhead);
for (int i = 0; i < config.max_data; i++) {
txn[i].magic = TX_MAGIC;
txn[i].state = TX_EMPTY;
txn[i].occupied = 0;
txn[i].vxid = -1;
txn[i].type = VSL_t_unknown;
txn[i].t = 0.;
......@@ -260,14 +260,14 @@ DATA_Dump(void)
continue;
}
if (txn[i].state == TX_EMPTY)
if (txn[i].occupied == 0)
continue;
tx = &txn[i];
VSB_clear(data);
VSB_printf(data, "Tx entry %d: vxid=%u state=%s dir=%c records={",
i, tx->vxid, statename[tx->state],
i, tx->vxid, statename[tx->occupied],
C(tx->type) ? 'c' : B(tx->type) ? 'b' : '-');
VSTAILQ_FOREACH(rec, &tx->lines, linelist) {
......
......@@ -80,13 +80,14 @@ char *
get_payload(const logline_t *rec)
{
CHECK_OBJ_NOTNULL(rec, LOGLINE_MAGIC);
assert(OCCUPIED(rec));
if (!rec->len)
return empty;
chunk_t *chunk = VSTAILQ_FIRST(&rec->chunks);
CHECK_OBJ_NOTNULL(chunk, CHUNK_MAGIC);
assert(chunk->state == DATA_DONE);
assert(OCCUPIED(chunk));
if (rec->len <= config.chunk_size)
return chunk->data;
......@@ -117,6 +118,7 @@ get_tag(const tx_t *tx, enum VSL_tag_e tag)
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
VSTAILQ_FOREACH(rec, &tx->lines, linelist) {
CHECK_OBJ_NOTNULL(rec, LOGLINE_MAGIC);
assert(OCCUPIED(rec));
if (rec->tag == tag)
tagrec = rec;
}
......@@ -138,6 +140,7 @@ get_hdr(const tx_t *tx, enum VSL_tag_e tag, const char *hdr)
char *c;
CHECK_OBJ_NOTNULL(rec, LOGLINE_MAGIC);
assert(OCCUPIED(rec));
if (rec->tag != tag)
continue;
c = get_payload(rec);
......@@ -1215,7 +1218,7 @@ FMT_Format(tx_t *tx, struct vsb *os)
compiled_fmt_t fmt;
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
assert(tx->state == TX_DONE);
assert(OCCUPIED(tx));
switch(tx->type) {
case VSL_t_req:
......
......@@ -18,12 +18,12 @@ if [ "$CKSUM" != "4102580059 20793538 $OUT" ]; then
fi
# sed removes the version/revision from the "initializing" line.
# grep removes logs by the threads about free lists, which are not
# relevant to the regression, and are not predictable from one run to
# the next.
CKSUM=$( sed -e 's/\(initializing\) \(.*\)/\1/' $LOG | egrep -v 'Writer: returned|Reader: took' | cksum )
# grep removes logs about table allocations and by the threads about
# free lists, which are not relevant to the regression, and are not
# predictable from one run to the next.
CKSUM=$( sed -e 's/\(initializing\) \(.*\)/\1/' $LOG | egrep -v 'Writer: returned|Reader: took|Allocating table' | cksum )
if [ "$CKSUM" != '469328279 66951401' ]; then
if [ "$CKSUM" != '3970198226 66951221' ]; then
echo "ERROR: Regression test varnishevent log incorrect cksum: $CKSUM"
exit 1
fi
......
......@@ -69,7 +69,7 @@ static char
for (int i = 0; i < config.max_data; i++) {
MCHECK_OBJ(&txn[i], TX_MAGIC);
MASSERT(txn[i].state == TX_EMPTY);
MASSERT(!OCCUPIED(&txn[i]));
MASSERT(txn[i].vxid == -1);
MASSERT(txn[i].type == VSL_t_unknown);
MAZ(txn[i].t);
......@@ -81,7 +81,7 @@ static char
for (int i = 0; i < nrecords; i++) {
MCHECK_OBJ(&lines[i], LOGLINE_MAGIC);
MASSERT(lines[i].state == DATA_EMPTY);
MASSERT(!OCCUPIED(&lines[i]));
MASSERT(lines[i].tag == SLT__Bogus);
MASSERT(lines[i].len == 0);
MASSERT(VSTAILQ_EMPTY(&lines[i].chunks));
......@@ -92,7 +92,7 @@ static char
for (int i = 0; i < nchunks; i++) {
MCHECK_OBJ(&chunks[i], CHUNK_MAGIC);
MASSERT(chunks[i].state == DATA_EMPTY);
MASSERT(!OCCUPIED(&chunks[i]));
MASSERT(chunks[i].data == (chunks[0].data + (i * config.chunk_size)));
if (VSTAILQ_NEXT(&chunks[i], freelist) != NULL)
chunk_free++;
......@@ -294,7 +294,7 @@ static const char
MASSERT(nfree_chunks == 1147 + NRECS*CHUNKS_PER_REC);
MCHECK_OBJ(&tx, TX_MAGIC);
MASSERT(tx.state == TX_EMPTY);
MASSERT(!OCCUPIED(&tx));
MASSERT(tx.vxid == -1);
MASSERT(tx.type == VSL_t_unknown);
MAZ(tx.t);
......@@ -307,7 +307,7 @@ static const char
MASSERT(!VSTAILQ_EMPTY(&local_freeline));
VSTAILQ_FOREACH(rec, &local_freeline, freelist) {
MCHECK_OBJ_NOTNULL(rec, LOGLINE_MAGIC);
MASSERT(rec->state == DATA_EMPTY);
MASSERT(!OCCUPIED(rec));
MASSERT(rec->tag == SLT__Bogus);
MAZ(rec->len);
MASSERT(VSTAILQ_EMPTY(&tx.lines));
......@@ -319,7 +319,7 @@ static const char
n = 0;
VSTAILQ_FOREACH(chunk, &local_freechunk, freelist) {
MCHECK_OBJ_NOTNULL(chunk, CHUNK_MAGIC);
MASSERT(chunk->state == DATA_EMPTY);
MASSERT(!OCCUPIED(chunk));
MAZ(chunk->data[0]);
n++;
free(chunk->data);
......
......@@ -48,6 +48,7 @@ add_rec_chunk(tx_t *tx, logline_t *rec, chunk_t *chunk)
{
VSTAILQ_INSERT_TAIL(&tx->lines, rec, linelist);
rec->magic = LOGLINE_MAGIC;
rec->occupied = 1;
VSTAILQ_INIT(&rec->chunks);
VSTAILQ_INSERT_TAIL(&rec->chunks, chunk, chunklist);
chunk->magic = CHUNK_MAGIC;
......@@ -72,7 +73,7 @@ set_record_data(logline_t *rec, chunk_t *chunk, const char *data,
strcpy(chunk->data, data);
if (tag != SLT__Bogus)
rec->tag = tag;
chunk->state = DATA_DONE;
chunk->occupied = 1;
}
static void
......@@ -109,9 +110,11 @@ static const char
printf("... testing get_payload()\n");
rec.magic = LOGLINE_MAGIC;
rec.occupied = 1;
VSTAILQ_INIT(&rec.chunks);
chunk.magic = CHUNK_MAGIC;
chunk.data = (char *) calloc(1, config.chunk_size);
chunk.occupied = 1;
MAN(chunk.data);
/* Record with one chunk */
......@@ -177,6 +180,7 @@ static const char
for (int i = 0; i < NRECORDS; i++) {
recs[i].magic = LOGLINE_MAGIC;
recs[i].tag = SLT_ReqHeader;
recs[i].occupied = 1;
VSTAILQ_INSERT_TAIL(&tx.lines, &recs[i], linelist);
}
recs[NRECORDS / 2].tag = SLT_RespHeader;
......@@ -218,7 +222,7 @@ static const char
VSTAILQ_INIT(&recs[i].chunks);
c[i].magic = CHUNK_MAGIC;
c[i].data = (char *) calloc(1, config.chunk_size);
c[i].state = DATA_DONE;
c[i].occupied = 1;
strcpy(c[i].data, "Bar: baz");
VSTAILQ_INSERT_TAIL(&recs[i].chunks, &c[i], chunklist);
}
......@@ -313,7 +317,7 @@ static const char
VSTAILQ_INIT(&rec.chunks);
chunk.magic = CHUNK_MAGIC;
chunk.data = (char *) calloc(1, config.chunk_size);
chunk.state = DATA_DONE;
chunk.occupied = 1;
MAN(chunk.data);
rec.len = strlen(SHORT_STRING);
strcpy(chunk.data, SHORT_STRING);
......@@ -1313,7 +1317,7 @@ static const char
MAN(os);
tx.magic = TX_MAGIC;
tx.state = TX_DONE;
tx.occupied = 1;
VSTAILQ_INIT(&tx.lines);
for (int i = 0; i < NRECS; i++) {
recs[i] = (logline_t *) calloc(1, sizeof(logline_t));
......
......@@ -77,7 +77,7 @@ static char
chunk.data = (char *) calloc(1, config.chunk_size);
for (int i = 0; i < THRESHOLD; i++) {
tx.state = DATA_DONE;
tx.occupied = 1;
tx.type = VSL_t_req;
wrt_write(&tx);
......
......@@ -213,7 +213,7 @@ static inline void
submit(tx_t *tx)
{
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
assert(tx->state == TX_DONE);
assert(OCCUPIED(tx));
SPSCQ_Enq(tx);
signal_spscq_ready();
submitted++;
......@@ -246,7 +246,7 @@ event(struct VSL_data *vsl, struct VSL_transaction * const pt[], void *priv)
continue;
}
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
assert(tx->state == TX_EMPTY);
assert(!OCCUPIED(tx));
assert(VSTAILQ_EMPTY(&tx->lines));
tx->type = t->type;
tx->vxid = t->vxid;
......@@ -278,7 +278,7 @@ event(struct VSL_data *vsl, struct VSL_transaction * const pt[], void *priv)
continue;
}
CHECK_OBJ_NOTNULL(rec, LOGLINE_MAGIC);
assert(rec->state == DATA_EMPTY);
assert(!OCCUPIED(rec));
assert(VSTAILQ_EMPTY(&rec->chunks));
rec->tag = VSL_TAG(t->c->rec.ptr);
......@@ -307,18 +307,18 @@ event(struct VSL_data *vsl, struct VSL_transaction * const pt[], void *priv)
continue;
}
CHECK_OBJ(chunk, CHUNK_MAGIC);
assert(chunk->state == DATA_EMPTY);
assert(!OCCUPIED(chunk));
VSTAILQ_INSERT_TAIL(&rec->chunks, chunk, chunklist);
int cp = n;
if (cp > config.chunk_size)
cp = config.chunk_size;
memcpy(chunk->data, p, cp);
chunk->state = DATA_DONE;
chunk->occupied = 1;
p += cp;
n -= cp;
total_chunks++;
}
rec->state = DATA_DONE;
rec->occupied = 1;
VSTAILQ_INSERT_TAIL(&tx->lines, rec, linelist);
nrec++;
}
......@@ -328,7 +328,7 @@ event(struct VSL_data *vsl, struct VSL_transaction * const pt[], void *priv)
continue;
}
tx->state = TX_DONE;
tx->occupied = 1;
seen++;
MON_StatsUpdate(STATS_DONE, nrec, total_chunks);
if (tx_occ > tx_occ_hi)
......
......@@ -73,23 +73,13 @@
struct sigaction default_action;
typedef enum {
DATA_EMPTY = 0,
DATA_DONE,
} data_state_e;
typedef enum {
TX_EMPTY = 0,
TX_DONE,
} tx_state_e;
typedef struct chunk_t {
unsigned magic;
#define CHUNK_MAGIC 0x676e0d19
data_state_e state;
char *data;
VSTAILQ_ENTRY(chunk_t) freelist;
VSTAILQ_ENTRY(chunk_t) chunklist;
unsigned int occupied:1;
} chunk_t;
typedef VSTAILQ_HEAD(chunkhead_s, chunk_t) chunkhead_t;
......@@ -100,12 +90,12 @@ unsigned nchunks;
typedef struct logline_t {
unsigned magic;
#define LOGLINE_MAGIC 0xf427a374
enum VSL_tag_e tag;
data_state_e state;
chunkhead_t chunks;
unsigned len;
chunkhead_t chunks;
VSTAILQ_ENTRY(logline_t) freelist;
VSTAILQ_ENTRY(logline_t) linelist;
enum VSL_tag_e tag;
unsigned int occupied:1;
} logline_t;
logline_t *lines;
......@@ -116,27 +106,23 @@ typedef VSTAILQ_HEAD(linehead_s, logline_t) linehead_t;
typedef struct tx_t {
unsigned magic;
#define TX_MAGIC 0xff463e42
double t;
tx_state_e state;
int32_t vxid;
enum VSL_transaction_e type;
linehead_t lines;
VSTAILQ_ENTRY(tx_t) freelist;
VSTAILQ_ENTRY(tx_t) spscq;
double t;
enum VSL_transaction_e type:7;
unsigned int occupied:1;
} tx_t;
tx_t *txn;
typedef VSTAILQ_HEAD(txhead_s, tx_t) txhead_t;
unsigned tx_occ, rec_occ, chunk_occ, tx_occ_hi, rec_occ_hi, chunk_occ_hi;
int tag2idx[MAX_VSL_TAG];
enum VSL_tag_e idx2tag[MAX_VSL_TAG];
VSTAILQ_HEAD(freehead_s, logline_t);
#define OCCUPIED(p) ((p)->occupied == 1)
unsigned global_nfree_tx, global_nfree_line, global_nfree_chunk;
unsigned tx_occ, rec_occ, chunk_occ, tx_occ_hi, rec_occ_hi, chunk_occ_hi,
global_nfree_tx, global_nfree_line, global_nfree_chunk;
/* Writer (consumer) waits for this condition when the SPSC queue is empty.
Reader (producer) signals the condition after enqueue. */
......
......@@ -167,7 +167,7 @@ wrt_write(tx_t *tx)
int errnum;
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
assert(tx->state == TX_DONE);
assert(OCCUPIED(tx));
AZ(pthread_mutex_lock(&reopen_lock));
if (reopen && fo != stdout) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment