Skip to content

Commit aab1815

Browse files
committed
fix: tform: regression due to #797
The fix of #797 causes deadlocks when assigned MODMAX or MODMIN dollars appear on their RHS, inside a function argument. In that case, another lock on the dollar is attempted. For example: `$dol = max_($dol,something);` Use PTHREAD_MUTEX_RECURSIVE for dollar variables, such that a thread may re-lock a dollar during assignment operations. The MODSUM case has always deadlocked for such constructions.
1 parent ea3fc30 commit aab1815

6 files changed

Lines changed: 99 additions & 6 deletions

File tree

check/fixes.frm

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,48 @@ P;
24762476
assert succeeded?
24772477
assert result("F") =~ expr("9999")
24782478
*--#] Issue268_2 :
2479+
*--#[ Issue271 :
2480+
#-
2481+
#define N "16"
2482+
Symbol x,n;
2483+
Local test = -{`N'*(`N'+1)/2} + <x^1>+...+<x^`N'>;
2484+
.sort
2485+
#$split = 0;
2486+
Identify x^n?pos_ = n;
2487+
$split = $split + term_;
2488+
ModuleOption sum $split;
2489+
.sort
2490+
#message split = `$split'
2491+
Print;
2492+
.end
2493+
assert succeeded?
2494+
assert stdout =~ exact_pattern(<<EOF)
2495+
~~~split = 0
2496+
EOF
2497+
assert result("test") =~ expr("0")
2498+
*--#] Issue271 :
2499+
*--#[ Issue271b :
2500+
#-
2501+
#define N "16"
2502+
Symbol x,n;
2503+
Local test = -{`N'*(`N'+1)/2} + <x^1>+...+<x^`N'>;
2504+
.sort
2505+
#$split = 0;
2506+
$split = $split + term_;
2507+
ModuleOption sum $split;
2508+
.sort
2509+
#message split = `$split'
2510+
Print;
2511+
.end
2512+
# This symbolic sum doesn't work in TFORM, but does work in ParFORM:
2513+
#pend_if threaded?
2514+
assert succeeded?
2515+
assert stdout =~ exact_pattern(<<EOF)
2516+
~~~split = -136+x+x^2+x^3+x^4+x^5+x^6+x^7+x^8+x^9+x^10+x^11+x^12+x^13+x^14+x^15
2517+
+x^16
2518+
EOF
2519+
assert result("test") =~ expr("- 136 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16")
2520+
*--#] Issue271b :
24792521
*--#[ Issue277 :
24802522
* A question about addargs
24812523
CFunction f,g,h;
@@ -4448,6 +4490,53 @@ assert warning?("Excess information in symmetric properties")
44484490
assert warning?("Illegal information in number of arguments properties")
44494491
assert warning?("Undefined $-variable")
44504492
*--#] Issue766 :
4493+
*--#[ Issue796 :
4494+
* Regression: the fix for 796 deadlocks here:
4495+
Symbol x;
4496+
Local test = <x^1>+...+<x^128>;
4497+
#$maxpow = 0;
4498+
$maxpow = max_($maxpow,count_(x,1));
4499+
ModuleOption maximum $maxpow;
4500+
.sort
4501+
#message maxpow: `$maxpow'
4502+
.end
4503+
assert succeeded?
4504+
assert stdout =~ exact_pattern(<<'EOF')
4505+
maxpow: 128
4506+
EOF
4507+
*--#] Issue796 :
4508+
*--#[ Issue796b :
4509+
* Regression: the fix for 796 deadlocks here:
4510+
Symbol x;
4511+
Local test = <x^1>+...+<x^128>;
4512+
#$minpow = 129;
4513+
$minpow = min_($minpow,count_(x,1));
4514+
ModuleOption minimum $minpow;
4515+
.sort
4516+
#message minpow: `$minpow'
4517+
.end
4518+
assert succeeded?
4519+
assert stdout =~ exact_pattern(<<'EOF')
4520+
minpow: 1
4521+
EOF
4522+
*--#] Issue796b :
4523+
*--#[ Issue796c :
4524+
* This case has always deadlocked:
4525+
Symbol x;
4526+
Local test = <x^1>+...+<x^128>;
4527+
#$sumpow = 129;
4528+
$sumpow = max_($sumpow,count_(x,1));
4529+
ModuleOption sum $sumpow;
4530+
.sort
4531+
#message sumpow: `$sumpow'
4532+
.end
4533+
# ParFORM does not pass this test
4534+
#pend_if mpi?
4535+
assert succeeded?
4536+
assert stdout =~ exact_pattern(<<'EOF')
4537+
sumpow: 129
4538+
EOF
4539+
*--#] Issue796c :
44514540
*--#[ PullReq535 :
44524541
* This test requires more than the specified 50K workspace.
44534542
#:maxtermsize 200

sources/checkpoint.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,7 @@ int DoRecovery(int *moduletype)
20992099
R_COPY_B(d->where, size, void*);
21002100
}
21012101
#ifdef WITHPTHREADS
2102-
d->pthreadslock = dummylock;
2102+
INIRECLOCK(d->pthreadslock);
21032103
#endif
21042104
if ( d->nfactors > 1 ) {
21052105
R_COPY_B(d->factors,sizeof(FACDOLLAR)*d->nfactors,FACDOLLAR*);

sources/declare.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,12 @@ static inline LONG ULongToLong(ULONG x)
462462
#define INILOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
463463
#define EXTERNRWLOCK(x) extern pthread_rwlock_t x;
464464
#define INIRWLOCK(x) pthread_rwlock_t x = PTHREAD_RWLOCK_INITIALIZER;
465+
#define INIRECLOCK(x) do { pthread_mutexattr_t attrib; \
466+
pthread_mutexattr_init(&attrib); \
467+
pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE); \
468+
pthread_mutex_init(&(x), &attrib); \
469+
pthread_mutexattr_destroy(&attrib); \
470+
} while(0)
465471
#ifdef DEBUGGINGLOCKS
466472
#include <asm/errno.h>
467473
#define LOCK(x) while ( pthread_mutex_trylock(&(x)) == EBUSY ) {}

sources/dollar.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535

3636
#include "form3.h"
3737

38-
/* EXTERNLOCK(dummylock) */
39-
4038
static UBYTE underscore[2] = {'_',0};
4139

4240
/*
@@ -1566,7 +1564,7 @@ DOLLARS DolToTerms(PHEAD WORD numdollar)
15661564
newd->size = size;
15671565
newd->numdummies = d->numdummies;
15681566
#ifdef WITHPTHREADS
1569-
newd->pthreadslock = dummylock;
1567+
INIRECLOCK(newd->pthreadslock);
15701568
#endif
15711569
size++;
15721570
NCOPY(t,w,size);

sources/module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ UBYTE * DoModDollar(UBYTE *s, int type)
718718
dlocal->where[i] = dglobal->where[i];
719719
dlocal->where[dlocal->size] = 0;
720720
}
721-
dlocal->pthreadslock = dummylock;
721+
INIRECLOCK(dlocal->pthreadslock);
722722
dlocal->nfactors = dglobal->nfactors;
723723
if ( dglobal->nfactors > 1 ) {
724724
int nsize;

sources/names.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2612,7 +2612,7 @@ int AddDollar(UBYTE *name, WORD type, WORD *start, LONG size)
26122612
dol->zero = 0;
26132613
dol->numdummies = 0;
26142614
#ifdef WITHPTHREADS
2615-
dol->pthreadslock = dummylock;
2615+
INIRECLOCK(dol->pthreadslock);
26162616
#endif
26172617
dol->nfactors = 0;
26182618
dol->factors = 0;

0 commit comments

Comments
 (0)