From iainduncanlists at gmail.com Thu Nov 19 10:28:55 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Thu, 19 Nov 2020 10:28:55 -0800 Subject: [CM] Anyone using S7 on microcontrollers? Message-ID: Hi folks, wondering if anyone is using S7 on MCUs. (Adruinos, Arm, teensies, whatever!) thanks! iain -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris.actondev at gmail.com Thu Nov 19 11:23:29 2020 From: chris.actondev at gmail.com (Christos Vagias) Date: Thu, 19 Nov 2020 20:23:29 +0100 Subject: [CM] Anyone using S7 on microcontrollers? In-Reply-To: References: Message-ID: Hi Iain, I'd also like to know, and have thought about this :) The problem I'm seeing here is the file size of the program (-O0 seems to produce a 3mb binary and -Os 5mb) and RAM usage (if I remember correctly 15-30mb usage of ram). Concerning RAM though I remember somewhere in the source code I've seen some comments about the initial memory allocation which could be lower. Christos On Thu, 19 Nov 2020 at 19:31, Iain Duncan wrote: > Hi folks, wondering if anyone is using S7 on MCUs. (Adruinos, Arm, > teensies, whatever!) > > thanks! > iain > _______________________________________________ > Cmdist mailing list > Cmdist at ccrma.stanford.edu > https://cm-mail.stanford.edu/mailman/listinfo/cmdist > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bil at ccrma.Stanford.EDU Thu Nov 19 14:19:21 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Thu, 19 Nov 2020 14:19:21 -0800 Subject: [CM] =?utf-8?q?Anyone_using_S7_on_microcontrollers=3F?= In-Reply-To: References: Message-ID: I tried this: gcc s7.c -o repl -DWITH_MAIN -I. -O2 -g -ldl -lm -Wl,-export-dynamic -DINITIAL_HEAP_SIZE=6400 -DSYMBOL_TABLE_SIZE=4373 and it claims the repl runtime size is 2.4 MBytes, but I'm not sure I believe it. The heap size needs to be a multiple of 32, and I always use a prime for the symbol table size, but I can't remember why. Someone was using s7 with the blackfin microprocessor. From bil at ccrma.Stanford.EDU Thu Nov 19 14:24:56 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Thu, 19 Nov 2020 14:24:56 -0800 Subject: [CM] =?utf-8?q?Anyone_using_S7_on_microcontrollers=3F?= In-Reply-To: References: Message-ID: top says it's 4 MBytes "resident" size. From deeteeoh1138 at gmail.com Sat Nov 21 11:15:25 2020 From: deeteeoh1138 at gmail.com (David O'Toole) Date: Sat, 21 Nov 2020 14:15:25 -0500 Subject: [CM] 20.8 -- unbound variable "__func__" Message-ID: Hello everyone! I'm back hacking on Scheme Mosaic. The following code no longer works, what is the correct thing to do? ;;; Assertion facility from Snd docs. (define *debugging* #t) (define-expansion (assert assertion) (if *debugging* `(unless ,assertion (format *stderr* "~A: ~A failed~%" __func__ ',assertion)) (values))) -------------- next part -------------- An HTML attachment was scrubbed... URL: From bil at ccrma.Stanford.EDU Sat Nov 21 12:32:22 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Sat, 21 Nov 2020 12:32:22 -0800 Subject: [CM] =?utf-8?b?MjAuOCAtLSB1bmJvdW5kIHZhcmlhYmxlICJfX2Z1bmNfXyI=?= In-Reply-To: References: Message-ID: <91f2e5c976b1255652f2dae98ccebd99@ccrma.stanford.edu> Use (*function*) in place of __func__ (see s7.html). From bil at ccrma.Stanford.EDU Sun Nov 22 03:15:42 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Sun, 22 Nov 2020 03:15:42 -0800 Subject: [CM] Snd 20.9 Message-ID: <1f20204a18e4d57c4b1ae388c0238199@ccrma.stanford.edu> Snd 20.9: Snd: clm.rb and snd-test.rb updated for Ruby 3.0, thanks to Mike. s7: added s7_load_c_string and s7_load_c_string_with_environment tools/tmock.scm, tnum.scm, concordance.scm notcurses_s7.c assumes version 2 of notcurses; for version 1, pass -DNOTCURSES_1=1. checked: Fedora 33, Ubuntu 20.10, sbcl 2.0.10 Thanks!: Woody Douglass, Christos Vagias, Mike Scholz, IOhannes m zmoelnig, David Runge From iainduncanlists at gmail.com Sun Nov 22 09:18:18 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Sun, 22 Nov 2020 09:18:18 -0800 Subject: [CM] some questions re S7, real-time use, and memory allocation Message-ID: Hi folks, I tried hunting through s7.html for answers, so if I missed the answer (due to not understanding) my apologies. In my next release of scheme for max, I'm allowing one to specify which of the two max threads an S7 object lives in, with all input to the object promoted or deferred accordingly. This allows using S7 in timing critical situations. It also means S7 can be running in the same thread as DSP. I'm also working on a Pd port, which has only one thread, so S7 will be in the audio thread. I have read numerous articles on real-time audio coding that say "don't malloc in the audio thread", because you never know when this could lead to an operating system level disk swap. I've read various strategies to avoid it, including pre-allocating pools of whatever you might allocate, or pre-allocating a big chunk of memory so you allocate from memory that is guaranteed not to need to swap. My questions: - is there a way to do memory pre-allocation for S7 so that I can guarantee that creating new objects isn't going to lead to OS level swapping? as in, have S7 only allocate from a memory buffer I've already set aside? (RAM is cheap, underruns are bad..) - any thoughts about why you might or might not do this? - any thoughts on how hard this would be to implement if it has not been done? - are there any alternative approaches I should look into? - are there tools I could use to see how much is going on? Any general input on this issue and how others deal with it or not would be much appreciated! iain -------------- next part -------------- An HTML attachment was scrubbed... URL: From bil at ccrma.Stanford.EDU Sun Nov 22 15:05:25 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Sun, 22 Nov 2020 15:05:25 -0800 Subject: [CM] some questions re S7, real-time use, and memory allocation In-Reply-To: References: Message-ID: s7 calls malloc very infrequently; it has its own malloc (mallocate and friends), calling malloc only to get large blocks that it handles after that. More likely to be a problem is garbage collection. I haven't tried to use s7 in real-time, but I would expect it to be a struggle. From iainduncanlists at gmail.com Sun Nov 22 15:21:21 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Sun, 22 Nov 2020 15:21:21 -0800 Subject: [CM] some questions re S7, real-time use, and memory allocation In-Reply-To: References: Message-ID: Thanks Bill, that sounds promising on the malloc front then. I'll take a look at the code. What I'm imagining right now is two s4m objects, one in high priority thread and one in the low, so that the majority of stuff is done in the low and the high is only used for lightweight timing critical tasks. If this doesn't pan out, I can always do the high priority thread stuff in Max or C instead, but it would be nice to be able to use S7 if possible. I *think* I should be able to keep the stuff in the high priority thread minimal enough to keep a handle on the garbage collection side, but dealing first hand with a garbage collector is new to me. (As in, I've done some soft realtime in C, and I've done work in GC'd languages, but none of that was in situations where I cared when the GC ran). If you (or anyone else) has pointers on how to learn more about that sort of thing, or how to watch when the GC runs, I'm all ears. thanks iain On Sun, Nov 22, 2020 at 3:05 PM wrote: > s7 calls malloc very infrequently; it has its own > malloc (mallocate and friends), calling malloc > only to get large blocks that it handles after that. > More likely to be a problem is garbage collection. > I haven't tried to use s7 in real-time, but I > would expect it to be a struggle. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From iainduncanlists at gmail.com Sun Nov 22 15:27:19 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Sun, 22 Nov 2020 15:27:19 -0800 Subject: [CM] some questions re S7, real-time use, and memory allocation In-Reply-To: References: Message-ID: Another thought, my use case is mostly to make sequencers and algo composition aids, not to render real time audio, so while timing is important, I'm not going to be running a lot of code in the RT thread. It will likely run once per minimum time unit, ie maybe 24 parts per quarter, or something. Is there any reason I could not just have that function (clocked from max) turn off the GC, do it's work, and then turn the GC back on to clean up at the end of every tick? is that crazy talk? Christos, I think you are using S7 in the audio thread in your VST thing right? How are you dealing with that issue, or has it not bitten you? iain On Sun, Nov 22, 2020 at 3:21 PM Iain Duncan wrote: > Thanks Bill, that sounds promising on the malloc front then. I'll take a > look at the code. > > What I'm imagining right now is two s4m objects, one in high priority > thread and one in the low, so that the majority of stuff is done in the low > and the high is only used for lightweight timing critical tasks. If this > doesn't pan out, I can always do the high priority thread stuff in Max or C > instead, but it would be nice to be able to use S7 if possible. I *think* I > should be able to keep the stuff in the high priority thread minimal enough > to keep a handle on the garbage collection side, but dealing first hand > with a garbage collector is new to me. (As in, I've done some soft > realtime in C, and I've done work in GC'd languages, but none of that was > in situations where I cared when the GC ran). If you (or anyone else) has > pointers on how to learn more about that sort of thing, or how to watch > when the GC runs, I'm all ears. > > thanks > iain > > On Sun, Nov 22, 2020 at 3:05 PM wrote: > >> s7 calls malloc very infrequently; it has its own >> malloc (mallocate and friends), calling malloc >> only to get large blocks that it handles after that. >> More likely to be a problem is garbage collection. >> I haven't tried to use s7 in real-time, but I >> would expect it to be a struggle. >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From iainduncanlists at gmail.com Sun Nov 22 16:36:57 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Sun, 22 Nov 2020 16:36:57 -0800 Subject: [CM] S7s GC Message-ID: Hi friends, learning about garbage collection is new to me, if anyone can share some tips on what I should be looking into for S7's memory management and garbage collection that would be lovely. IE what kind of GC is it? or just good resources on learning this sort of stuff. thanks! iain -------------- next part -------------- An HTML attachment was scrubbed... URL: From iainduncanlists at gmail.com Sun Nov 22 18:32:25 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Sun, 22 Nov 2020 18:32:25 -0800 Subject: [CM] Anyone using S7 on microcontrollers? In-Reply-To: References: Message-ID: Well that should be totally doable then! I will have to give this a crack over the holidays. thanks Bill. On Thu, Nov 19, 2020 at 2:27 PM wrote: > top says it's 4 MBytes "resident" size. > > > _______________________________________________ > Cmdist mailing list > Cmdist at ccrma.stanford.edu > https://cm-mail.stanford.edu/mailman/listinfo/cmdist > -------------- next part -------------- An HTML attachment was scrubbed... URL: From k.s.matheussen at gmail.com Mon Nov 23 03:29:12 2020 From: k.s.matheussen at gmail.com (Kjetil Matheussen) Date: Mon, 23 Nov 2020 12:29:12 +0100 Subject: [CM] some questions re S7, real-time use, and memory allocation In-Reply-To: References: Message-ID: You might also want to consider doing all scheme processing in a separate thread. That's the way snd did it when it was possible to compile it as a Pd external: https://github.com/kmatheussen/snd-rt/blob/master/snd_pd_external.c You might get a little bit skewed timing now and then this way, but that might not be important. From k.s.matheussen at gmail.com Mon Nov 23 03:39:50 2020 From: k.s.matheussen at gmail.com (Kjetil Matheussen) Date: Mon, 23 Nov 2020 12:39:50 +0100 Subject: [CM] S7s GC In-Reply-To: References: Message-ID: S7's has a tracing garbage collector, meaning that it has a set of "roots" which it traces all live objects from. When all live objects are found, everything else can be freed. You might want to find this work interesting: http://users.notam02.no/~kjetism/rollendurchmesserzeitsammler/ although I'm not sure it would work very well as a replacement for s7's garbage collector. It might work to replace it with BDW-GC running in incremental mode though, although I wouldn't bet on it. On Mon, Nov 23, 2020 at 1:42 AM Iain Duncan wrote: > > Hi friends, learning about garbage collection is new to me, if anyone can share some tips on what I should be looking into for S7's memory management and garbage collection that would be lovely. IE what kind of GC is it? or just good resources on learning this sort of stuff. > > thanks! > iain > _______________________________________________ > Cmdist mailing list > Cmdist at ccrma.stanford.edu > https://cm-mail.stanford.edu/mailman/listinfo/cmdist From chris.actondev at gmail.com Mon Nov 23 03:41:49 2020 From: chris.actondev at gmail.com (Christos Vagias) Date: Mon, 23 Nov 2020 12:41:49 +0100 Subject: [CM] some questions re S7, real-time use, and memory allocation In-Reply-To: References: Message-ID: Hey Iain, I'm indeed using s7 in the audio thread (and another instance in separate thread for the GUI) but I've just used simple midi input to make some visualizations, nothing in the area of audio generation/output so didn't have any problems (yet). Also, didn't extensively test it with real time audio in mind, just wanted to get it working. And it'll be quite some time until I get to work with it again I'm afraid. Regarding your question of turning off the GC, there's a way of doing it! I think it's the (gc) function which accepts a boolean argument (to turn on or off) or none to just run the GC. On Mon, 23 Nov 2020 at 00:27, Iain Duncan wrote: > Another thought, my use case is mostly to make sequencers and algo > composition aids, not to render real time audio, so while timing is > important, I'm not going to be running a lot of code in the RT thread. It > will likely run once per minimum time unit, ie maybe 24 parts per quarter, > or something. Is there any reason I could not just have that function > (clocked from max) turn off the GC, do it's work, and then turn the GC back > on to clean up at the end of every tick? is that crazy talk? > > Christos, I think you are using S7 in the audio thread in your VST thing > right? How are you dealing with that issue, or has it not bitten you? > > iain > > On Sun, Nov 22, 2020 at 3:21 PM Iain Duncan > wrote: > >> Thanks Bill, that sounds promising on the malloc front then. I'll take a >> look at the code. >> >> What I'm imagining right now is two s4m objects, one in high priority >> thread and one in the low, so that the majority of stuff is done in the low >> and the high is only used for lightweight timing critical tasks. If this >> doesn't pan out, I can always do the high priority thread stuff in Max or C >> instead, but it would be nice to be able to use S7 if possible. I *think* I >> should be able to keep the stuff in the high priority thread minimal enough >> to keep a handle on the garbage collection side, but dealing first hand >> with a garbage collector is new to me. (As in, I've done some soft >> realtime in C, and I've done work in GC'd languages, but none of that was >> in situations where I cared when the GC ran). If you (or anyone else) has >> pointers on how to learn more about that sort of thing, or how to watch >> when the GC runs, I'm all ears. >> >> thanks >> iain >> >> On Sun, Nov 22, 2020 at 3:05 PM wrote: >> >>> s7 calls malloc very infrequently; it has its own >>> malloc (mallocate and friends), calling malloc >>> only to get large blocks that it handles after that. >>> More likely to be a problem is garbage collection. >>> I haven't tried to use s7 in real-time, but I >>> would expect it to be a struggle. >>> >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: From bil at ccrma.Stanford.EDU Mon Nov 23 05:50:34 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Mon, 23 Nov 2020 05:50:34 -0800 Subject: [CM] S7s GC In-Reply-To: References: Message-ID: As Kjetil says, it's a "tracing" GC (not based on refcounts which I found a nightmare for the FFI user); it has two generations, one immortal (never GC'd, not in the heap), and the mortals. It is concurrent in a small sense -- when s7 knows some cell is no longer needed, it immediately frees it, rather than waiting for the GC to be triggered. You can play with gc triggers and so on -- see the various gc related fields in *s7*. The problem with this in real-time is that you don't know when the GC will pause the s7 interpreter and do its thing; the gc call usually is measured in milliseconds (set the gc-stats *s7* field to see it being called, and how long it took), but that's a long time in real-time audio work. You can turn off the gc in time-critical sections (s7_gc_on from C, or the gc function in scheme), but if the heap fills up, s7 has to stop and get more space. The alternative is a segfault. So don't leave it off for very long! Also you can't just call the gc yourself at any time -- someday I'll try to fix this, but for now, try to call it only when nothing else is being evaluated). From bil at ccrma.Stanford.EDU Mon Nov 23 05:56:55 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Mon, 23 Nov 2020 05:56:55 -0800 Subject: [CM] S7s GC In-Reply-To: References: Message-ID: I forgot to say that I tried using separate threads for the gc (it is a natural for this in that the most compute-time expensive part is just spinning through the heap -- it can easily be split into N threads). But I got no speed up overall from this -- there's a brief comment in s7.c about it ca line 7079. From iainduncanlists at gmail.com Mon Nov 23 06:44:53 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Mon, 23 Nov 2020 06:44:53 -0800 Subject: [CM] S7s GC In-Reply-To: References: Message-ID: Thanks very much Bill and Kjetil. Sounds like there is a lot to learn here. The thing that is confusing me right now is why it hasn't been a problem so far in my timing tests of scheduling. Hopefully you don't mind another barrage of questions. Some background, basically I have two kinds of work going on: timing critical (notes and control events playing) and general i/o that is not critical (user moving dials, updating sequences, what have you). Right now I'm trying to make sure there are good options for users to pick their tradeoffs. Bizarrely, i've not noticed any delays from the GC running. I'm wondering if this is because the delay/schedule code works by having the max scheduler trigger it and that the GC never runs between wake up time and completion of those functions (which are pretty light). I think for my purposes, sub 5ms jitter is something we can live with, though i don't seem to even be getting that so far, but nor have I pushed it. This is really "event" real time, not audio real time. I'm going to call the pass at the interpreter that is run from the scheduler the "event pass" for nomenclature's sake.. Questions: 1) So if it traces live objects, does that mean minimizing the object tree in an instance will cut down the time it takes to run the GC? and is there any advantage to certain kinds of objects? As in, does it speed up the GC pass if I'm using top level globals and simply calling set on them so that there is not much for the GC to trace? Or any other code level strategies to speed up the GC pass? 2) I could just turn off the GC for these event passes. But I'm not clear how I let it run again as Bill said it can't be manually triggered (I do think that would be super helpful if you get that itch though Bill! :-) ) Do I need to run some scheme code with the GC back on and it will just happen? I would be totally fine with allocating a big heap and deferring the pass while "deliberating leaking" for a while. I was under the impression nothing happens in S7 until C makes a call, but am I wrong there? Does the GC sometimes just do it's thing from a thread? 3) I have been confused about threading in S7. It seems to me that it works fine for me to access the same S7 interp from multiple threads, but am I just getting lucky? I cooked up the option to lock the s4m object into 1 thread because I thought that at some point I was going to get data structure corruption if I have two different max threads making calls into the same interpreter. But am I wrong there? If it's actually safe (or I can make it safe somehow) for the multiple threads to call into the GC, would it work for me turn off the GC for all events in the high thread (triggered by midi input, clocks, or scheduler callback) and then let it run from a call to the low thread? In max there is an option to make a low-priority callback too, so I could perhaps use that to get the GC to run when I want it, in the lower thread only, preserving the critical timing. Thanks everyone! iain On Mon, Nov 23, 2020 at 5:57 AM wrote: > I forgot to say that I tried using separate threads for > the gc (it is a natural for this in that the most > compute-time expensive part is just spinning through > the heap -- it can easily be split into N threads). > But I got no speed up overall from this -- there's > a brief comment in s7.c about it ca line 7079. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bil at ccrma.Stanford.EDU Mon Nov 23 07:25:52 2020 From: bil at ccrma.Stanford.EDU (bil at ccrma.Stanford.EDU) Date: Mon, 23 Nov 2020 07:25:52 -0800 Subject: [CM] S7s GC In-Reply-To: References: Message-ID: <468868e34e9c183ca7fe6972efc46479@ccrma.stanford.edu> in C: s7_gc_on(sc, false); /* blocks the GC from running, but the heap will grow if necessary */ s7_gc_on(sc, true). /* allow the GC to run, does not trigger the GC */ in Scheme: (gc #f) ; same as s7_gc_on(sc, false) (gc #t) ; turns GC on and calls the GC I could change (gc #t) to simply re-allow GC's I suppose. On the times: here I am running s7test (which creates lots of objects) with (set! (*s7* 'gc-stats) #t) /home/bil/motif-snd/ repl s7test.scm load s7test.scm gc freed 111174/128000 (free: 126037), time: 0.000683 gc freed 117417/128000 (free: 125595), time: 0.000442 gc freed 111427/128000 (free: 111491), time: 0.000632 gc freed 109546/128000 (free: 111432), time: 0.000835 gc freed 103932/128000 (free: 111446), time: 0.000549 gc freed 123825/128000 (free: 125522), time: 0.000489 gc freed 95883/128000 (free: 123736), time: 0.000485 gc freed 3015/128000 (free: 123799), time: 0.000366 gc freed 121331/128000 (free: 121395), time: 0.000806 gc freed 123449/128000 (free: 123513), time: 0.000741 gc freed 107711/128000 (free: 123489), time: 0.000832 gc freed 111976/128000 (free: 123443), time: 0.000642 gc freed 109104/128000 (free: 115881), time: 0.000687 gc freed 101924/128000 (free: 115603), time: 0.000579 gc freed 98488/128000 (free: 114473), time: 0.000575 ... So the interruption is normally less than a millisecond (this is using the default heap-size, but I don't think that matters much). The mark process is almost insignificant in the overall computation, so don't worry about object types or layouts. The only case I've seen where it matters are GC benchmarks based on millions of huge lists (mark_pair traverses each list, which can become tedious). It's possible you haven't noticed the GC because it's not being called much -- s7 goes to great lengths to avoid creating objects itself: (define (f) (do ((i 0 (+ i 1)) (sum 0)) ((= i 1000) sum) (set! sum (+ sum i)))) (gc) (set! (*s7* 'gc-stats) 7) (display (f)) (newline) (gc) ;; gc freed 102/128000 (free: 127828), time: 0.000084 Set gc-stats and run your code -- maybe you don't need to do anything. I think if you have 2 threads calling into the same s7 interpreter, you do need to be sure they don't interrupt each other. If you try to call s7_eval_c_string or something while the GC is being run from some other thread, you'll be unhappy. From iainduncanlists at gmail.com Mon Nov 23 08:17:01 2020 From: iainduncanlists at gmail.com (Iain Duncan) Date: Mon, 23 Nov 2020 08:17:01 -0800 Subject: [CM] S7s GC In-Reply-To: <468868e34e9c183ca7fe6972efc46479@ccrma.stanford.edu> References: <468868e34e9c183ca7fe6972efc46479@ccrma.stanford.edu> Message-ID: Thanks Bill, that looks very encouraging. I have to context switch over to earning a living for a couple of days, but I will dig into this later this week. I think it would be helpful to be able to turn the GC on with control of whether it is instantly triggered, from both C and Scheme, but it sounds like it should not be a problem to get it to work fine for note/control level realtime. (aka "very soft realtime"? haha). Most people running a real time DAW with softsynths are going to be expecting to run with an audio latency of 5ms or more anyway, so I think this should be possible. (Phew!) That makes sense about the threading. I need to figure out exactly how Max handles it's switches too. There may be some kind of protection there that I don't know about (not the most documented part of Max...) I sure appreciate the help fellows! iain On Mon, Nov 23, 2020 at 7:25 AM wrote: > in C: > > s7_gc_on(sc, false); /* blocks the GC from running, but the heap will > grow if necessary */ > s7_gc_on(sc, true). /* allow the GC to run, does not trigger the GC */ > > in Scheme: > (gc #f) ; same as s7_gc_on(sc, false) > (gc #t) ; turns GC on and calls the GC > > I could change (gc #t) to simply re-allow GC's I suppose. > > On the times: here I am running s7test (which creates lots of objects) > with > (set! (*s7* 'gc-stats) #t) > > /home/bil/motif-snd/ repl s7test.scm > load s7test.scm > gc freed 111174/128000 (free: 126037), time: 0.000683 > gc freed 117417/128000 (free: 125595), time: 0.000442 > gc freed 111427/128000 (free: 111491), time: 0.000632 > gc freed 109546/128000 (free: 111432), time: 0.000835 > gc freed 103932/128000 (free: 111446), time: 0.000549 > gc freed 123825/128000 (free: 125522), time: 0.000489 > gc freed 95883/128000 (free: 123736), time: 0.000485 > gc freed 3015/128000 (free: 123799), time: 0.000366 > gc freed 121331/128000 (free: 121395), time: 0.000806 > gc freed 123449/128000 (free: 123513), time: 0.000741 > gc freed 107711/128000 (free: 123489), time: 0.000832 > gc freed 111976/128000 (free: 123443), time: 0.000642 > gc freed 109104/128000 (free: 115881), time: 0.000687 > gc freed 101924/128000 (free: 115603), time: 0.000579 > gc freed 98488/128000 (free: 114473), time: 0.000575 > ... > > So the interruption is normally less than a millisecond (this is using > the default heap-size, but I don't think that matters much). The mark > process is almost insignificant in the overall computation, so don't > worry > about object types or layouts. The only case I've seen where it matters > are GC benchmarks based on millions of huge lists (mark_pair traverses > each list, which can become tedious). > > It's possible you haven't noticed the GC because it's not being > called much -- s7 goes to great lengths to avoid creating > objects itself: > > (define (f) > (do ((i 0 (+ i 1)) > (sum 0)) > ((= i 1000) sum) > (set! sum (+ sum i)))) > > (gc) > (set! (*s7* 'gc-stats) 7) > (display (f)) (newline) > (gc) > ;; gc freed 102/128000 (free: 127828), time: 0.000084 > > Set gc-stats and run your code -- maybe you don't need to do anything. > > I think if you have 2 threads calling into the same s7 interpreter, you > do need > to be sure they don't interrupt each other. If you try to call > s7_eval_c_string > or something while the GC is being run from some other thread, you'll be > unhappy. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: