[sheepdog] [PATCH] add likely/unlikely to performance critical path
Liu Yuan
namei.unix at gmail.com
Fri Aug 9 20:05:40 CEST 2013
Sinc we are alrady here with likely/unlikely helper, we can make use of it in
our performance critical path. Though the efffect might not be pronounced.
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
include/sheep.h | 2 +-
include/util.h | 10 +++++-----
lib/net.c | 2 +-
lib/strbuf.c | 12 +++++------
lib/util.c | 54 +++++++++++++++++++++++++-------------------------
lib/work.c | 2 +-
sheep/journal.c | 12 +++++------
sheep/md.c | 6 +++---
sheep/object_cache.c | 32 +++++++++++++++---------------
sheep/plain_store.c | 12 +++++------
10 files changed, 72 insertions(+), 72 deletions(-)
diff --git a/include/sheep.h b/include/sheep.h
index 4e08a1b..295cb24 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -101,7 +101,7 @@ static inline int get_vnode_next_idx(const struct sd_vnode *entries,
idx = prev_idxs[nr_prev_idxs - 1];
for (;;) {
idx = (idx + 1) % nr_entries;
- if (idx == first_idx)
+ if (unlikely(idx == first_idx))
panic("can't find next new idx");
for (found = false, i = 0; i < nr_prev_idxs; i++) {
diff --git a/include/util.h b/include/util.h
index bdffd48..ff1f0c7 100644
--- a/include/util.h
+++ b/include/util.h
@@ -275,7 +275,7 @@ static inline void sd_init_lock(struct sd_lock *lock)
ret = pthread_rwlock_init(&lock->rwlock, NULL);
} while (ret == EAGAIN);
- if (ret != 0)
+ if (unlikely(ret != 0))
panic("failed to initialize a lock, %s", strerror(ret));
}
@@ -283,7 +283,7 @@ static inline void sd_destroy_lock(struct sd_lock *lock)
{
int ret = pthread_rwlock_destroy(&lock->rwlock);
- if (ret != 0)
+ if (unlikely(ret != 0))
panic("failed to destroy a lock, %s", strerror(ret));
}
@@ -295,7 +295,7 @@ static inline void sd_read_lock(struct sd_lock *lock)
ret = pthread_rwlock_rdlock(&lock->rwlock);
} while (ret == EAGAIN);
- if (ret != 0)
+ if (unlikely(ret != 0))
panic("failed to lock for reading, %s", strerror(ret));
}
@@ -303,7 +303,7 @@ static inline void sd_write_lock(struct sd_lock *lock)
{
int ret = pthread_rwlock_wrlock(&lock->rwlock);
- if (ret != 0)
+ if (unlikely(ret != 0))
panic("failed to lock for writing, %s", strerror(ret));
}
@@ -311,7 +311,7 @@ static inline void sd_unlock(struct sd_lock *lock)
{
int ret = pthread_rwlock_unlock(&lock->rwlock);
- if (ret != 0)
+ if (unlikely(ret != 0))
panic("failed to unlock, %s", strerror(ret));
}
diff --git a/lib/net.c b/lib/net.c
index 0a35dd7..3341970 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -438,7 +438,7 @@ char *addr_to_str(char *str, int size, const uint8_t *addr, uint16_t port)
}
}
ret = inet_ntop(af, addr + addr_start_idx, str, size);
- if (ret == NULL)
+ if (unlikely(ret == NULL))
panic("failed to convert addr to string, %m");
if (port) {
diff --git a/lib/strbuf.c b/lib/strbuf.c
index 4a41d4d..7a10049 100644
--- a/lib/strbuf.c
+++ b/lib/strbuf.c
@@ -52,7 +52,7 @@ void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
void strbuf_grow(struct strbuf *sb, size_t extra)
{
- if (sb->len + extra + 1 <= sb->len)
+ if (unlikely(sb->len + extra + 1 <= sb->len))
panic("you want to use way too much memory");
ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
}
@@ -67,7 +67,7 @@ void strbuf_rtrim(struct strbuf *sb)
void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
{
strbuf_grow(sb, len);
- if (pos > sb->len)
+ if (unlikely(pos > sb->len))
panic("`pos' is too far after the end of the buffer");
memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
memcpy(sb->buf + pos, data, len);
@@ -77,11 +77,11 @@ void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
const void *data, size_t dlen)
{
- if (pos + len < pos)
+ if (unlikely(pos + len < pos))
panic("you want to use way too much memory");
- if (pos > sb->len)
+ if (unlikely(pos > sb->len))
panic("`pos' is too far after the end of the buffer");
- if (pos + len > sb->len)
+ if (unlikely(pos + len > sb->len))
panic("`pos + len' is too far after the end of the buffer");
if (dlen >= len)
@@ -120,7 +120,7 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
va_start(ap, fmt);
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
va_end(ap);
- if (len > strbuf_avail(sb))
+ if (unlikely(len > strbuf_avail(sb)))
panic("this should not happen, your snprintf is broken");
}
strbuf_setlen(sb, sb->len + len);
diff --git a/lib/util.c b/lib/util.c
index 2f877c4..82356d6 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -46,9 +46,9 @@ try_to_free_t set_try_to_free_routine(try_to_free_t routine)
void *xmalloc(size_t size)
{
void *ret = malloc(size);
- if (!ret && !size)
+ if (unlikely(!ret) && unlikely(!size))
ret = malloc(1);
- if (!ret) {
+ if (unlikely(!ret)) {
try_to_free_routine(size);
ret = malloc(size);
if (!ret && !size)
@@ -67,9 +67,9 @@ void *xzalloc(size_t size)
void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
- if (!ret && !size)
+ if (unlikely(!ret) && unlikely(!size))
ret = realloc(ptr, 1);
- if (!ret) {
+ if (unlikely(!ret)) {
try_to_free_routine(size);
ret = realloc(ptr, size);
if (!ret && !size)
@@ -83,9 +83,9 @@ void *xrealloc(void *ptr, size_t size)
void *xcalloc(size_t nmemb, size_t size)
{
void *ret = calloc(nmemb, size);
- if (!ret && (!nmemb || !size))
+ if (unlikely(!ret) && (!nmemb || !size))
ret = calloc(1, 1);
- if (!ret) {
+ if (unlikely(!ret)) {
try_to_free_routine(nmemb * size);
ret = calloc(nmemb, size);
if (!ret && (!nmemb || !size))
@@ -99,7 +99,7 @@ void *xcalloc(size_t nmemb, size_t size)
void *xvalloc(size_t size)
{
void *ret = valloc(size);
- if (!ret)
+ if (unlikely(!ret))
panic("Out of memory");
return ret;
}
@@ -109,7 +109,7 @@ static ssize_t _read(int fd, void *buf, size_t len)
ssize_t nr;
while (true) {
nr = read(fd, buf, len);
- if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+ if (unlikely(nr < 0) && (errno == EAGAIN || errno == EINTR))
continue;
return nr;
}
@@ -120,7 +120,7 @@ static ssize_t _write(int fd, const void *buf, size_t len)
ssize_t nr;
while (true) {
nr = write(fd, buf, len);
- if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+ if (unlikely(nr < 0) && (errno == EAGAIN || errno == EINTR))
continue;
return nr;
}
@@ -133,9 +133,9 @@ ssize_t xread(int fd, void *buf, size_t count)
while (count > 0) {
ssize_t loaded = _read(fd, p, count);
- if (loaded < 0)
+ if (unlikely(loaded < 0))
return -1;
- if (loaded == 0)
+ if (unlikely(loaded == 0))
return total;
count -= loaded;
p += loaded;
@@ -152,9 +152,9 @@ ssize_t xwrite(int fd, const void *buf, size_t count)
while (count > 0) {
ssize_t written = _write(fd, p, count);
- if (written < 0)
+ if (unlikely(written < 0))
return -1;
- if (!written) {
+ if (unlikely(!written)) {
errno = ENOSPC;
return -1;
}
@@ -171,7 +171,7 @@ static ssize_t _pread(int fd, void *buf, size_t len, off_t offset)
ssize_t nr;
while (true) {
nr = pread(fd, buf, len, offset);
- if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+ if (unlikely(nr < 0) && (errno == EAGAIN || errno == EINTR))
continue;
return nr;
}
@@ -182,7 +182,7 @@ static ssize_t _pwrite(int fd, const void *buf, size_t len, off_t offset)
ssize_t nr;
while (true) {
nr = pwrite(fd, buf, len, offset);
- if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+ if (unlikely(nr < 0) && (errno == EAGAIN || errno == EINTR))
continue;
return nr;
}
@@ -195,9 +195,9 @@ ssize_t xpread(int fd, void *buf, size_t count, off_t offset)
while (count > 0) {
ssize_t loaded = _pread(fd, p, count, offset);
- if (loaded < 0)
+ if (unlikely(loaded < 0))
return -1;
- if (loaded == 0)
+ if (unlikely(loaded == 0))
return total;
count -= loaded;
p += loaded;
@@ -215,9 +215,9 @@ ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset)
while (count > 0) {
ssize_t written = _pwrite(fd, p, count, offset);
- if (written < 0)
+ if (unlikely(written < 0))
return -1;
- if (!written) {
+ if (unlikely(!written)) {
errno = ENOSPC;
return -1;
}
@@ -256,7 +256,7 @@ int xfallocate(int fd, int mode, off_t offset, off_t len)
do {
ret = fallocate(fd, mode, offset, len);
- } while (ret < 0 && (errno == EAGAIN || errno == EINTR));
+ } while (unlikely(ret < 0) && (errno == EAGAIN || errno == EINTR));
return ret;
}
@@ -267,7 +267,7 @@ int xftruncate(int fd, off_t length)
do {
ret = ftruncate(fd, length);
- } while (ret < 0 && (errno == EAGAIN || errno == EINTR));
+ } while (unlikely(ret < 0) && (errno == EAGAIN || errno == EINTR));
return ret;
}
@@ -284,11 +284,11 @@ int eventfd_xread(int efd)
do {
ret = eventfd_read(efd, &value);
- } while (ret < 0 && errno == EINTR);
+ } while (unlikely(ret < 0) && errno == EINTR);
if (ret == 0)
ret = value;
- else if (errno != EAGAIN)
+ else if (unlikely(errno != EAGAIN))
panic("eventfd_read() failed, %m");
return ret;
@@ -300,9 +300,9 @@ void eventfd_xwrite(int efd, int value)
do {
ret = eventfd_write(efd, (eventfd_t)value);
- } while (ret < 0 && (errno == EINTR || errno == EAGAIN));
+ } while (unlikely(ret < 0) && (errno == EINTR || errno == EAGAIN));
- if (ret < 0)
+ if (unlikely(ret < 0))
panic("eventfd_write() failed, %m");
}
@@ -581,14 +581,14 @@ again:
}
ret = xwrite(fd, buf, len);
- if (ret != len) {
+ if (unlikely(ret != len)) {
sd_err("failed to write %s, %m", path);
ret = -1;
goto close_fd;
}
ret = rename(tmp_path, path);
- if (ret < 0) {
+ if (unlikely(ret < 0)) {
sd_err("failed to rename %s, %m", path);
ret = -1;
}
diff --git a/lib/work.c b/lib/work.c
index 305a8c0..56beb62 100644
--- a/lib/work.c
+++ b/lib/work.c
@@ -166,7 +166,7 @@ void suspend_worker_threads(void)
}
FOR_EACH_BIT(tid, tid_map, tid_max) {
- if (tkill(tid, SIGUSR2) < 0)
+ if (unlikely(tkill(tid, SIGUSR2) < 0))
panic("%m");
}
diff --git a/sheep/journal.c b/sheep/journal.c
index 2beaba9..cd38701 100644
--- a/sheep/journal.c
+++ b/sheep/journal.c
@@ -317,13 +317,13 @@ static void *commit_data(void *ignored)
/* Tell runtime to release resources after termination */
err = pthread_detach(pthread_self());
- if (err)
+ if (unlikely(err))
panic("%s", strerror(err));
sync();
- if (xftruncate(jfile.commit_fd, 0) < 0)
+ if (unlikely(xftruncate(jfile.commit_fd, 0) < 0))
panic("truncate %m");
- if (prealloc(jfile.commit_fd, jfile_size) < 0)
+ if (unlikely(prealloc(jfile.commit_fd, jfile_size) < 0))
panic("prealloc");
uatomic_set_false(&jfile.in_commit);
@@ -338,7 +338,7 @@ static void switch_journal_file(void)
pthread_t thread;
retry:
- if (!uatomic_set_true(&jfile.in_commit)) {
+ if (unlikely(!uatomic_set_true(&jfile.in_commit))) {
sd_err("journal file in committing, "
"you might need enlarge jfile size");
usleep(100000); /* Wait until committing is finished */
@@ -353,7 +353,7 @@ retry:
jfile.pos = 0;
err = pthread_create(&thread, NULL, commit_data, NULL);
- if (err)
+ if (unlikely(err))
panic("%s", strerror(err));
}
@@ -392,7 +392,7 @@ static int journal_file_write(struct journal_descriptor *jd, const char *buf)
* Feel free to correct me If I am wrong.
*/
written = xpwrite(jfile.fd, wbuffer, wsize, woff);
- if (written != wsize) {
+ if (unlikely(written != wsize)) {
sd_err("failed, written %zd, len %zd", written, wsize);
/* FIXME: teach journal file handle EIO gracefully */
ret = SD_RES_EIO;
diff --git a/sheep/md.c b/sheep/md.c
index 038c180..dd2bba5 100644
--- a/sheep/md.c
+++ b/sheep/md.c
@@ -190,7 +190,7 @@ static int for_each_object_in_path(char *path,
char p[PATH_MAX];
dir = opendir(path);
- if (!dir) {
+ if (unlikely(!dir)) {
sd_err("failed to open %s, %m", path);
return SD_RES_EIO;
}
@@ -198,7 +198,7 @@ static int for_each_object_in_path(char *path,
while ((d = readdir(dir))) {
uint32_t epoch = 0;
- if (!strncmp(d->d_name, ".", 1))
+ if (unlikely(!strncmp(d->d_name, ".", 1)))
continue;
oid = strtoull(d->d_name, NULL, 16);
@@ -458,7 +458,7 @@ int md_handle_eio(char *fault_path)
static inline bool md_access(char *path)
{
if (access(path, R_OK | W_OK) < 0) {
- if (errno != ENOENT)
+ if (unlikely(errno != ENOENT))
sd_err("failed to check %s, %m", path);
return false;
}
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 7431cfa..1f8822e 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -322,7 +322,7 @@ static int remove_cache_object(struct object_cache *oc, uint32_t idx)
snprintf(path, sizeof(path), "%s/%06"PRIx32"/%08"PRIx32,
object_cache_dir, oc->vid, idx);
sd_debug("%"PRIx64, idx_to_oid(oc->vid, idx));
- if (unlink(path) < 0) {
+ if (unlikely(unlink(path) < 0)) {
sd_err("failed to remove cached object %m");
if (errno == ENOENT)
return SD_RES_SUCCESS;
@@ -349,7 +349,7 @@ static int read_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
}
fd = open(p, flags, sd_def_fmode);
- if (fd < 0) {
+ if (unlikely(fd < 0)) {
sd_err("%m");
ret = SD_RES_EIO;
goto out;
@@ -357,7 +357,7 @@ static int read_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
size = xpread(fd, buf, count, offset);
- if (size != count) {
+ if (unlikely(size != count)) {
sd_err("size %zu, count:%zu, offset %jd %m", size, count,
(intmax_t)offset);
ret = SD_RES_EIO;
@@ -385,7 +385,7 @@ static int write_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
}
fd = open(p, flags, sd_def_fmode);
- if (fd < 0) {
+ if (unlikely(fd < 0)) {
sd_err("%m");
ret = SD_RES_EIO;
goto out;
@@ -393,7 +393,7 @@ static int write_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
size = xpwrite(fd, buf, count, offset);
- if (size != count) {
+ if (unlikely(size != count)) {
sd_err("size %zu, count:%zu, offset %jd %m", size, count,
(intmax_t)offset);
ret = SD_RES_EIO;
@@ -711,7 +711,7 @@ static void add_to_lru_cache(struct object_cache *oc, uint32_t idx, bool create)
sd_debug("oid %"PRIx64" added", idx_to_oid(oc->vid, idx));
write_lock_cache(oc);
- if (lru_tree_insert(&oc->lru_tree, entry))
+ if (unlikely(lru_tree_insert(&oc->lru_tree, entry)))
panic("the object already exist");
uatomic_add(&gcache.capacity, CACHE_OBJECT_SIZE);
list_add_tail(&entry->lru_list, &oc->lru_head);
@@ -730,7 +730,7 @@ static inline int lookup_path(char *path)
int ret = SD_RES_SUCCESS;
if (access(path, R_OK | W_OK) < 0) {
- if (errno != ENOENT) {
+ if (unlikely(errno != ENOENT)) {
sd_debug("%m");
ret = SD_RES_EIO;
} else {
@@ -753,13 +753,13 @@ static int object_cache_lookup(struct object_cache *oc, uint32_t idx,
flags |= O_CREAT | O_TRUNC;
fd = open(path, flags, sd_def_fmode);
- if (fd < 0) {
+ if (unlikely(fd < 0)) {
sd_debug("%s, %m", path);
ret = SD_RES_EIO;
goto out;
}
ret = prealloc(fd, get_objsize(idx_to_oid(oc->vid, idx)));
- if (ret < 0) {
+ if (unlikely(ret < 0)) {
ret = SD_RES_EIO;
goto out_close;
}
@@ -783,7 +783,7 @@ static int create_cache_object(struct object_cache *oc, uint32_t idx,
object_cache_dir, oc->vid, idx);
fd = open(tmp_path, flags, sd_def_fmode);
if (fd < 0) {
- if (errno == EEXIST) {
+ if (likely(errno == EEXIST)) {
sd_debug("%08"PRIx32" already created", idx);
goto out;
}
@@ -795,7 +795,7 @@ static int create_cache_object(struct object_cache *oc, uint32_t idx,
/* We need to extend it if the buffer is trimmed */
if (offset != 0 || buf_size != obj_size) {
ret = prealloc(fd, obj_size);
- if (ret < 0) {
+ if (unlikely(ret < 0)) {
ret = SD_RES_EIO;
sd_err("%m");
goto out_close;
@@ -803,7 +803,7 @@ static int create_cache_object(struct object_cache *oc, uint32_t idx,
}
ret = xpwrite(fd, buffer, buf_size, offset);
- if (ret != buf_size) {
+ if (unlikely(ret != buf_size)) {
ret = SD_RES_EIO;
sd_err("failed, vid %"PRIx32", idx %"PRIx32, oc->vid, idx);
goto out_close;
@@ -812,7 +812,7 @@ static int create_cache_object(struct object_cache *oc, uint32_t idx,
snprintf(path, sizeof(path), "%s/%06"PRIx32"/%08"PRIx32,
object_cache_dir, oc->vid, idx);
ret = link(tmp_path, path);
- if (ret < 0) {
+ if (unlikely(ret < 0)) {
if (errno == EEXIST) {
ret = SD_RES_OID_EXIST;
goto out_close;
@@ -895,9 +895,9 @@ static void do_push_object(struct work *work)
if (oid_is_readonly(idx_to_oid(oc->vid, entry_idx(entry))))
goto clean;
- if (push_cache_object(oc->vid, entry_idx(entry), entry->bmap,
- !!(entry->idx & CACHE_CREATE_BIT))
- != SD_RES_SUCCESS)
+ if (unlikely(push_cache_object(oc->vid, entry_idx(entry), entry->bmap,
+ !!(entry->idx & CACHE_CREATE_BIT))
+ != SD_RES_SUCCESS))
panic("push failed but should never fail");
clean:
if (uatomic_sub_return(&oc->push_count, 1) == 0)
diff --git a/sheep/plain_store.c b/sheep/plain_store.c
index d3c57e6..c9a077e 100644
--- a/sheep/plain_store.c
+++ b/sheep/plain_store.c
@@ -105,8 +105,8 @@ int default_write(uint64_t oid, const struct siocb *iocb)
}
if (uatomic_is_true(&sys->use_journal) &&
- journal_write_store(oid, iocb->buf, iocb->length, iocb->offset,
- false)
+ unlikely(journal_write_store(oid, iocb->buf, iocb->length,
+ iocb->offset, false))
!= SD_RES_SUCCESS) {
sd_err("turn off journaling");
uatomic_set_false(&sys->use_journal);
@@ -117,11 +117,11 @@ int default_write(uint64_t oid, const struct siocb *iocb)
get_obj_path(oid, path);
fd = open(path, flags, sd_def_fmode);
- if (fd < 0)
+ if (unlikely(fd < 0))
return err_to_sderr(path, oid, errno);
size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset);
- if (size != iocb->length) {
+ if (unlikely(size != iocb->length)) {
sd_err("failed to write object %"PRIx64", path=%s, offset=%"
PRId64", size=%"PRId32", result=%zd, %m", oid, path,
iocb->offset, iocb->length, size);
@@ -241,7 +241,7 @@ static int default_read_from_path(uint64_t oid, char *path,
return err_to_sderr(path, oid, errno);
size = xpread(fd, iocb->buf, iocb->length, iocb->offset);
- if (size != iocb->length) {
+ if (unlikely(size != iocb->length)) {
sd_err("failed to read object %"PRIx64", path=%s, offset=%"
PRId64", size=%"PRId32", result=%zd, %m", oid, path,
iocb->offset, iocb->length, size);
@@ -420,7 +420,7 @@ static int move_object_to_stale_dir(uint64_t oid, char *wd, uint32_t epoch,
snprintf(stale_path, PATH_MAX, "%s/.stale/%016"PRIx64".%"PRIu32, wd,
oid, tgt_epoch);
- if (rename(path, stale_path) < 0) {
+ if (unlikely(rename(path, stale_path)) < 0) {
sd_err("failed to move stale object %" PRIX64 " to %s, %m", oid,
path);
return SD_RES_EIO;
--
1.7.9.5
More information about the sheepdog
mailing list