Skip to content

Commit ae693ff

Browse files
committed
fix releasing timing.
(1) recorded_lock_rec > current_lock_rec should not be occurred on rb_ec_vm_lock_rec_release(). (2) should be release VM lock at EXEC_TAG(), not POP_TAG(). (3) some refactoring.
1 parent 0714cb7 commit ae693ff

File tree

3 files changed

+30
-27
lines changed

3 files changed

+30
-27
lines changed

eval_intern.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,6 @@ LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *);
127127
rb_fiber_start(); \
128128
} while (0)
129129

130-
void rb_ec_vm_lock_rec_release(rb_execution_context_t *ec, int lock_rec);
131-
132-
static inline void
133-
rb_ec_vm_lock_rec_check(rb_execution_context_t *ec, int lock_rec)
134-
{
135-
if (rb_ec_vm_lock_rec(ec) != lock_rec) {
136-
rb_ec_vm_lock_rec_release(ec, lock_rec);
137-
}
138-
}
139-
140130
#define EC_PUSH_TAG(ec) do { \
141131
rb_execution_context_t * const _ec = (ec); \
142132
struct rb_vm_tag _tag; \
@@ -146,7 +136,6 @@ rb_ec_vm_lock_rec_check(rb_execution_context_t *ec, int lock_rec)
146136
_tag.lock_rec = rb_ec_vm_lock_rec(_ec); \
147137

148138
#define EC_POP_TAG() \
149-
rb_ec_vm_lock_rec_check(_ec, _tag.lock_rec); \
150139
_ec->tag = _tag.prev; \
151140
} while (0)
152141

@@ -169,12 +158,23 @@ rb_ec_vm_lock_rec_check(rb_execution_context_t *ec, int lock_rec)
169158
# define VAR_NOCLOBBERED(var) var
170159
#endif
171160

161+
static inline void
162+
rb_ec_vm_lock_rec_check(const rb_execution_context_t *ec, unsigned int recorded_lock_rec)
163+
{
164+
unsigned int current_lock_rec = rb_ec_vm_lock_rec(ec);
165+
if (current_lock_rec != recorded_lock_rec) {
166+
rb_ec_vm_lock_rec_release(ec, recorded_lock_rec, current_lock_rec);
167+
}
168+
}
169+
172170
/* clear ec->tag->state, and return the value */
173171
static inline int
174172
rb_ec_tag_state(const rb_execution_context_t *ec)
175173
{
176-
enum ruby_tag_type state = ec->tag->state;
177-
ec->tag->state = TAG_NONE;
174+
struct rb_vm_tag *tag = ec->tag;
175+
enum ruby_tag_type state = tag->state;
176+
tag->state = TAG_NONE;
177+
rb_ec_vm_lock_rec_check(ec, tag->lock_rec);
178178
return state;
179179
}
180180

vm_core.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ struct rb_vm_tag {
794794
rb_jmpbuf_t buf;
795795
struct rb_vm_tag *prev;
796796
enum ruby_tag_type state;
797-
int lock_rec;
797+
unsigned int lock_rec;
798798
};
799799

800800
STATIC_ASSERT(rb_vm_tag_buf_offset, offsetof(struct rb_vm_tag, buf) > 0);
@@ -1798,8 +1798,12 @@ rb_current_vm(void)
17981798
return ruby_current_vm_ptr;
17991799
}
18001800

1801-
static inline int
1802-
rb_ec_vm_lock_rec(rb_execution_context_t *ec)
1801+
void rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec,
1802+
unsigned int recorded_lock_rec,
1803+
unsigned int current_lock_rec);
1804+
1805+
static inline unsigned int
1806+
rb_ec_vm_lock_rec(const rb_execution_context_t *ec)
18031807
{
18041808
rb_vm_t *vm = rb_ec_vm_ptr(ec);
18051809

vm_sync.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ vm_lock_leave(rb_vm_t *vm, unsigned int *lev APPEND_LOCATION_ARGS)
116116
VM_ASSERT(vm->ractor.sync.lock_rec == *lev);
117117

118118
vm->ractor.sync.lock_rec--;
119+
*lev = vm->ractor.sync.lock_rec;
119120

120121
if (vm->ractor.sync.lock_rec == 0) {
121122
vm->ractor.sync.lock_owner = NULL;
@@ -248,21 +249,19 @@ rb_vm_barrier(void)
248249
}
249250

250251
void
251-
rb_ec_vm_lock_rec_release(rb_execution_context_t *ec, int recorded_lock_rec)
252+
rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec,
253+
unsigned int recorded_lock_rec,
254+
unsigned int current_lock_rec)
252255
{
253-
int current_lock_rec = rb_ec_vm_lock_rec(ec);
254-
unsigned int lev;
255-
256-
bp();
256+
VM_ASSERT(recorded_lock_rec != current_lock_rec);
257257

258-
if (recorded_lock_rec > current_lock_rec) {
259-
for (; recorded_lock_rec > current_lock_rec; current_lock_rec++) {
260-
RB_VM_LOCK_ENTER_LEV(&lev);
261-
}
258+
if (UNLIKELY(recorded_lock_rec > current_lock_rec)) {
259+
rb_bug("unexpected situation - recordd:%u current:%u",
260+
recorded_lock_rec, current_lock_rec);
262261
}
263262
else {
264-
for (; recorded_lock_rec < current_lock_rec; current_lock_rec--) {
265-
RB_VM_LOCK_LEAVE_LEV(&lev);
263+
while (recorded_lock_rec < current_lock_rec) {
264+
RB_VM_LOCK_LEAVE_LEV(&current_lock_rec);
266265
}
267266
}
268267

0 commit comments

Comments
 (0)