Rob Browning <[EMAIL PROTECTED]> writes: > > This would only work if you forbid side-effects, right?
Well, leave it up to the application to keep itself out of trouble if the code is not reentrant. That'd be consistent a general policy of not stopping stupid multi-thread code, only code that might crash the interpreter. > I was also wondering about the possibilities for deadlock with the > current code, and then what they might be with a srfi-45 force, Whenever arbitrary code executes in a mutex I guess there's scope for that. srfi-45 shouldn't be inherently worse. Some code below (untested) for what I think "force" could look like without per-promise mutexes. Having a magic "uncomputed" value means no locking at all once computed (same as your code). The thunk to be called is in a separate field, zapped once no longer needed. Second block of code is with two magic "uncomputed" values, one for normal and one for srfi-45 style lazy promises. If I understand how they're supposed to work :-). #define SCM_PROMISE_DATA SCM_SMOB_OBJECT #define SCM_PROMISE_EXPR SCM_SMOB_OBJECT_2 { SCM data, expr, ans; SCM_VALIDATE_SMOB (1, promise, promise); data = SCM_PROMISE_DATA (promise); if (data != SCM_PROMISE_MAGIC_UNCOMPUTED_INDICATOR) return data; SCM_CRITICAL_SECTION_START; data = SCM_PROMISE_DATA (promise); expr = SCM_PROMISE_EXPR (promise); SCM_CRITICAL_SECTION_END; if (data != SCM_PROMISE_MAGIC_UNCOMPUTED_INDICATOR) return data; ans = scm_call_0 (expr); SCM_CRITICAL_SECTION_START; data = SCM_PROMISE_DATA (promise); if (data == SCM_PROMISE_MAGIC_UNCOMPUTED_INDICATOR) { SCM_SET_PROMISE_DATA (promise, ans); /* we set the value */ SCM_SET_PROMISE_EXPR (promise, SCM_BOOL_F); /* gc the expression */ } else { /* recursive force or other thread set the value, return that */ ans = data; } SCM_CRITICAL_SECTION_END; return ans; } { SCM data, expr, ans; SCM_VALIDATE_SMOB (1, promise, promise); again: data = SCM_PROMISE_DATA (promise); if ((data & ~1) != SCM_PROMISE_MAGIC_UNCOMPUTED) return data; SCM_CRITICAL_SECTION_START; data = SCM_PROMISE_DATA (promise); expr = SCM_PROMISE_EXPR (promise); SCM_CRITICAL_SECTION_END; if ((data & ~1) != SCM_PROMISE_MAGIC_UNCOMPUTED) return data; ans = scm_call_0 (expr); SCM_CRITICAL_SECTION_START; data = SCM_PROMISE_DATA (promise); if (data == SCM_PROMISE_MAGIC_UNCOMPUTED_LAZY && SCM_PROMISE_P (ans)) { /* SRFI-45 lazy promise, mutate ourselves to ANS and go again */ SCM_SET_PROMISE_DATA (promise, SCM_PROMISE_DATA (ans)); SCM_SET_PROMISE_EXPR (promise, SCM_PROMISE_EXPR (ans)); SCM_CRITICAL_SECTION_END; goto again; } else if (data == SCM_PROMISE_MAGIC_UNCOMPUTED_NORMAL) { SCM_SET_PROMISE_DATA (promise, ans); /* we set the value */ SCM_SET_PROMISE_EXPR (promise, SCM_BOOL_F); /* gc the expression */ } else { /* recursive force or other thread set the value, return that */ ans = data; } SCM_CRITICAL_SECTION_END; return ans; } _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://lists.gnu.org/mailman/listinfo/guile-devel