Skip to content

Instantly share code, notes, and snippets.

@alban
Created July 18, 2017 10:20
Show Gist options
  • Save alban/7efde27ac7a1c25fcc769b8d3a29dbfc to your computer and use it in GitHub Desktop.
Save alban/7efde27ac7a1c25fcc769b8d3a29dbfc to your computer and use it in GitHub Desktop.
ticket_spinlock-bpf-clocks.patch
diff --git a/Makefile b/Makefile
index b277f9a..ca4653b 100644
--- a/Makefile
+++ b/Makefile
@@ -19,4 +19,4 @@ spinlock_test: $(OBJS)
$(CC) -c $(CFLAGS) -o $@ $<
clean:
- rm -f *~ $(OBJS) $(TARGETS)
\ No newline at end of file
+ rm -f *~ $(OBJS) $(TARGETS)
diff --git a/spinlock.h b/spinlock.h
index a68a0b9..ce6c0c7 100644
--- a/spinlock.h
+++ b/spinlock.h
@@ -158,6 +158,7 @@ static __inline__ void spin_lock(struct spinlock *lock)
if(inc.head == inc.tail) break;
//loop
__RELAX();
+ __sync_synchronize();
inc.head = __ACCESS_ONCE(lock->tickets.head);
} while(1);
@@ -174,6 +175,7 @@ static __inline__ void spin_lock(struct spinlock *lock)
static __inline__ void spin_unlock(struct spinlock *lock)
{
__ADD(1, &lock->tickets.head);
+ __sync_synchronize();
}
/*
diff --git a/spinlock_test.c b/spinlock_test.c
index e831e02..46dc4f1 100644
--- a/spinlock_test.c
+++ b/spinlock_test.c
@@ -43,28 +43,59 @@ static void sync_wait(void)
spin_unlock(&g_sync_lock);
}
+#define rec_count (1 * 1000 * 1000)
+#define thr_count 16
+
+struct records {
+ unsigned long long ts;
+ unsigned long long thr;
+} rec[rec_count*thr_count];
+int ts_index = 0;
+
static void *test_thread(void *unused)
{
+ printf("Thread created: %llu\n", (unsigned long long)pthread_self());
sync_wait();
#ifdef TEST_TRY_LOCK
- while(spin_trylock(&g_lock) == 0);
+ //while(spin_trylock(&g_lock) == 0);
#else
- spin_lock(&g_lock);
+ //spin_lock(&g_lock);
#endif
#ifdef DEBUG
- printf("Lock acquired by thread [%lld], [head:%d, tail:%d]\n",
- (unsigned long long)pthread_self(), g_lock.tickets.head, g_lock.tickets.tail);
+ //printf("Lock acquired by thread [%lld], [head:%d, tail:%d]\n",
+ // (unsigned long long)pthread_self(), g_lock.tickets.head, g_lock.tickets.tail);
#endif
- spin_unlock(&g_lock);
+ //spin_unlock(&g_lock);
#ifdef DEBUG
- printf("Unlock by thread [%lld], [head:%d, tail:%d]\n",
- (unsigned long long)pthread_self(), g_lock.tickets.head, g_lock.tickets.tail);
+ //printf("Unlock by thread [%lld], [head:%d, tail:%d]\n",
+ // (unsigned long long)pthread_self(), g_lock.tickets.head, g_lock.tickets.tail);
#endif
+ int i;
+
+ unsigned long long myself = (unsigned long long) pthread_self();
+ for (i = 0; i < rec_count; i++) {
+ struct timespec tp;
+
+ spin_lock(&g_lock);
+ //printf("Lock acquired by thread [%lld], [head:%d, tail:%d]\n",
+ // (unsigned long long)pthread_self(), g_lock.tickets.head, g_lock.tickets.tail);
+ __sync_synchronize();
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ rec[ts_index].ts = tp.tv_sec * 1000 * 1000 * 1000 + tp.tv_nsec;
+ rec[ts_index].thr = myself;
+ ts_index++;
+ if (i == 0) sleep(1);
+ __sync_synchronize();
+ spin_unlock(&g_lock);
+ //printf("Unlock by thread [%lld], [head:%d, tail:%d]\n",
+ // (unsigned long long)pthread_self(), g_lock.tickets.head, g_lock.tickets.tail);
+ }
+
return NULL;
}
@@ -127,6 +158,17 @@ int main(int argc, char **argv)
}
for(i = 0; i < TEST_THREADS; ++i)
pthread_join(tids[i], NULL);
+
+ __sync_synchronize();
+
+ for(i = 0; i < rec_count * TEST_THREADS; i++) {
+ //printf("%d;%llu;%llu\n", i, rec[i].ts, rec[i].thr);
+
+ if (i > 0 && rec[i].ts < rec[i-1].ts) {
+ printf("fail!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!: %d: %llu, %llu, %llu\n", i, rec[i-1].ts, rec[i].ts, rec[i-1].ts - rec[i].ts);
+ exit(EXIT_FAILURE);
+ }
+ }
}
free(tids);
return 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment