aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.c
diff options
context:
space:
mode:
authorKjell Winblad <[email protected]>2019-02-06 11:29:41 +0100
committerKjell Winblad <[email protected]>2019-05-27 12:21:18 +0200
commitb72e9d38110aac082cd98084dcb507a61b1bc3ad (patch)
tree0c380c5f8a722e72950c5d71664419caefa90acb /erts/emulator/beam/bif.c
parentfe77a98f2e76b8e577df8fc68cb2a68adabc413c (diff)
downloadotp-b72e9d38110aac082cd98084dcb507a61b1bc3ad.tar.gz
otp-b72e9d38110aac082cd98084dcb507a61b1bc3ad.tar.bz2
otp-b72e9d38110aac082cd98084dcb507a61b1bc3ad.zip
Make erlang:phash2/1 and erlang:phash2/2 yield
The erlang:phash2 functions did not yield even if the input was very large and a call to one of the functions did only consume a single reduction. This commit fixes these problems.
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r--erts/emulator/beam/bif.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index b81056c774..b35fe2fc02 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4866,9 +4866,13 @@ BIF_RETTYPE phash_2(BIF_ALIST_2)
BIF_RETTYPE phash2_1(BIF_ALIST_1)
{
Uint32 hash;
-
- hash = make_hash2(BIF_ARG_1);
- BIF_RET(make_small(hash & ((1L << 27) - 1)));
+ Eterm trap_state = THE_NON_VALUE;
+ hash = trapping_make_hash2(BIF_ARG_1, &trap_state, BIF_P);
+ if (trap_state == THE_NON_VALUE) {
+ BIF_RET(make_small(hash & ((1L << 27) - 1)));
+ } else {
+ BIF_TRAP1(bif_export[BIF_phash2_1], BIF_P, trap_state);
+ }
}
BIF_RETTYPE phash2_2(BIF_ALIST_2)
@@ -4876,6 +4880,7 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2)
Uint32 hash;
Uint32 final_hash;
Uint32 range;
+ Eterm trap_state = THE_NON_VALUE;
/* Check for special case 2^32 */
if (term_equals_2pow32(BIF_ARG_2)) {
@@ -4887,7 +4892,10 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2)
}
range = (Uint32) u;
}
- hash = make_hash2(BIF_ARG_1);
+ hash = trapping_make_hash2(BIF_ARG_1, &trap_state, BIF_P);
+ if (trap_state != THE_NON_VALUE) {
+ BIF_TRAP2(bif_export[BIF_phash2_2], BIF_P, trap_state, BIF_ARG_2);
+ }
if (range) {
final_hash = hash % range; /* [0..range-1] */
} else {