Skip to content

Commit

Permalink
Change to a per session mutex in I/O buffer
Browse files Browse the repository at this point in the history
A per session mutex should enhance performance when multiple compressed
or encrypted archives are simultaneously extracted.

Signed-off-by: Hans Beckerus <hans.beckerus at gmail.com>
  • Loading branch information
Hans Beckerus committed May 1, 2022
1 parent 0dbbe56 commit f2e7893
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 30 deletions.
63 changes: 33 additions & 30 deletions src/iobuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,20 @@
size_t iob_hist_sz = 0;
size_t iob_sz = 0;

static pthread_mutex_t io_mutex = PTHREAD_MUTEX_INITIALIZER;

#define SPACE_LEFT(ri, wi) (IOB_SZ - SPACE_USED((ri), (wi)))
#define SPACE_USED(ri, wi) (((wi) - (ri)) & (IOB_SZ-1))

/*!
*****************************************************************************
*
****************************************************************************/
size_t iob_write(struct iob *dest, FILE *fp, int hist)
size_t iob_write(struct iob *iob, FILE *fp, int hist)
{
unsigned tot = 0;
pthread_mutex_lock(&io_mutex);
unsigned int lwi = dest->wi; /* read once */
unsigned int lri = dest->ri;
pthread_mutex_unlock(&io_mutex);
pthread_mutex_lock(&iob->lock);
unsigned int lwi = iob->wi; /* read once */
unsigned int lri = iob->ri;
pthread_mutex_unlock(&iob->lock);
size_t left = SPACE_LEFT(lri, lwi) - 1; /* -1 to avoid wi = ri */
if (IOB_HIST_SZ && hist == IOB_SAVE_HIST) {
left = left > IOB_HIST_SZ ? left - IOB_HIST_SZ : 0;
Expand All @@ -62,7 +60,7 @@ size_t iob_write(struct iob *dest, FILE *fp, int hist)
unsigned int chunk = IOB_SZ - lwi; /* assume one large chunk */
chunk = chunk < left ? chunk : left; /* reconsider assumption */
while (left > 0) {
size_t n = fread(dest->data_p + lwi, 1, chunk, fp);
size_t n = fread(iob->data_p + lwi, 1, chunk, fp);
if (n != chunk) {
if (ferror(fp)) {
perror("read");
Expand All @@ -77,12 +75,12 @@ size_t iob_write(struct iob *dest, FILE *fp, int hist)
chunk -= n;
chunk = !chunk ? left : chunk;
}
pthread_mutex_lock(&io_mutex);
dest->wi = lwi;
dest->used = SPACE_USED(dest->ri, lwi); /* dest->ri might have changed */
pthread_mutex_unlock(&io_mutex);
pthread_mutex_lock(&iob->lock);
iob->wi = lwi;
iob->used = SPACE_USED(iob->ri, lwi); /* iob->ri might have changed */
pthread_mutex_unlock(&iob->lock);
MB();
dest->offset += tot;
iob->offset += tot;

return tot;
}
Expand All @@ -91,13 +89,13 @@ size_t iob_write(struct iob *dest, FILE *fp, int hist)
*****************************************************************************
*
****************************************************************************/
size_t iob_read(char *dest, struct iob *src, size_t size, size_t off)
size_t iob_read(char *dest, struct iob *iob, size_t size, size_t off)
{
size_t tot = 0;
pthread_mutex_lock(&io_mutex);
unsigned int lri = src->ri; /* read once */
size_t used = src->used;
pthread_mutex_unlock(&io_mutex);
pthread_mutex_lock(&iob->lock);
unsigned int lri = iob->ri; /* read once */
size_t used = iob->used;
pthread_mutex_unlock(&iob->lock);
if (off) {
/* consume offset */
off = off < used ? off : used;
Expand All @@ -108,17 +106,17 @@ size_t iob_read(char *dest, struct iob *src, size_t size, size_t off)
unsigned int chunk = IOB_SZ - lri; /* assume one large chunk */
chunk = chunk < size ? chunk : size; /* reconsider assumption */
while (size) {
memcpy(dest, src->data_p + lri, chunk);
memcpy(dest, iob->data_p + lri, chunk);
lri = (lri + chunk) & (IOB_SZ - 1);
tot += chunk;
size -= chunk;
dest += chunk;
chunk = size;
}
pthread_mutex_lock(&io_mutex);
src->ri = lri;
src->used -= tot; /* src->used might have changed */
pthread_mutex_unlock(&io_mutex);
pthread_mutex_lock(&iob->lock);
iob->ri = lri;
iob->used -= tot; /* iob->used might have changed */
pthread_mutex_unlock(&iob->lock);

return tot;
}
Expand All @@ -127,21 +125,21 @@ size_t iob_read(char *dest, struct iob *src, size_t size, size_t off)
*****************************************************************************
*
****************************************************************************/
size_t iob_copy(char *dest, struct iob *src, size_t size, size_t pos)
size_t iob_copy(char *dest, struct iob *iob, size_t size, size_t pos)
{
size_t tot = 0;
unsigned int chunk = IOB_SZ - pos; /* assume one large chunk */
chunk = chunk < size ? chunk : size; /* reconsider assumption */
pthread_mutex_lock(&io_mutex);
pthread_mutex_lock(&iob->lock);
while (size) {
memcpy(dest, src->data_p + pos, chunk);
memcpy(dest, iob->data_p + pos, chunk);
pos = (pos + chunk) & (IOB_SZ - 1);
tot += chunk;
size -= chunk;
dest += chunk;
chunk = size;
}
pthread_mutex_unlock(&io_mutex);
pthread_mutex_unlock(&iob->lock);
return tot;
}

Expand Down Expand Up @@ -177,6 +175,8 @@ struct iob *iob_alloc(size_t size)
if (!iob)
return NULL;

pthread_mutex_init(&iob->lock, NULL);

return iob;
}

Expand All @@ -186,7 +186,10 @@ struct iob *iob_alloc(size_t size)
****************************************************************************/
void iob_free(struct iob *iob)
{
free(iob);
if (iob) {
pthread_mutex_destroy(&iob->lock);
free(iob);
}
}

/*!
Expand All @@ -196,9 +199,9 @@ void iob_free(struct iob *iob)
int iob_full(struct iob *iob)
{
int res;
pthread_mutex_lock(&io_mutex);
pthread_mutex_lock(&iob->lock);
res = !SPACE_LEFT(iob->ri, iob->wi);
pthread_mutex_unlock(&io_mutex);
pthread_mutex_unlock(&iob->lock);
return res;
}

1 change: 1 addition & 0 deletions src/iobuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct iob {
volatile size_t ri;
volatile size_t wi;
size_t used;
pthread_mutex_t lock;
uint8_t data_p[];
};

Expand Down

0 comments on commit f2e7893

Please sign in to comment.