+scm_spawn_thread (scm_t_catch_body body, void *body_data,
+ scm_t_catch_handler handler, void *handler_data)
+{
+ SCM thread;
+ coop_t *t;
+ SCM root, old_winds;
+ c_launch_data *data = (c_launch_data *) scm_malloc (sizeof (*data));
+
+ /* Unwind wind chain. */
+ old_winds = scm_dynwinds;
+ scm_dowinds (SCM_EOL, scm_ilength (scm_root->dynwinds));
+
+ /* Allocate thread locals. */
+ root = scm_make_root (scm_root->handle);
+ /* Make thread. */
+ thread = scm_cell (scm_tc16_thread, 0);
+ SCM_DEFER_INTS;
+
+ data->u.thread = thread;
+ data->body = body;
+ data->body_data = body_data;
+ data->handler = handler;
+ data->handler_data = handler_data;
+
+ t = coop_create (c_launch_thread, (void *) data);
+
+ t->data = SCM_ROOT_STATE (root);
+ SCM_SET_CELL_WORD_1 (thread, (scm_t_bits) t);
+ scm_thread_count++;
+ /* Note that the following statement also could cause coop_yield.*/
+ SCM_ALLOW_INTS;
+
+ /* We're now ready for the thread to begin. */
+ coop_yield();
+
+ /* Return to old dynamic context. */
+ scm_dowinds (old_winds, - scm_ilength (old_winds));
+
+ return thread;
+}
+