vyzo's thread mailboxes (3.99.0.19)
svn: r9010
This commit is contained in:
parent
a314447264
commit
c58820e30d
|
@ -55,6 +55,7 @@
|
||||||
"David Van Horn, "
|
"David Van Horn, "
|
||||||
"Anton van Straaten, "
|
"Anton van Straaten, "
|
||||||
"Dale Vaillancourt, "
|
"Dale Vaillancourt, "
|
||||||
|
"Dimitris Vyzovitis, "
|
||||||
"Stephanie Weirich, "
|
"Stephanie Weirich, "
|
||||||
"Noel Welsh, "
|
"Noel Welsh, "
|
||||||
"Adam Wick, "
|
"Adam Wick, "
|
||||||
|
|
|
@ -42,7 +42,11 @@
|
||||||
free-transformer-identifier=?
|
free-transformer-identifier=?
|
||||||
free-template-identifier=?
|
free-template-identifier=?
|
||||||
free-label-identifier=?
|
free-label-identifier=?
|
||||||
vector-copy!)
|
vector-copy!
|
||||||
|
thread-send
|
||||||
|
thread-receive
|
||||||
|
thread-try-receive
|
||||||
|
thread-receive-evt)
|
||||||
(rename syntax->datum syntax-object->datum)
|
(rename syntax->datum syntax-object->datum)
|
||||||
(rename datum->syntax datum->syntax-object)
|
(rename datum->syntax datum->syntax-object)
|
||||||
(rename free-identifier=? module-identifier=?)
|
(rename free-identifier=? module-identifier=?)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
@note-lib-only[scheme/async-channel]
|
@note-lib-only[scheme/async-channel]
|
||||||
|
|
||||||
|
@margin-note/ref{See also @secref["threadmbox"].}
|
||||||
|
|
||||||
@defproc[(async-channel? [v any/c]) boolean?]{
|
@defproc[(async-channel? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,14 @@
|
||||||
[(_ s) (scheme s)]))
|
[(_ s) (scheme s)]))
|
||||||
(provide exnraise Exn)
|
(provide exnraise Exn)
|
||||||
|
|
||||||
(provide refalso moreref Guide guideintro guidesecref
|
(provide margin-note/ref
|
||||||
|
refalso moreref Guide guideintro guidesecref
|
||||||
HonuManual)
|
HonuManual)
|
||||||
|
|
||||||
|
(define (margin-note/ref . s)
|
||||||
|
(apply margin-note
|
||||||
|
(decode-content (cons magnify s))))
|
||||||
|
|
||||||
(define (refalso tag . s)
|
(define (refalso tag . s)
|
||||||
(apply margin-note
|
(apply margin-note
|
||||||
(decode-content (append (list magnify (secref tag) " also provides information on ")
|
(decode-content (append (list magnify (secref tag) " also provides information on ")
|
||||||
|
|
|
@ -222,3 +222,34 @@ suspended and then resumes after a call to
|
||||||
@scheme[thread-suspend-evt], the result event remains ready; after
|
@scheme[thread-suspend-evt], the result event remains ready; after
|
||||||
each resume of @scheme[thd] created a fresh event to be returned by
|
each resume of @scheme[thd] created a fresh event to be returned by
|
||||||
@scheme[thread-suspend-evt].}
|
@scheme[thread-suspend-evt].}
|
||||||
|
|
||||||
|
@;------------------------------------------------------------------------
|
||||||
|
@section[#:tag "threadmbox"]{Thread Mailboxes}
|
||||||
|
|
||||||
|
Each thread has a @defterm{mailbox} through which it can receive
|
||||||
|
arbitrary message. In other words, each thread has a built-in
|
||||||
|
asynchronous channel.
|
||||||
|
|
||||||
|
@margin-note/ref{See also @secref["async-channel"].}
|
||||||
|
|
||||||
|
@defproc[(thread-send [thd thread?] [v any/c]) void?]{
|
||||||
|
|
||||||
|
Queues @scheme[v] as a message to @scheme[thd]. This function never
|
||||||
|
blocks.}
|
||||||
|
|
||||||
|
@defproc[(thread-receive) any/c]{
|
||||||
|
|
||||||
|
Receives and dequeues a message queued for the current thread, if
|
||||||
|
any. If no message is available, @scheme[thread-receive] blocks until
|
||||||
|
one is available.}
|
||||||
|
|
||||||
|
@defproc[(thread-try-receive) any/c]{
|
||||||
|
|
||||||
|
Receives and dequeues a message queued for the current thread, if any,
|
||||||
|
or returns @scheme[#f] immediately if no message is available.}
|
||||||
|
|
||||||
|
@defproc[(thread-receive-evt) evt?]{
|
||||||
|
|
||||||
|
Returns a constant @tech{synchronizable event} (see @secref["sync"])
|
||||||
|
that becomes ready when the synchronizing thread has a message to
|
||||||
|
receive. The event result is itself.}
|
||||||
|
|
|
@ -687,6 +687,44 @@
|
||||||
(test #f sync/timeout 0 (thread-suspend-evt t))
|
(test #f sync/timeout 0 (thread-suspend-evt t))
|
||||||
(test d thread-dead-evt t)))))
|
(test d thread-dead-evt t)))))
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
;; thread mbox
|
||||||
|
|
||||||
|
(test #f thread-try-receive)
|
||||||
|
(test #f sync/timeout 0 (thread-receive-evt))
|
||||||
|
(test (void) thread-send (current-thread) 10)
|
||||||
|
(let ([t (thread-receive-evt)])
|
||||||
|
(test t sync/timeout 10 t))
|
||||||
|
(test 10 thread-try-receive)
|
||||||
|
(test #f thread-try-receive)
|
||||||
|
(let ([t (current-thread)])
|
||||||
|
(thread (lambda ()
|
||||||
|
(sync (system-idle-evt))
|
||||||
|
(thread-send t 35))))
|
||||||
|
(test 35 thread-receive)
|
||||||
|
(let* ([s #f]
|
||||||
|
[t1 (let ([t (current-thread)])
|
||||||
|
(thread (lambda ()
|
||||||
|
(set! s (thread-receive)))))])
|
||||||
|
(sync (system-idle-evt))
|
||||||
|
(thread-suspend t1)
|
||||||
|
(thread-send t1 'apple)
|
||||||
|
(sync (system-idle-evt))
|
||||||
|
(test #f values s)
|
||||||
|
(thread-resume t1)
|
||||||
|
(sync (system-idle-evt))
|
||||||
|
(test 'apple values s))
|
||||||
|
(let* ([s 0]
|
||||||
|
[t (thread (lambda ()
|
||||||
|
(set! s (list (thread-receive)
|
||||||
|
(thread-receive)
|
||||||
|
(thread-receive)))))])
|
||||||
|
(thread-send t 0)
|
||||||
|
(thread-send t 1)
|
||||||
|
(thread-send t 2)
|
||||||
|
(sync (system-idle-evt))
|
||||||
|
(test '(0 1 2) values s))
|
||||||
|
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
;; Garbage collection
|
;; Garbage collection
|
||||||
|
|
||||||
|
|
|
@ -1066,6 +1066,10 @@ typedef struct Scheme_Thread {
|
||||||
|
|
||||||
Scheme_Object *name;
|
Scheme_Object *name;
|
||||||
|
|
||||||
|
Scheme_Object *mbox_first;
|
||||||
|
Scheme_Object *mbox_last;
|
||||||
|
Scheme_Object *mbox_sema;
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
int gc_owner_set;
|
int gc_owner_set;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1678,6 +1678,9 @@ static int thread_val_MARK(void *p) {
|
||||||
gcMARK(pr->dead_box);
|
gcMARK(pr->dead_box);
|
||||||
gcMARK(pr->running_box);
|
gcMARK(pr->running_box);
|
||||||
|
|
||||||
|
gcMARK(pr->mbox_first);
|
||||||
|
gcMARK(pr->mbox_last);
|
||||||
|
gcMARK(pr->mbox_sema);
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Thread));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Thread));
|
||||||
}
|
}
|
||||||
|
@ -1775,6 +1778,9 @@ static int thread_val_FIXUP(void *p) {
|
||||||
gcFIXUP(pr->dead_box);
|
gcFIXUP(pr->dead_box);
|
||||||
gcFIXUP(pr->running_box);
|
gcFIXUP(pr->running_box);
|
||||||
|
|
||||||
|
gcFIXUP(pr->mbox_first);
|
||||||
|
gcFIXUP(pr->mbox_last);
|
||||||
|
gcFIXUP(pr->mbox_sema);
|
||||||
return
|
return
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Thread));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Thread));
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,6 +692,9 @@ thread_val {
|
||||||
gcMARK(pr->dead_box);
|
gcMARK(pr->dead_box);
|
||||||
gcMARK(pr->running_box);
|
gcMARK(pr->running_box);
|
||||||
|
|
||||||
|
gcMARK(pr->mbox_first);
|
||||||
|
gcMARK(pr->mbox_last);
|
||||||
|
gcMARK(pr->mbox_sema);
|
||||||
size:
|
size:
|
||||||
gcBYTES_TO_WORDS(sizeof(Scheme_Thread));
|
gcBYTES_TO_WORDS(sizeof(Scheme_Thread));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
EXPECTED_PRIM_COUNT to the new value, and then USE_COMPILED_STARTUP
|
EXPECTED_PRIM_COUNT to the new value, and then USE_COMPILED_STARTUP
|
||||||
can be set to 1 again. */
|
can be set to 1 again. */
|
||||||
|
|
||||||
#define USE_COMPILED_STARTUP 1
|
#define USE_COMPILED_STARTUP 0
|
||||||
|
|
||||||
#define EXPECTED_PRIM_COUNT 899
|
#define EXPECTED_PRIM_COUNT 903
|
||||||
|
|
||||||
#ifdef MZSCHEME_SOMETHING_OMITTED
|
#ifdef MZSCHEME_SOMETHING_OMITTED
|
||||||
# undef USE_COMPILED_STARTUP
|
# undef USE_COMPILED_STARTUP
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
consistently.)
|
consistently.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MZSCHEME_VERSION "3.99.0.18"
|
#define MZSCHEME_VERSION "3.99.0.19"
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_X 3
|
#define MZSCHEME_VERSION_X 3
|
||||||
#define MZSCHEME_VERSION_Y 99
|
#define MZSCHEME_VERSION_Y 99
|
||||||
#define MZSCHEME_VERSION_Z 0
|
#define MZSCHEME_VERSION_Z 0
|
||||||
#define MZSCHEME_VERSION_W 18
|
#define MZSCHEME_VERSION_W 19
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||||
|
|
|
@ -38,6 +38,11 @@ static Scheme_Object *make_channel(int n, Scheme_Object **p);
|
||||||
static Scheme_Object *make_channel_put(int n, Scheme_Object **p);
|
static Scheme_Object *make_channel_put(int n, Scheme_Object **p);
|
||||||
static Scheme_Object *channel_p(int n, Scheme_Object **p);
|
static Scheme_Object *channel_p(int n, Scheme_Object **p);
|
||||||
|
|
||||||
|
static Scheme_Object *thread_send(int n, Scheme_Object **p);
|
||||||
|
static Scheme_Object *thread_receive(int n, Scheme_Object **p);
|
||||||
|
static Scheme_Object *thread_try_receive(int n, Scheme_Object **p);
|
||||||
|
static Scheme_Object *thread_receive_evt(int n, Scheme_Object **p);
|
||||||
|
|
||||||
static Scheme_Object *make_alarm(int n, Scheme_Object **p);
|
static Scheme_Object *make_alarm(int n, Scheme_Object **p);
|
||||||
static Scheme_Object *make_sys_idle(int n, Scheme_Object **p);
|
static Scheme_Object *make_sys_idle(int n, Scheme_Object **p);
|
||||||
|
|
||||||
|
@ -47,12 +52,14 @@ static int channel_syncer_ready(Scheme_Object *ch, Scheme_Schedule_Info *sinfo);
|
||||||
static int alarm_ready(Scheme_Object *ch, Scheme_Schedule_Info *sinfo);
|
static int alarm_ready(Scheme_Object *ch, Scheme_Schedule_Info *sinfo);
|
||||||
static int always_ready(Scheme_Object *w);
|
static int always_ready(Scheme_Object *w);
|
||||||
static int never_ready(Scheme_Object *w);
|
static int never_ready(Scheme_Object *w);
|
||||||
|
static int thread_recv_ready(Scheme_Object *ch, Scheme_Schedule_Info *sinfo);
|
||||||
|
|
||||||
static int pending_break(Scheme_Thread *p);
|
static int pending_break(Scheme_Thread *p);
|
||||||
|
|
||||||
int scheme_main_was_once_suspended;
|
int scheme_main_was_once_suspended;
|
||||||
|
|
||||||
static Scheme_Object *system_idle_put_evt;
|
static Scheme_Object *system_idle_put_evt;
|
||||||
|
static Scheme_Object *thread_recv_evt;
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
static void register_traversers(void);
|
static void register_traversers(void);
|
||||||
|
@ -136,6 +143,28 @@ void scheme_init_sema(Scheme_Env *env)
|
||||||
1, 1, 1),
|
1, 1, 1),
|
||||||
env);
|
env);
|
||||||
|
|
||||||
|
scheme_add_global_constant("thread-send",
|
||||||
|
scheme_make_prim_w_arity(thread_send,
|
||||||
|
"thread-send",
|
||||||
|
2, 2),
|
||||||
|
env);
|
||||||
|
scheme_add_global_constant("thread-receive",
|
||||||
|
scheme_make_prim_w_arity(thread_receive,
|
||||||
|
"thread-receive",
|
||||||
|
0, 0),
|
||||||
|
env);
|
||||||
|
scheme_add_global_constant("thread-try-receive",
|
||||||
|
scheme_make_prim_w_arity(thread_try_receive,
|
||||||
|
"thread-try-receive",
|
||||||
|
0, 0),
|
||||||
|
env);
|
||||||
|
scheme_add_global_constant("thread-receive-evt",
|
||||||
|
scheme_make_prim_w_arity(thread_receive_evt,
|
||||||
|
"thread-receive-evt",
|
||||||
|
0, 0),
|
||||||
|
env);
|
||||||
|
|
||||||
|
|
||||||
scheme_add_global_constant("alarm-evt",
|
scheme_add_global_constant("alarm-evt",
|
||||||
scheme_make_prim_w_arity(make_alarm,
|
scheme_make_prim_w_arity(make_alarm,
|
||||||
"alarm-evt",
|
"alarm-evt",
|
||||||
|
@ -157,6 +186,11 @@ void scheme_init_sema(Scheme_Env *env)
|
||||||
o->type = scheme_never_evt_type;
|
o->type = scheme_never_evt_type;
|
||||||
scheme_add_global_constant("never-evt", o, env);
|
scheme_add_global_constant("never-evt", o, env);
|
||||||
|
|
||||||
|
REGISTER_SO(thread_recv_evt);
|
||||||
|
o = scheme_alloc_small_object();
|
||||||
|
o->type = scheme_thread_recv_evt_type;
|
||||||
|
thread_recv_evt = o;
|
||||||
|
|
||||||
REGISTER_SO(scheme_system_idle_channel);
|
REGISTER_SO(scheme_system_idle_channel);
|
||||||
scheme_system_idle_channel = scheme_make_channel();
|
scheme_system_idle_channel = scheme_make_channel();
|
||||||
|
|
||||||
|
@ -168,6 +202,7 @@ void scheme_init_sema(Scheme_Env *env)
|
||||||
scheme_add_evt(scheme_alarm_type, (Scheme_Ready_Fun)alarm_ready, NULL, NULL, 0);
|
scheme_add_evt(scheme_alarm_type, (Scheme_Ready_Fun)alarm_ready, NULL, NULL, 0);
|
||||||
scheme_add_evt(scheme_always_evt_type, always_ready, NULL, NULL, 0);
|
scheme_add_evt(scheme_always_evt_type, always_ready, NULL, NULL, 0);
|
||||||
scheme_add_evt(scheme_never_evt_type, never_ready, NULL, NULL, 0);
|
scheme_add_evt(scheme_never_evt_type, never_ready, NULL, NULL, 0);
|
||||||
|
scheme_add_evt(scheme_thread_recv_evt_type, (Scheme_Ready_Fun)thread_recv_ready, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheme_Object *scheme_make_sema(long v)
|
Scheme_Object *scheme_make_sema(long v)
|
||||||
|
@ -842,7 +877,7 @@ static Scheme_Object *block_sema(int n, Scheme_Object **p)
|
||||||
|
|
||||||
scheme_wait_sema(p[0], 0);
|
scheme_wait_sema(p[0], 0);
|
||||||
|
|
||||||
/* In case a break appeared after wwe received the post,
|
/* In case a break appeared after we received the post,
|
||||||
check for a break, because scheme_wait_sema() won't: */
|
check for a break, because scheme_wait_sema() won't: */
|
||||||
scheme_check_break_now();
|
scheme_check_break_now();
|
||||||
|
|
||||||
|
@ -975,6 +1010,134 @@ int scheme_try_channel_get(Scheme_Object *ch)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Thread mbox */
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
static void make_mbox_sema(Scheme_Thread *p)
|
||||||
|
{
|
||||||
|
if (!p->mbox_sema) {
|
||||||
|
Scheme_Object *sema = NULL;
|
||||||
|
sema = scheme_make_sema(0);
|
||||||
|
p->mbox_sema = sema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mbox_push(Scheme_Thread *p, Scheme_Object *o)
|
||||||
|
{
|
||||||
|
Scheme_Object *next;
|
||||||
|
|
||||||
|
next = scheme_make_raw_pair(o, NULL);
|
||||||
|
|
||||||
|
if (p->mbox_first) {
|
||||||
|
SCHEME_CDR(p->mbox_last) = next;
|
||||||
|
p->mbox_last = next;
|
||||||
|
} else {
|
||||||
|
p->mbox_first = next;
|
||||||
|
p->mbox_last = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
make_mbox_sema(p);
|
||||||
|
scheme_post_sema(p->mbox_sema);
|
||||||
|
/* Post can't overflow the semaphore, because we'd run out of
|
||||||
|
memory for the queue, first. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *mbox_pop( Scheme_Thread *p, int dec)
|
||||||
|
{
|
||||||
|
/* Assertion: mbox_first != NULL */
|
||||||
|
Scheme_Object *r = NULL;
|
||||||
|
|
||||||
|
r = SCHEME_CAR(p->mbox_first);
|
||||||
|
p->mbox_first = SCHEME_CDR(p->mbox_first);
|
||||||
|
if (!p->mbox_first)
|
||||||
|
p->mbox_last = NULL;
|
||||||
|
|
||||||
|
if (dec)
|
||||||
|
scheme_try_plain_sema(p->mbox_sema);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *thread_send(int argc, Scheme_Object **argv)
|
||||||
|
{
|
||||||
|
if (SCHEME_THREADP(argv[0])) {
|
||||||
|
int running;
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
scheme_check_proc_arity("thread-send", 0, 2, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
running = ((Scheme_Thread*)argv[0])->running;
|
||||||
|
if (MZTHREAD_STILL_RUNNING(running)) {
|
||||||
|
mbox_push((Scheme_Thread*)argv[0], argv[1]);
|
||||||
|
return scheme_void;
|
||||||
|
} else {
|
||||||
|
if (argc > 2) {
|
||||||
|
return _scheme_tail_apply(argv[2], 0, NULL);
|
||||||
|
} else
|
||||||
|
scheme_raise_exn(MZEXN_FAIL, "thread-send: thread is not running");
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
scheme_wrong_type("thread-send", "thread", 0, argc, argv);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *thread_receive(int argc, Scheme_Object **argv)
|
||||||
|
{
|
||||||
|
/* The mbox semaphore can only be downed by the current thread, so
|
||||||
|
receive/try-receive can directly dec+pop without syncing
|
||||||
|
(by calling mbox_pop with dec=1). */
|
||||||
|
if (scheme_current_thread->mbox_first) {
|
||||||
|
return mbox_pop(scheme_current_thread, 1);
|
||||||
|
} else {
|
||||||
|
Scheme_Object *v;
|
||||||
|
Scheme_Thread *p = scheme_current_thread;
|
||||||
|
|
||||||
|
make_mbox_sema(p);
|
||||||
|
|
||||||
|
scheme_wait_sema(p->mbox_sema, 0);
|
||||||
|
/* We're relying on atomicity of return after wait succeeds to ensure
|
||||||
|
that a semaphore wait guarantees a mailbox dequeue. */
|
||||||
|
v = mbox_pop(p, 0);
|
||||||
|
|
||||||
|
/* Due to that atomicity, though, we're obliged to check for
|
||||||
|
a break at this point: */
|
||||||
|
scheme_check_break_now();
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *thread_try_receive(int argc, Scheme_Object **argv)
|
||||||
|
{
|
||||||
|
if (scheme_current_thread->mbox_first)
|
||||||
|
return mbox_pop(scheme_current_thread, 1);
|
||||||
|
else
|
||||||
|
return scheme_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *thread_receive_evt(int argc, Scheme_Object **argv)
|
||||||
|
{
|
||||||
|
return thread_recv_evt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thread_recv_ready(Scheme_Object *ch, Scheme_Schedule_Info *sinfo)
|
||||||
|
{
|
||||||
|
Scheme_Thread *p;
|
||||||
|
|
||||||
|
p = sinfo->false_positive_ok;
|
||||||
|
if (!p)
|
||||||
|
p = scheme_current_thread;
|
||||||
|
|
||||||
|
make_mbox_sema(p);
|
||||||
|
|
||||||
|
scheme_set_sync_target(sinfo, p->mbox_sema, thread_recv_evt, NULL, 1, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* alarms */
|
/* alarms */
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
|
@ -140,103 +140,104 @@ enum {
|
||||||
scheme_thread_set_type, /* 122 */
|
scheme_thread_set_type, /* 122 */
|
||||||
scheme_string_converter_type, /* 123 */
|
scheme_string_converter_type, /* 123 */
|
||||||
scheme_alarm_type, /* 124 */
|
scheme_alarm_type, /* 124 */
|
||||||
scheme_thread_cell_type, /* 125 */
|
scheme_thread_recv_evt_type, /* 125 */
|
||||||
scheme_channel_syncer_type, /* 126 */
|
scheme_thread_cell_type, /* 126 */
|
||||||
scheme_special_comment_type, /* 127 */
|
scheme_channel_syncer_type, /* 127 */
|
||||||
scheme_write_evt_type, /* 128 */
|
scheme_special_comment_type, /* 128 */
|
||||||
scheme_always_evt_type, /* 129 */
|
scheme_write_evt_type, /* 129 */
|
||||||
scheme_never_evt_type, /* 130 */
|
scheme_always_evt_type, /* 130 */
|
||||||
scheme_progress_evt_type, /* 131 */
|
scheme_never_evt_type, /* 131 */
|
||||||
scheme_certifications_type, /* 132 */
|
scheme_progress_evt_type, /* 132 */
|
||||||
scheme_already_comp_type, /* 133 */
|
scheme_certifications_type, /* 133 */
|
||||||
scheme_readtable_type, /* 134 */
|
scheme_already_comp_type, /* 134 */
|
||||||
scheme_intdef_context_type, /* 135 */
|
scheme_readtable_type, /* 135 */
|
||||||
scheme_lexical_rib_type, /* 136 */
|
scheme_intdef_context_type, /* 136 */
|
||||||
scheme_thread_cell_values_type, /* 137 */
|
scheme_lexical_rib_type, /* 137 */
|
||||||
scheme_global_ref_type, /* 138 */
|
scheme_thread_cell_values_type, /* 138 */
|
||||||
scheme_cont_mark_chain_type, /* 139 */
|
scheme_global_ref_type, /* 139 */
|
||||||
scheme_raw_pair_type, /* 140 */
|
scheme_cont_mark_chain_type, /* 140 */
|
||||||
scheme_prompt_type, /* 141 */
|
scheme_raw_pair_type, /* 141 */
|
||||||
scheme_prompt_tag_type, /* 142 */
|
scheme_prompt_type, /* 142 */
|
||||||
scheme_expanded_syntax_type, /* 143 */
|
scheme_prompt_tag_type, /* 143 */
|
||||||
scheme_delay_syntax_type, /* 144 */
|
scheme_expanded_syntax_type, /* 144 */
|
||||||
scheme_cust_box_type, /* 145 */
|
scheme_delay_syntax_type, /* 145 */
|
||||||
scheme_resolved_module_path_type, /* 146 */
|
scheme_cust_box_type, /* 146 */
|
||||||
scheme_module_phase_exports_type, /* 147 */
|
scheme_resolved_module_path_type, /* 147 */
|
||||||
|
scheme_module_phase_exports_type, /* 148 */
|
||||||
|
|
||||||
#ifdef MZTAG_REQUIRED
|
#ifdef MZTAG_REQUIRED
|
||||||
_scheme_last_normal_type_, /* 148 */
|
_scheme_last_normal_type_, /* 149 */
|
||||||
|
|
||||||
scheme_rt_weak_array, /* 149 */
|
scheme_rt_weak_array, /* 150 */
|
||||||
|
|
||||||
scheme_rt_comp_env, /* 150 */
|
scheme_rt_comp_env, /* 151 */
|
||||||
scheme_rt_constant_binding, /* 151 */
|
scheme_rt_constant_binding, /* 152 */
|
||||||
scheme_rt_resolve_info, /* 152 */
|
scheme_rt_resolve_info, /* 153 */
|
||||||
scheme_rt_optimize_info, /* 153 */
|
scheme_rt_optimize_info, /* 154 */
|
||||||
scheme_rt_compile_info, /* 154 */
|
scheme_rt_compile_info, /* 155 */
|
||||||
scheme_rt_cont_mark, /* 155 */
|
scheme_rt_cont_mark, /* 156 */
|
||||||
scheme_rt_saved_stack, /* 156 */
|
scheme_rt_saved_stack, /* 157 */
|
||||||
scheme_rt_reply_item, /* 157 */
|
scheme_rt_reply_item, /* 158 */
|
||||||
scheme_rt_closure_info, /* 158 */
|
scheme_rt_closure_info, /* 159 */
|
||||||
scheme_rt_overflow, /* 159 */
|
scheme_rt_overflow, /* 160 */
|
||||||
scheme_rt_overflow_jmp, /* 160 */
|
scheme_rt_overflow_jmp, /* 161 */
|
||||||
scheme_rt_meta_cont, /* 161 */
|
scheme_rt_meta_cont, /* 162 */
|
||||||
scheme_rt_dyn_wind_cell, /* 162 */
|
scheme_rt_dyn_wind_cell, /* 163 */
|
||||||
scheme_rt_dyn_wind_info, /* 163 */
|
scheme_rt_dyn_wind_info, /* 164 */
|
||||||
scheme_rt_dyn_wind, /* 164 */
|
scheme_rt_dyn_wind, /* 165 */
|
||||||
scheme_rt_dup_check, /* 165 */
|
scheme_rt_dup_check, /* 166 */
|
||||||
scheme_rt_thread_memory, /* 166 */
|
scheme_rt_thread_memory, /* 167 */
|
||||||
scheme_rt_input_file, /* 167 */
|
scheme_rt_input_file, /* 168 */
|
||||||
scheme_rt_input_fd, /* 168 */
|
scheme_rt_input_fd, /* 169 */
|
||||||
scheme_rt_oskit_console_input, /* 169 */
|
scheme_rt_oskit_console_input, /* 170 */
|
||||||
scheme_rt_tested_input_file, /* 170 */
|
scheme_rt_tested_input_file, /* 171 */
|
||||||
scheme_rt_tested_output_file, /* 171 */
|
scheme_rt_tested_output_file, /* 172 */
|
||||||
scheme_rt_indexed_string, /* 172 */
|
scheme_rt_indexed_string, /* 173 */
|
||||||
scheme_rt_output_file, /* 173 */
|
scheme_rt_output_file, /* 174 */
|
||||||
scheme_rt_load_handler_data, /* 174 */
|
scheme_rt_load_handler_data, /* 175 */
|
||||||
scheme_rt_pipe, /* 175 */
|
scheme_rt_pipe, /* 176 */
|
||||||
scheme_rt_beos_process, /* 176 */
|
scheme_rt_beos_process, /* 177 */
|
||||||
scheme_rt_system_child, /* 177 */
|
scheme_rt_system_child, /* 178 */
|
||||||
scheme_rt_tcp, /* 178 */
|
scheme_rt_tcp, /* 179 */
|
||||||
scheme_rt_write_data, /* 179 */
|
scheme_rt_write_data, /* 180 */
|
||||||
scheme_rt_tcp_select_info, /* 180 */
|
scheme_rt_tcp_select_info, /* 181 */
|
||||||
scheme_rt_namespace_option, /* 181 */
|
scheme_rt_namespace_option, /* 182 */
|
||||||
scheme_rt_param_data, /* 182 */
|
scheme_rt_param_data, /* 183 */
|
||||||
scheme_rt_will, /* 183 */
|
scheme_rt_will, /* 184 */
|
||||||
scheme_rt_will_registration, /* 184 */
|
scheme_rt_will_registration, /* 185 */
|
||||||
scheme_rt_struct_proc_info, /* 185 */
|
scheme_rt_struct_proc_info, /* 186 */
|
||||||
scheme_rt_linker_name, /* 186 */
|
scheme_rt_linker_name, /* 187 */
|
||||||
scheme_rt_param_map, /* 187 */
|
scheme_rt_param_map, /* 188 */
|
||||||
scheme_rt_finalization, /* 188 */
|
scheme_rt_finalization, /* 189 */
|
||||||
scheme_rt_finalizations, /* 189 */
|
scheme_rt_finalizations, /* 190 */
|
||||||
scheme_rt_cpp_object, /* 190 */
|
scheme_rt_cpp_object, /* 191 */
|
||||||
scheme_rt_cpp_array_object, /* 191 */
|
scheme_rt_cpp_array_object, /* 192 */
|
||||||
scheme_rt_stack_object, /* 192 */
|
scheme_rt_stack_object, /* 193 */
|
||||||
scheme_rt_preallocated_object, /* 193 */
|
scheme_rt_preallocated_object, /* 194 */
|
||||||
scheme_thread_hop_type, /* 194 */
|
scheme_thread_hop_type, /* 195 */
|
||||||
scheme_rt_srcloc, /* 195 */
|
scheme_rt_srcloc, /* 196 */
|
||||||
scheme_rt_evt, /* 196 */
|
scheme_rt_evt, /* 197 */
|
||||||
scheme_rt_syncing, /* 197 */
|
scheme_rt_syncing, /* 198 */
|
||||||
scheme_rt_comp_prefix, /* 198 */
|
scheme_rt_comp_prefix, /* 199 */
|
||||||
scheme_rt_user_input, /* 199 */
|
scheme_rt_user_input, /* 200 */
|
||||||
scheme_rt_user_output, /* 200 */
|
scheme_rt_user_output, /* 201 */
|
||||||
scheme_rt_compact_port, /* 201 */
|
scheme_rt_compact_port, /* 202 */
|
||||||
scheme_rt_read_special_dw, /* 202 */
|
scheme_rt_read_special_dw, /* 203 */
|
||||||
scheme_rt_regwork, /* 203 */
|
scheme_rt_regwork, /* 204 */
|
||||||
scheme_rt_buf_holder, /* 204 */
|
scheme_rt_buf_holder, /* 205 */
|
||||||
scheme_rt_parameterization, /* 205 */
|
scheme_rt_parameterization, /* 206 */
|
||||||
scheme_rt_print_params, /* 206 */
|
scheme_rt_print_params, /* 207 */
|
||||||
scheme_rt_read_params, /* 207 */
|
scheme_rt_read_params, /* 208 */
|
||||||
scheme_rt_native_code, /* 208 */
|
scheme_rt_native_code, /* 209 */
|
||||||
scheme_rt_native_code_plus_case, /* 209 */
|
scheme_rt_native_code_plus_case, /* 210 */
|
||||||
scheme_rt_jitter_data, /* 210 */
|
scheme_rt_jitter_data, /* 211 */
|
||||||
scheme_rt_module_exports, /* 211 */
|
scheme_rt_module_exports, /* 212 */
|
||||||
scheme_rt_delay_load_info, /* 212 */
|
scheme_rt_delay_load_info, /* 213 */
|
||||||
scheme_rt_marshal_info, /* 213 */
|
scheme_rt_marshal_info, /* 214 */
|
||||||
scheme_rt_unmarshal_info, /* 214 */
|
scheme_rt_unmarshal_info, /* 215 */
|
||||||
scheme_rt_runstack, /* 215 */
|
scheme_rt_runstack, /* 216 */
|
||||||
scheme_rt_sfs_info, /* 216 */
|
scheme_rt_sfs_info, /* 217 */
|
||||||
scheme_rt_validate_clearing, /* 217 */
|
scheme_rt_validate_clearing, /* 218 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_scheme_last_type_
|
_scheme_last_type_
|
||||||
|
|
|
@ -2244,6 +2244,15 @@ static Scheme_Thread *make_thread(Scheme_Config *config,
|
||||||
|
|
||||||
process->nester = process->nestee = NULL;
|
process->nester = process->nestee = NULL;
|
||||||
|
|
||||||
|
process->mbox_first = NULL;
|
||||||
|
process->mbox_last = NULL;
|
||||||
|
process->mbox_sema = NULL;
|
||||||
|
|
||||||
|
process->mref = NULL;
|
||||||
|
process->extra_mrefs = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* A thread points to a lot of stuff, so it's bad to put a finalization
|
/* A thread points to a lot of stuff, so it's bad to put a finalization
|
||||||
on it, which is what registering with a custodian does. Instead, we
|
on it, which is what registering with a custodian does. Instead, we
|
||||||
register a weak indirection with the custodian. That way, the thread
|
register a weak indirection with the custodian. That way, the thread
|
||||||
|
@ -2586,6 +2595,10 @@ static void thread_is_dead(Scheme_Thread *r)
|
||||||
r->error_buf = NULL;
|
r->error_buf = NULL;
|
||||||
|
|
||||||
r->spare_runstack = NULL;
|
r->spare_runstack = NULL;
|
||||||
|
|
||||||
|
r->mbox_first = NULL;
|
||||||
|
r->mbox_last = NULL;
|
||||||
|
r->mbox_sema = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_thread(Scheme_Thread *r)
|
static void remove_thread(Scheme_Thread *r)
|
||||||
|
|
|
@ -236,6 +236,7 @@ scheme_init_type (Scheme_Env *env)
|
||||||
set_name(scheme_write_evt_type, "<write-evt>");
|
set_name(scheme_write_evt_type, "<write-evt>");
|
||||||
set_name(scheme_always_evt_type, "<always-evt>");
|
set_name(scheme_always_evt_type, "<always-evt>");
|
||||||
set_name(scheme_never_evt_type, "<never-evt>");
|
set_name(scheme_never_evt_type, "<never-evt>");
|
||||||
|
set_name(scheme_thread_recv_evt_type, "<thread-receive-evt>");
|
||||||
|
|
||||||
set_name(scheme_thread_resume_type, "<thread-resume-evt>");
|
set_name(scheme_thread_resume_type, "<thread-resume-evt>");
|
||||||
set_name(scheme_thread_suspend_type, "<thread-suspend-evt>");
|
set_name(scheme_thread_suspend_type, "<thread-suspend-evt>");
|
||||||
|
@ -585,6 +586,7 @@ void scheme_register_traversers(void)
|
||||||
GC_REG_TRAV(scheme_nack_evt_type, twoptr_obj);
|
GC_REG_TRAV(scheme_nack_evt_type, twoptr_obj);
|
||||||
GC_REG_TRAV(scheme_always_evt_type, char_obj);
|
GC_REG_TRAV(scheme_always_evt_type, char_obj);
|
||||||
GC_REG_TRAV(scheme_never_evt_type, char_obj);
|
GC_REG_TRAV(scheme_never_evt_type, char_obj);
|
||||||
|
GC_REG_TRAV(scheme_thread_recv_evt_type, char_obj);
|
||||||
|
|
||||||
GC_REG_TRAV(scheme_inspector_type, mark_inspector);
|
GC_REG_TRAV(scheme_inspector_type, mark_inspector);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user