Skip to content

Commit 31a65ce

Browse files
committed
Add stress test, bug fixes
1 parent a6f8979 commit 31a65ce

File tree

5 files changed

+70
-21
lines changed

5 files changed

+70
-21
lines changed

include/qt_feb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef filter_code (*qt_feb_taskfilter_f)(qt_key_t addr,
1818
void *restrict arg);
1919

2020
int INTERNAL qthread_feb_adr_init(const aligned_t *dest, const bool is_from_recursive_lock);
21+
int INTERNAL qthread_feb_adr_remove(aligned_t *dest);
2122

2223
void INTERNAL qt_feb_subsystem_init(uint_fast8_t);
2324

include/qthread/qthread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ int qthread_readXX(aligned_t *dest,
555555
int qthread_lock(const aligned_t *a);
556556
int qthread_unlock(const aligned_t *a);
557557
int qthread_lock_init(const aligned_t *a, const bool is_recursive);
558+
int qthread_lock_destroy(aligned_t *a);
558559

559560
const int qthread_trylock(const aligned_t *a);
560561

src/feb.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ static QINLINE void qthread_gotlock_empty_inner(qthread_shepherd_t *shep,
430430
FREE_ADDRRES(X);
431431
qthread_gotlock_fill_inner(shep, m, maddr, 1, precond_tasks);
432432
}
433-
if ((m->full == 1) && (m->EFQ == NULL) && (m->FEQ == NULL) && (m->FFQ == NULL) && (m->FFWQ == NULL)) {
433+
if ((m->full == 1) && (m->EFQ == NULL) && (m->FEQ == NULL) && (m->FFQ == NULL) && (m->FFWQ == NULL) && (m->acq_owner_stat.state <FEB_is_recursive_lock )) {
434434
removeable = 1;
435435
} else {
436436
removeable = 0;
@@ -551,7 +551,7 @@ static QINLINE void qthread_gotlock_fill_inner(qthread_shepherd_t *shep,
551551
}
552552
if (recursive == 0) {
553553
int removeable;
554-
if ((m->EFQ == NULL) && (m->FEQ == NULL) && (m->full == 1)) {
554+
if ((m->EFQ == NULL) && (m->FEQ == NULL) && (m->full == 1) && (m->acq_owner_stat.state < FEB_is_recursive_lock)) {
555555
qthread_debug(FEB_DETAILS, "m(%p), addr(%p), recursive(%u): addrstat removeable!\n", m, maddr, recursive);
556556
removeable = 1;
557557
} else {
@@ -733,6 +733,11 @@ int INTERNAL qthread_feb_adr_init(const aligned_t *dest, const bool is_from_recu
733733
return QTHREAD_SUCCESS;
734734
} /*}}} */
735735

736+
int INTERNAL qthread_feb_adr_remove(aligned_t *dest)
737+
{ /*{{{ */
738+
qthread_FEB_remove(dest);
739+
} /*}}} */
740+
736741
int API_FUNC qthread_fill(const aligned_t *dest)
737742
{ /*{{{ */
738743
const aligned_t *alignedaddr;
@@ -776,9 +781,6 @@ int API_FUNC qthread_fill(const aligned_t *dest)
776781
m = (qthread_addrstat_t *)qt_hash_get_locked(FEBs[lockbin], (void *)alignedaddr);
777782
if (m) {
778783
QTHREAD_FASTLOCK_LOCK(&m->lock);
779-
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
780-
--m->acq_owner_stat.recursive_access_counter;
781-
}
782784
}
783785
} /* END CRITICAL SECTION */
784786
qt_hash_unlock(FEBs[lockbin]); /* unlock hash */
@@ -787,10 +789,12 @@ int API_FUNC qthread_fill(const aligned_t *dest)
787789
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
788790
--m->acq_owner_stat.recursive_access_counter;
789791
if (m->acq_owner_stat.recursive_access_counter >0){
790-
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): decrementing recursive_access_counter\n", dest, qthread_id());
792+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): released recursive lock (inner)\n", dest, qthread_id());
793+
QTHREAD_FASTLOCK_UNLOCK(&m->lock);
791794
return QTHREAD_SUCCESS;
792795
}
793-
m->acq_owner_stat.state = FEB_is_recursive_lock; //reset
796+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): released recursive lock (outer)\n", dest, qthread_id());
797+
m->acq_owner_stat.state = FEB_is_recursive_lock; //reset owner, maintain lock type
794798
}
795799
/* if dest wasn't in the hash, it was already full. Since it was,
796800
* we need to fill it. */
@@ -1460,6 +1464,7 @@ int API_FUNC qthread_readFE(aligned_t *restrict dest,
14601464
if (!me) {
14611465
return qthread_feb_blocker_func(dest, (void *)src, READFE);
14621466
}
1467+
14631468
assert(me->rdata);
14641469
qthread_debug(FEB_CALLS, "dest=%p, src=%p (tid=%i)\n", dest, src, me->thread_id);
14651470
QTHREAD_FEB_UNIQUERECORD(feb, src, me);
@@ -1520,13 +1525,16 @@ int API_FUNC qthread_readFE(aligned_t *restrict dest,
15201525
if (m->full == 0) { /* empty, thus, we must block */
15211526
/* unless read_FE was taken by qthread_lock() */
15221527
/* on same thread */
1523-
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
1524-
if (m->acq_owner_stat.state == qthread_id()) {
1528+
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
1529+
if (m->acq_owner_stat.state == qthread_readstate(CURRENT_WORKER)) {
1530+
15251531
++m->acq_owner_stat.recursive_access_counter;
1532+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): acquired recursive lock (inner)\n", dest, me->thread_id);
15261533
QTHREAD_FASTLOCK_UNLOCK(&m->lock);
15271534
QTHREAD_FEB_TIMER_STOP(febblock, me);
15281535
return QTHREAD_SUCCESS;
15291536
}
1537+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): attempt to acquire inner recursive lock failed thus blocking\n", dest, me->thread_id);
15301538
}
15311539
QTHREAD_WAIT_TIMER_DECLARATION;
15321540
qthread_addrres_t *X = ALLOC_ADDRRES();
@@ -1552,16 +1560,18 @@ int API_FUNC qthread_readFE(aligned_t *restrict dest,
15521560
#endif /* QTHREAD_USE_EUREKAS */
15531561
qthread_debug(FEB_BEHAVIOR, "tid %u succeeded on %p=%p after waiting\n", me->thread_id, dest, src);
15541562
} else { /* full, thus IT IS OURS! MUAHAHAHA! */
1563+
1564+
15551565
if (dest && (dest != src)) {
15561566
*(aligned_t *)dest = *(aligned_t *)src;
15571567
MACHINE_FENCE;
15581568
}
15591569

15601570
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
1561-
m->acq_owner_stat.state == qthread_id();
1571+
m->acq_owner_stat.state = qthread_readstate(CURRENT_WORKER); /* Set owner */
15621572
++m->acq_owner_stat.recursive_access_counter;
15631573
MACHINE_FENCE;
1564-
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): incrementing recursive_access_counter\n", dest, qthread_id());
1574+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): acquired recursive lock (outer)\n", dest, me->thread_id);
15651575
}
15661576

15671577
qthread_debug(FEB_BEHAVIOR, "tid %u succeeded on %p=%p\n", me->thread_id, dest, src);
@@ -1651,13 +1661,17 @@ int API_FUNC qthread_readFE_nb(aligned_t *restrict dest,
16511661
# endif /* ifdef LOCK_FREE_FEBS */
16521662
qthread_debug(FEB_DETAILS, "data structure locked\n");
16531663
/* by this point m is locked */
1654-
if (m->full == 0) { /* empty, thus, we must fail */
1655-
/* unless called from qthread_trylock on a recursive lock*/
1656-
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
1657-
1664+
if (m->full == 0) { /* empty, thus, we must block */
1665+
/* unless read_FE was taken by qthread_lock() */
1666+
/* on same thread */
1667+
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
1668+
if (m->acq_owner_stat.state == qthread_readstate(CURRENT_WORKER)) {
1669+
16581670
++m->acq_owner_stat.recursive_access_counter;
1659-
QTHREAD_FASTLOCK_UNLOCK(&m->lock);
1671+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): acquired recursive lock (inner)\n", dest, me->thread_id);
1672+
QTHREAD_FASTLOCK_UNLOCK(&m->lock);
16601673
return QTHREAD_SUCCESS;
1674+
}
16611675
}
16621676
qthread_debug(FEB_BEHAVIOR, "tid %u non-blocking fail\n", me->thread_id);
16631677
QTHREAD_FASTLOCK_UNLOCK(&m->lock);
@@ -1669,10 +1683,10 @@ int API_FUNC qthread_readFE_nb(aligned_t *restrict dest,
16691683
}
16701684

16711685
if(m->acq_owner_stat.state >= FEB_is_recursive_lock) {
1672-
m->acq_owner_stat.state == qthread_id();
1686+
m->acq_owner_stat.state = qthread_readstate(CURRENT_WORKER); /* Set owner */
16731687
++m->acq_owner_stat.recursive_access_counter;
16741688
MACHINE_FENCE;
1675-
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): incrementing recursive_access_counter\n", dest, qthread_id());
1689+
qthread_debug(FEB_BEHAVIOR, "dest=%p (tid=%i): acquired recursive lock (outer)\n", dest, me->thread_id);
16761690
}
16771691

16781692
qthread_debug(FEB_BEHAVIOR, "tid %u succeeded on %p=%p\n", me->thread_id, dest, src);

src/locks.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ int API_FUNC qthread_lock_init(const aligned_t *a, const bool is_recursive)
1616
return qthread_feb_adr_init(a, is_recursive);
1717
} /*}}} */
1818

19+
int API_FUNC qthread_lock_destroy(aligned_t *a)
20+
{ /*{{{ */
21+
return qthread_feb_adr_remove(a);
22+
}
23+
1924
int API_FUNC qthread_lock(const aligned_t *a)
2025
{ /*{{{ */
2126
return qthread_readFE(NULL, a);

test/stress/lock_acq_rel.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,47 @@
33
#include <qthread/qthread.h>
44
#include <qthread/qloop.h>
55

6-
static int64_t count = 0;
6+
static int64_t count;
77
static aligned_t lock;
8+
bool is_recursive_lock = true;
89

9-
static void task(size_t start, size_t stop, void *args_) {
10+
static void task_1(size_t start, size_t stop, void *args_) {
1011
qthread_lock(&lock);
1112
count++;
1213
qthread_unlock(&lock);
1314
}
1415

16+
static void task_2(size_t start, size_t stop, void *args_) {
17+
qthread_lock(&lock);
18+
qthread_lock(&lock);
19+
count++;
20+
qthread_unlock(&lock);
21+
qthread_unlock(&lock);
22+
}
23+
1524
int main(int argc, char *argv[]) {
1625
uint64_t iters = 1000000l;
1726
assert(qthread_initialize() == 0);
18-
qt_loop(0, iters, task, NULL);
27+
28+
/* Simple lock acquire and release */
29+
count = 0;
30+
qt_loop(0, iters, task_1, NULL);
1931
assert(iters == count);
32+
33+
/* Recursive lock acquire and release, no recursion */
34+
qthread_lock_init(&lock, is_recursive_lock);
35+
{
36+
/* Recursive lock acquire and release, no recursion */
37+
count = 0;
38+
qt_loop(0, iters, task_1, NULL);
39+
assert(iters == count);
40+
41+
/* Recursive lock acquire and release */
42+
count = 0;
43+
qt_loop(0, iters, task_2, NULL);
44+
assert(iters == count);
45+
}
46+
qthread_lock_destroy(&lock);
47+
2048
return 0;
2149
}

0 commit comments

Comments
 (0)