beneroth changed the topic of #picolisp to: PicoLisp language | The scalpel of software development | Channel Log: https://libera.irclog.whitequark.org/picolisp | Check www.picolisp.com for more information
seninha has quit [Quit: Leaving]
seninha has joined #picolisp
seninha has quit [Ping timeout: 260 seconds]
rob_w has joined #picolisp
rob_w has quit [*.net *.split]
stux has quit [*.net *.split]
rick42 has quit [*.net *.split]
drakonis has quit [*.net *.split]
payphone has quit [*.net *.split]
z4k4ri4 has quit [*.net *.split]
mario-goulart has quit [*.net *.split]
chexum has quit [*.net *.split]
skyjuice has quit [*.net *.split]
aw- has quit [*.net *.split]
tankf33der has quit [*.net *.split]
casaca has quit [*.net *.split]
cpli has quit [*.net *.split]
DKordic has quit [*.net *.split]
beneroth has quit [*.net *.split]
viaken has quit [*.net *.split]
clacke has quit [*.net *.split]
theruran has quit [*.net *.split]
tankf33der[m] has quit [*.net *.split]
felter3 has quit [*.net *.split]
hrberg has quit [Max SendQ exceeded]
casaca has joined #picolisp
payphone has joined #picolisp
cpli has joined #picolisp
drakonis has joined #picolisp
chexum has joined #picolisp
rick42 has joined #picolisp
stux has joined #picolisp
mario-goulart has joined #picolisp
rob_w has joined #picolisp
clacke has joined #picolisp
beneroth has joined #picolisp
theruran has joined #picolisp
DKordic has joined #picolisp
viaken has joined #picolisp
z4k4ri4 has joined #picolisp
hrberg_ has joined #picolisp
hrberg_ has quit [Max SendQ exceeded]
tankf33der has joined #picolisp
aw- has joined #picolisp
felter3 has joined #picolisp
hrberg has joined #picolisp
msavoritias has joined #picolisp
<tankf33der> hi all
<tankf33der> abu[7]: here >
<tankf33der> abu[7]: here ?
<aw-> hi
<tankf33der> i run some code in the (loop ...) and memory leaking in the place i do not expect
<aw-> :O
<aw-> example?
<tankf33der> cutting lines to find the place
seninha has joined #picolisp
<tankf33der> if start test-leak1.l memory leak begins
<tankf33der> if run test-leak2.l itself in the loop memory do not leak.
<tankf33der> maybe this ok
<aw-> hmmm
<aw-> (let Ctx (% ...
<aw-> your code seems wrong
<aw-> i dont usually do (let (Ctx (something)) ...) unless i have 2 or more variables, like (let (Ctx1 A Ctx2 B) ...
<aw-> in any case, i think your Ctx isnt being passed to "free"
<aw-> i may be wrong ;)
Nistur has quit [Ping timeout: 260 seconds]
<aw-> or maybe your result specification for malloc should be N (signed 64-bit) instead of P (unsigned 64-bit) ?
<aw-> does malloc always return a value >= 0 ?
<aw-> ah, i just see from linux manpage: void *malloc(size_t size);
<aw-> and in picolisp docs: (native "lib.so" "fun" 'P) # void *fun(void);
<aw-> so i think you're OK...
<tankf33der> yeah
<aw-> tankf33der: i wonder if your "memory" leak is caused by (loop) constantly searching/opening the lib to find malloc
<aw-> tankf33der: might be stupid, but can you try the test again with (native "@" "malloc" ...) and (native "@" "free" ...
Nistur has joined #picolisp
<tankf33der> the same leak
<tankf33der> no fd leaks
<aw-> i think abu[7] needs to try, sorry!!
<beneroth> interesting case
<aw-> hey beneroth!
<beneroth> hey aw- !
<beneroth> :)
<aw-> i haven't touched (native) in so long, can't debug as quickly as before
<beneroth> compared to me, you're a native expert
<aw-> beneroth: how are you?
<beneroth> good. stressed but soon some vacation finally.
<beneroth> was also quite too hot here for my taste, but it's getting cooler since yesterday.
<aw-> ohhh, vacation is always good
<beneroth> yeah, needed!
<aw-> yes the entire northern hemisphere has been suffocating from heat lately
<beneroth> though I hope also I have some time to try some things out and code some stuff for myself
<aw-> oh you mean, vacation from work, not from computers ;)
<beneroth> yeah. well also from computer, will go traveling a bit to the north, but take a computer with me for the quiet times ;-)
<beneroth> how are you?
<aw-> cool
<aw-> i'm fine, enjoying the warm weather hahaha
<aw-> not working much, which is good
<beneroth> good! I'm happy for you :)
<tankf33der> does not leak.
<abu[7]> Hi tankf33der, aw-, beneroth!
<abu[7]> tankf33der, your code looks indeed good
<abu[7]> hmm, I tried this
<abu[7]> : (do 99999999 (%@ "free" NIL (%@ "malloc" 'P 99999)))
<abu[7]> and monitor the process with 'ps'
<abu[7]> No change in process size
<aw-> tankf33der: how do you determine it's leaking?
<tankf33der> You should run two files exactly as paste shows
<tankf33der> Load the file in the loop,
<tankf33der> If run malloc without load it does not leak
<abu[7]> ok
<aw-> yeah, so each (load) creates a new symbol?
<abu[7]> right, size increases
<abu[7]> A 'load' without malloc/free does net increase
<abu[7]> strange!
<abu[7]> The 'let' can be omitted:
<abu[7]> (%@ "free" NIL (%@ "malloc" 'P 224))
<tankf33der> right
<tankf33der> afk
rob_w has quit [Remote host closed the connection]
<abu[7]> Interesting, the 'malloc'ed size does not matter. So free() itself works.
<tankf33der> Without free it would increase faster, much faster
<abu[7]> right
<tankf33der> try (buf …
<tankf33der> and try (%@ “strdup” …
<abu[7]> buf does not malloc anything
<abu[7]> it reserves stack space
<tankf33der> ok
<abu[7]> It is also not open+close of files, because if instead of (do 99999 (load "mem.l")) I do (do 99999 (in "mem.l" (eval (read)))) it does *not* increase
<abu[7]>
<abu[7]> "mem.l" is a single line (%@ "free" NIL (%@ "malloc" 'P 99))
<abu[7]> This makes absolutely no sense to me
<abu[7]> How can we find out *which* part of the memory gets bigger?
<abu[7]> Ha! It is free() alone too!
<abu[7]> Just (%@ "free" NIL 0) already increases
<abu[7]> but it increases not so much as with malloc
<abu[7]> Is it the native call?
<abu[7]> yes
<abu[7]> (%@ "getenv" 'S "TERM") also increases
<abu[7]> any native call
<abu[7]> e.g. (%@ "addu" T '(T . 3) '(T . 4)) -> 7
<abu[7]> Oh, I think I know
<abu[7]> It must be the library which gets opened repeatedly
<abu[7]> Yes! It is the lib!
<abu[7]> Change the file to (native *Lib "getenv" 'S "TERM")
<abu[7]> and then
<abu[7]> : (setq *Lib "@")
<abu[7]> (do 99999 (load "mem.l"))
<abu[7]> No more increase!
<abu[7]> (native *Lib ... re-uses the same transient symbol "@" (which holds the library handle after the first call)
<abu[7]> If "@" is used *inside* the file, it is a new transient symbol each time, and so the library gets loaded into memory each time
<abu[7]> 'load' keeps transient symbols private
<abu[7]> But I don't understand why this is also for '%@' ...
beneroth has quit [Ping timeout: 240 seconds]
beneroth has joined #picolisp
<beneroth> but if its transient symbols, so additional pil-managed-memory usage... then a (gc) should clean it, no?
<abu[7]> No, this is not the probleon
<abu[7]> problem
<abu[7]> Not Lisp heap
<abu[7]> The library get loaded each time
<abu[7]> But there is still something I don't understand
<beneroth> ah.. kinda loading the shared library for each call into memory
<abu[7]> Investigating ...
<abu[7]> yes
<abu[7]> bbl
<beneroth> see ya :)
<abu[7]> I'm outside in the rain ;)
<abu[7]> Can't type on a wet Penti
<tankf33der> :)
<abu[7]> Anyway I'm wrong. (%@ "getenv" 'S "TERM") does not specify the lib as a transient, and there is even no lib loading involved because it uses the binary itself, which is already loaded.
<abu[7]> Must think more (still walking)
<abu[7]> Now I found the true reason
<abu[7]> It is not the library, but the ffi structure allocated in the value of the transient symbol
<tankf33der> Eh
<abu[7]> In (%@ "getenv" 'S "TERM") it is "getenv"
<abu[7]> It holds a pointer to the prepared C call
<abu[7]> Prepare is quite expensive, so the pointer is cached
<beneroth> so (native) itself is causing the leaking, though it might be different depending on what gets allocated?
<beneroth> bbl
<abu[7]> The alloced size is always the same, one per function
<abu[7]> ffi *ffiPrep(char *lib, char *fun, ... in @src/lib.c
<abu[7]> ffi *p = malloc(sizeof(ffi) + nargs * sizeof(ffi_type*));
<abu[7]> OK, the size differs for each function, depending on its arguments
<abu[7]> This is done once for each function
<abu[7]> eg. "getenv"
<abu[7]> Then the symbol "getenv" stores this pointer in its value, and native directly uses it on all following calls
<abu[7]> But in 'load' transients are locally scoped
<abu[7]> so we get a new one each time
<abu[7]> The scoping is needed here for native calls
<abu[7]> becaus "getenv" might also be in another library and gets a different structure
<abu[7]> So there is not really a solution
pablo_escoberg has joined #picolisp
<abu[7]> Whe idea with native calls was that they reside in lib files which are loaded just once and then called
<tankf33der> this is ok. as is.
<abu[7]> One could free it manually, but that's ugly
<abu[7]> Should be a warning in the docs
pablo_escoberg has quit [Quit: Client closed]
pablo_escoberg has joined #picolisp
<pablo_escoberg> I'm having a rather funny time trying to figure out how to get a transient symbol containing a single backslash followed by a single quote.  which is to say, I need a function that returns "\'" (I'm doing sql sanitization).  It's really the single backslash that's giving me agida.  How do you do this in picolisp?
<abu[7]> "\\'"
<abu[7]> Like in most languages like C
<abu[7]> The backslash is a markup (also the double quote) in a string, so it must itself be escaped
<abu[7]> The caret ^ is also a markup
<abu[7]> for Control chars
<abu[7]> I think this is all described in @doc/ref.html
<abu[7]> no
<abu[7]> : (chop "\\'") -> ("\\" "'")
<abu[7]> : (mapcar char (chop "\\'")) -> (92 39)
seninha has quit [Ping timeout: 246 seconds]
<pablo_escoberg> ah, ok.  I was confused by the way it was displaying.  My initial instinct on how to do this was correct, but I kept seeing what looked wrong. TY.
<abu[7]> Yeah, read and print are symmetrical in PicoLisp
<abu[7]> "\\" is a single char, and it prigts as "\\"
<abu[7]> : (char 92) -> "\\"
seninha has joined #picolisp
<pablo_escoberg> oh, ok, that explains it better as well.
pablo_escoberg has quit [Quit: Client closed]
msavoritias has quit [Remote host closed the connection]