リビジョン | b1c00a16f770a44b9b011f94cf897a16adef6aaa (tree) |
---|---|
日時 | 2018-03-12 13:41:53 |
作者 | Agustina Arzille <avarzille@rise...> |
コミッター | Agustina Arzille |
Improvements in stream interface and GC
@@ -2462,7 +2462,7 @@ | ||
2462 | 2462 | if ((n = *ip++) > 0) |
2463 | 2463 | { |
2464 | 2464 | list_fct (interp, &stack[sp - n], n); |
2465 | - interp->popn (n); | |
2465 | + sp -= n; | |
2466 | 2466 | U_PUSH (retval); |
2467 | 2467 | } |
2468 | 2468 | else |
@@ -2678,6 +2678,7 @@ | ||
2678 | 2678 | sx = fetch32 (ip); |
2679 | 2679 | nargs = process_keys (interp, retval, ix, |
2680 | 2680 | n, abs (sx) - ix - n, bp, nargs, sx < 0); |
2681 | + lastf = interp->cur_frame; | |
2681 | 2682 | NEXT_OP; |
2682 | 2683 | |
2683 | 2684 | OP_(MKCONT): |
@@ -1559,7 +1559,9 @@ | ||
1559 | 1559 | if (!ptr) |
1560 | 1560 | qp_return (str); |
1561 | 1561 | |
1562 | - stream *ns = strstream (interp, alloc_str (interp, 0), STRM_WRITE); | |
1562 | + stream *ns = strstream (interp, | |
1563 | + alloc_str (interp, 0), STRM_WRITE | STRM_NOLOCK); | |
1564 | + | |
1563 | 1565 | ns->write (interp, start, ptr - start); |
1564 | 1566 | |
1565 | 1567 | valref outs (interp, ns->as_obj ()), args (interp, NIL); |
@@ -1649,8 +1651,8 @@ | ||
1649 | 1651 | bool init_io (interpreter *interp) |
1650 | 1652 | { |
1651 | 1653 | static native_function backquote_macro; |
1652 | - auto nfp = (native_function *)ensure_mask (&backquote_macro, TYPE_SHIFT); | |
1653 | - native_function::add_macro (interp, "backquote", backquote_fct, nfp); | |
1654 | + native_function::add_macro (interp, "backquote", backquote_fct, | |
1655 | + (native_function *)ensure_mask (&backquote_macro, TYPE_SHIFT)); | |
1654 | 1656 | |
1655 | 1657 | return (true); |
1656 | 1658 | } |
@@ -358,7 +358,7 @@ | ||
358 | 358 | this->sweep_young_varobjs (); |
359 | 359 | } |
360 | 360 | |
361 | - void suspend_all (interpreter *interp); | |
361 | + void suspend_one (interpreter *interp, interpreter *target); | |
362 | 362 | void resume_all (interpreter *interp); |
363 | 363 | }; |
364 | 364 |
@@ -682,33 +682,28 @@ | ||
682 | 682 | # define RESUME_THR(id) ResumeThread (id) |
683 | 683 | #endif |
684 | 684 | |
685 | -void gcinfo::suspend_all (interpreter *interp) | |
685 | +void gcinfo::suspend_one (interpreter *interp, interpreter *target) | |
686 | 686 | { |
687 | - this->event.reset (); | |
688 | - | |
689 | - for (dlist::iterator it (&all_threads); it.valid (); it.adv ()) | |
690 | - { | |
691 | - interpreter *target = ((thread *)it.getp ())->interp; | |
692 | - if (target == interp) | |
693 | - continue; | |
687 | + if (target == interp) | |
688 | + return; | |
694 | 689 | |
695 | - /* Save the state, and if the thread is not blocking, | |
696 | - * suspend it asynchronously. Otherwise, the thread will | |
697 | - * have to wait on the GC event once it's done blocking. */ | |
698 | - target->lock_remote (interp); | |
699 | - target->saved_state = target->state; | |
700 | - target->state = INTERP_SUSPENDED; | |
701 | - target->sync_ev() = &this->event; | |
690 | + /* Save the state, and if the thread is not blocking, | |
691 | + * suspend it asynchronously. Otherwise, the thread will | |
692 | + * have to wait on the GC event once it's done blocking. */ | |
702 | 693 | |
703 | - if (target->saved_state == INTERP_RUNNING) | |
704 | - { | |
705 | - suspend_thr (as_thread(target->thread)->osid); | |
706 | - // Wait for thread to acknowledge signal. | |
707 | - this->event.post_send (); | |
708 | - } | |
694 | + target->lock_remote (interp); | |
695 | + target->saved_state = target->state; | |
696 | + target->state = INTERP_SUSPENDED; | |
697 | + target->sync_ev() = &this->event; | |
709 | 698 | |
710 | - target->unlock (); | |
699 | + if (target->saved_state == INTERP_RUNNING) | |
700 | + { | |
701 | + suspend_thr (as_thread(target->thread)->osid); | |
702 | + // Wait for thread to acknowledge signal. | |
703 | + this->event.post_send (); | |
711 | 704 | } |
705 | + | |
706 | + target->unlock (); | |
712 | 707 | } |
713 | 708 | |
714 | 709 | void gcinfo::resume_all (interpreter *interp) |
@@ -954,26 +949,25 @@ | ||
954 | 949 | sigaction (SIG_SUSPEND, &sa, &old); |
955 | 950 | #endif |
956 | 951 | |
957 | - this->suspend_all (interp); | |
958 | - | |
959 | - // The world is stopped. Time for the mark phase. | |
960 | - atomic_mfence_acq (); // Synchronize with every other thread. | |
952 | + this->event.reset (); | |
961 | 953 | |
962 | 954 | for (dlist::iterator it (&all_threads); it.valid (); it.adv ()) |
963 | 955 | { |
964 | 956 | thread *thrp = (thread *)it.getp (); |
965 | 957 | interpreter *ip2 = thrp->interp; |
966 | 958 | |
959 | + this->suspend_one (interp, ip2); | |
960 | + | |
967 | 961 | // Mark the interpreter's registers. |
968 | - gc_mark (ip2->thread, mask); | |
969 | - gc_mark (ip2->lasterr, mask); | |
970 | - gc_mark (ip2->retval, mask); | |
971 | - gc_mark (ip2->alval, mask); | |
972 | - gc_mark (ip2->aux, mask); | |
962 | + this->mark (ip2->thread, mask); | |
963 | + this->mark (ip2->lasterr, mask); | |
964 | + this->mark (ip2->retval, mask); | |
965 | + this->mark (ip2->alval, mask); | |
966 | + this->mark (ip2->aux, mask); | |
973 | 967 | |
974 | 968 | // Mark the interpreter's stack. |
975 | 969 | for (uint32_t i = 0; i < ip2->sp; ++i) |
976 | - gc_mark (ip2->stack[i], mask); | |
970 | + this->mark (ip2->stack[i], mask); | |
977 | 971 | |
978 | 972 | // Mark the thread's locks. |
979 | 973 | for (dlist::iterator lk (&thrp->locks); lk.valid (); lk.adv ()) |
@@ -981,7 +975,7 @@ | ||
981 | 975 | |
982 | 976 | for (valref_base *vp = ip2->values.next; |
983 | 977 | vp != &ip2->values; vp = vp->next) |
984 | - gc_mark (vp->value, mask); | |
978 | + this->mark (vp->value, mask); | |
985 | 979 | |
986 | 980 | if (full) |
987 | 981 | ip2->mmgr->clear_bitmaps (this->conses_per_page); |
@@ -30,7 +30,7 @@ | ||
30 | 30 | sigint_fct.flags = native_function::native_flag; |
31 | 31 | sigint_fct.type = typecode::FCT; |
32 | 32 | sigint_fct.fct = sigint_handler; |
33 | - sigint_fct.name = "sigint_handler"; | |
33 | + sigint_fct.name = "sigint-handler"; | |
34 | 34 | signal_handlers[SIGINT - 1] = sigint_fct.as_obj (); |
35 | 35 | |
36 | 36 | struct sigaction sa; |
@@ -18,6 +18,12 @@ | ||
18 | 18 | return (false); |
19 | 19 | } |
20 | 20 | |
21 | +static void | |
22 | +fini_stream (void *self) | |
23 | +{ | |
24 | + ((stream *)self)->close (interpreter::self ()); | |
25 | +} | |
26 | + | |
21 | 27 | spos spos::decode (object obj) |
22 | 28 | { |
23 | 29 | spos ret (0); |
@@ -68,24 +74,20 @@ | ||
68 | 74 | char *wrbuf = ret->rdbuf.start + ((mode & STRM_BID) ? bufsiz : 0); |
69 | 75 | ret->wrbuf.init (wrbuf, bufsiz); |
70 | 76 | |
71 | - interp->push (ret->bvec); | |
72 | - ret->ilock = alloc_lock (interp, true); | |
77 | + valref bv (interp, ret->bvec); | |
78 | + ret->ilock = (mode & STRM_NOLOCK) ? UNBOUND : alloc_lock (interp, true); | |
73 | 79 | ret->flags = mode; |
74 | 80 | |
75 | - if (ret->flags & STRM_APP) | |
81 | + if (!(ret->flags & STRM_APP)) | |
82 | + ret->pos = intobj (0); | |
83 | + else if (!ret->xseek (interp, spos (0), SEEK_END)) | |
76 | 84 | { |
77 | - valref ref (interp, ret->bvec); | |
78 | - if (!ret->xseek (interp, spos (0), SEEK_END)) | |
79 | - { | |
80 | - xfree (ret); | |
81 | - ret = nullptr; | |
82 | - } | |
85 | + xfree (ret); | |
86 | + return (nullptr); | |
83 | 87 | } |
84 | - else | |
85 | - ret->pos = intobj (0); | |
86 | 88 | |
89 | + ret->fini = fini_stream; | |
87 | 90 | interp->alval = ret->as_obj (); |
88 | - interp->popn (); | |
89 | 91 | gcregister (interp, ret); |
90 | 92 | return (ret); |
91 | 93 | } |
@@ -31,7 +31,7 @@ | ||
31 | 31 | static spos decode (object obj); |
32 | 32 | }; |
33 | 33 | |
34 | -/* Stream flags. */ | |
34 | +// Stream flags. | |
35 | 35 | enum |
36 | 36 | { |
37 | 37 | STRM_BUILTIN = 1 << 0, |
@@ -48,10 +48,11 @@ | ||
48 | 48 | STRM_UTF8 = 1 << 10, |
49 | 49 | STRM_OFFSET = 1 << 11, |
50 | 50 | STRM_CLOSED = 1 << 12, |
51 | - STRM_BID = 1 << 13 | |
51 | + STRM_BID = 1 << 13, | |
52 | + STRM_NOLOCK = 1 << 14 | |
52 | 53 | }; |
53 | 54 | |
54 | -class stream : public varobj | |
55 | +class stream : public finobj | |
55 | 56 | { |
56 | 57 | public: |
57 | 58 | class buffer |