Skip to content

Commit 32af7d0

Browse files
authored
Merge pull request #32 from LightBitsLabs/anton/create_lookup_unlocked
lookup without holding the lock during registration
2 parents 0eecd8a + 25ced46 commit 32af7d0

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

src/procstat.c

+27-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@
5454
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
5555
#endif
5656

57+
#ifndef unlikely
58+
#define unlikely(x) __builtin_expect(!!(x), 0)
59+
#endif
60+
61+
#ifndef likely
62+
#define likely(x) __builtin_expect(!!(x), 1)
63+
#endif
64+
5765
enum {
5866
STATS_ENTRY_FLAG_REGISTERED = 1 << 0,
5967
STATS_ENTRY_FLAG_DIR = 1 << 1,
@@ -771,17 +779,32 @@ static int register_item(struct procstat_context *context,
771779
struct procstat_item *item,
772780
struct procstat_directory *parent)
773781
{
774-
pthread_mutex_lock(&context->global_lock);
775-
if (parent) {
782+
if (likely(parent)) {
776783
struct procstat_item *duplicate;
784+
bool locked = false;
785+
786+
if (unlikely(root_directory(context, parent))) {
787+
/* Only root directory can be modified concurrently by different threads */
788+
pthread_mutex_lock(&context->global_lock);
789+
locked = true;
790+
}
777791

778792
duplicate = lookup_item_locked(parent, procstat_item_name(item), item->name_hash);
779-
if (duplicate) {
780-
pthread_mutex_unlock(&context->global_lock);
793+
if (unlikely(duplicate)) {
794+
if (locked)
795+
pthread_mutex_unlock(&context->global_lock);
781796
return EEXIST;
782797
}
798+
799+
if (likely(!locked))
800+
pthread_mutex_lock(&context->global_lock);
801+
783802
list_add_tail(&item->entry, &parent->children);
803+
} else {
804+
pthread_mutex_lock(&context->global_lock);
784805
}
806+
807+
785808
item->flags |= STATS_ENTRY_FLAG_REGISTERED;
786809
item->refcnt = 1;
787810
item->parent = parent;

0 commit comments

Comments
 (0)