Show enters and exits. Hide enters and exits.
| 00:00:13 | evan | yep |
| 00:00:26 | evan | once an object has been set it memory, you can't change it's size |
| 00:00:32 | evan | so you can't add new slots to it after the fact |
| 00:00:43 | evan | so you keep an extra slot at the beginning around to store any ivars that you missed |
| 00:00:51 | evan | kresten was saying that it works great |
| 00:02:32 | dgtized | but what if you never refered to them by name, what if you generated a symbol table for the class, and then just layered the symbol table for the subclass but instead of doing a lookup each time you just used it's static scope, as in depth/offset? |
| 00:02:58 | evan | doesn't work |
| 00:03:01 | dgtized | but you kept around the symbol table for send lookups? |
| 00:03:02 | evan | because you'll miss something |
| 00:03:09 | evan | and then where do you put this new ivar? |
| 00:03:11 | evan | or someone will do |
| 00:03:14 | evan | def "".blah |
| 00:03:17 | evan | @weee = 3 |
| 00:03:17 | evan | end |
| 00:03:23 | evan | where does @weee go? |
| 00:03:32 | dgtized | as a monkey patch you mean? |
| 00:03:33 | evan | what does send have to do with this? |
| 00:03:38 | evan | or extend |
| 00:03:46 | evan | or including a Module into the object's class |
| 00:03:54 | evan | there are zillions of ways to introduce new ivars in ruby |
| 00:04:11 | dgtized | you just append it to the symbol table, at this current level, and then replace further instances with that depth/offset? |
| 00:04:12 | manveru | heh |
| 00:04:32 | manveru | 1.instance_variable_set('@a', 1); 1.instance_variable_get('@a') |
| 00:04:33 | manveru | # 1 |
| 00:04:36 | manveru | still my favorite |
| 00:04:50 | evan | dgtized: what about current instances? |
| 00:04:59 | evan | have the GC replace all of them? |
| 00:05:03 | evan | yikes. |
| 00:05:10 | evan | for the record |
| 00:05:13 | evan | i tried this last year |
| 00:05:15 | evan | at MWRC |
| 00:05:17 | dgtized | they can share the symbol table for that class though can't they? |
| 00:05:26 | evan | and quickly realized that you can never know all the ivars an object might use |
| 00:05:40 | evan | dgtized: but old instances are too small now |
| 00:08:06 | dgtized | so what are you doing for all of the ones that aren't in this initial numbered ivars scheme? |
| 00:08:23 | dgtized | are they the only ones that are fast access or something? |
| 00:08:26 | evan | throw them in a lookuptable |
| 00:08:30 | evan | thats referenced in slot 0 |
| 00:09:06 | dgtized | so every single object has a lookuptable anyway, or only if an unknown instance variable gets allocated? |
| 00:09:17 | evan | the later |
| 00:09:22 | evan | you allocate it lazily |
| 00:09:50 | dgtized | but that lookuptable is not shared? |
| 00:09:58 | evan | course not |
| 00:10:03 | evan | objects don't share ivars. |
| 00:10:09 | enebo_ enters the room. | |
| 00:10:19 | evan | this lookuptable maps ivar names (@weeee) to values (1) |
| 00:11:45 | headius_ enters the room. | |
| 00:12:53 | dgtized | so whenever you fail a lookup at the current level you check your superclasses ivar lookup or no? |
| 00:13:07 | evan | no |
| 00:13:26 | evan | you alter the specialized methods to access the slots directly |
| 00:14:06 | evan | and for ivars that are added later, emit code that accesses them via the lookup table |
| 00:15:52 | dgtized | so if you had a contrained lookup table using a regular tuple, and you just spit out the offsets directly instead of doing a hash lookup that would be the same right? |
| 00:16:05 | dgtized | by constrained I mean it took up the same amount of space as you had instance variables |
| 00:16:52 | evan | um. |
| 00:16:57 | evan | yeah, you could do that |
| 00:17:05 | evan | then you could enlarge the tuple later |
| 00:17:17 | rubuildius_amd64 | Vladimir Sizikov: e12d21a90; 2097 files, 6777 examples, 24236 expectations, 0 failures, 4 errors; http://rafb.net/p/toobig.html |
| 00:17:18 | rubuildius_amd64 | Marnen Laibow-Koser: 68cfef604; 2097 files, 6771 examples, 24232 expectations, 0 failures, 0 errors; http://rafb.net/p/dW4mNF75.html |
| 00:17:26 | evan | but you'd have to check at every access to see if the table needs to be enlarged |
| 00:17:48 | dgtized | no, you would only have to do it if the access was out of bounds |
| 00:17:48 | evan | because when the ivar is added, you don't want to go out and find all instances and enlarge their ivars table |
| 00:18:02 | evan | and how do you think out of bounds checks are done? |
| 00:18:07 | evan | by checking the size. |
| 00:18:10 | evan | same thing. |
| 00:18:55 | dgtized | don't we do that with tuples anyway though? |
| 00:19:12 | dgtized | which is what those ivars are stored in right? |
| 00:19:29 | ezmobius_ enters the room. | |
| 00:19:32 | dgtized | that's what infinite Access reference out of range errors are right? |
| 00:19:36 | evan | i've lost ya now. |
| 00:19:41 | Arjen_ leaves the room. | |
| 00:19:41 | evan | i don't get what you're trying to do. |
| 00:19:55 | dgtized | right now we have a tuple for each object right, with a set number of slots |
| 00:20:03 | evan | no |
| 00:20:12 | rue | Back up. |
| 00:20:34 | dgtized | you have a static C array for each slot? |
| 00:20:34 | rue | Objects have slots for predefined, and they have a table for runtime ivars |
| 00:20:35 | evan | there is an optimization that stores ivars in a tuple, but not by slot number. It's basically just a tiny, linearly searched hash table |
| 00:20:39 | evan | dgtized: no |
| 00:20:48 | evan | an object is fixed size in memory |
| 00:20:50 | dgtized | I'm talking about for predefined |
| 00:20:55 | evan | a header, with a fixed number of slots after it |
| 00:21:00 | dgtized | I know that's what I meant by the tuple |
| 00:21:00 | evan | each slot can hold a reference to another object |
| 00:21:26 | dgtized | So each object is a vector of slots, where one slot is defined to be for a lookup table if you need to add slots? |
| 00:21:42 | evan | no |
| 00:21:53 | evan | i wasn't talking about current code |
| 00:22:06 | evan | i was talking in the future |
| 00:22:13 | evan | a scheme that the java hotruby uses |
| 00:22:16 | evan | that we might use too |
| 00:23:02 | nicksieger leaves the room. | |
| 00:23:05 | headius leaves the room. | |
| 00:23:13 | enebo leaves the room. | |
| 00:23:30 | anteaya leaves the room. | |
| 00:23:40 | therealadam leaves the room. | |
| 00:24:01 | Fullmoon leaves the room. | |
| 00:24:10 | dgtized | ok so right now we stick those extra ivars in __ivars__ right? |
| 00:24:17 | dgtized | and the rest should map to an existing slot |
| 00:24:40 | evan | no |
| 00:25:08 | evan | i think you're confusing yourself between now and the future. |
| 00:25:14 | evan | there are builtin classes |
| 00:25:17 | evan | that use the slots |
| 00:25:19 | dgtized | ok, well neither were explained well |
| 00:25:26 | dgtized | as in I thought you were talking about now |
| 00:25:38 | evan | dgtized: no need to be snippy. |
| 00:25:55 | srbaker enters the room. | |
| 00:26:02 | evan | anyway, some builtin class use the slots directly |
| 00:26:09 | evan | the name to slot index is hard coded |
| 00:26:17 | dgtized | sorry I didn't mean to be snippy I just thought we had been talking about now and then all of a sudden I was informed otherwise |
| 00:26:45 | evan | i guess you missed where I said this was a scheme we might do in the future. |
| 00:26:53 | evan | anyway, they're hardcoded |
| 00:27:02 | dgtized | ok so in those builtin's the ivars are actually instance variables on the C++ class? |
| 00:27:13 | evan | the compiler is taught to map certain ivars in certain classes to slots |
| 00:27:17 | evan | again, hardcoded. |
| 00:27:34 | evan | all other ivars are stored in a lookuptable |
| 00:27:39 | dgtized | or rather the builtin slots map to builtin C++ class instance variables |
| 00:27:42 | evan | which can be stored in 1 or 3 places: |
| 00:27:50 | evan | the external_ivars table (for immediates) |
| 00:27:57 | evan | the metaclass (for things like Array and String) |
| 00:28:01 | evan | the first slot |
| 00:28:11 | evan | case 2 should be eliminated |
| 00:28:15 | evan | it's there because of legacy |
| 00:28:36 | evan | dgtized: the mapping to C++ ivars is in the new VM yes |
| 00:28:43 | evan | but it's essentially exactly the same |
| 00:28:47 | dgtized | ok good same page then |
| 00:28:48 | evan | just with new syntax in the VM |
| 00:29:30 | dgtized | are you arguing for removing the metaclass in general or just for ivars, not following the argument on number 2 |
| 00:29:57 | dgtized | or I'm probably confusing the issue more there |
| 00:30:56 | evan | all builtins should just have a slot 0 reserved for ivars |
| 00:31:10 | evan | the case 2) is for builtins that doen't |
| 00:32:36 | dgtized | ok, but that's an implementation decision that makes them have 3 cases correct? |
| 00:33:21 | evan | yeah |
| 00:35:42 | rudebwoy leaves the room. | |
| 00:37:59 | enebo_ leaves the room. | |
| 00:38:02 | dgtized | ok, and those slots need to be fast access in C++ land so that when they get used by C++ methods they are direct access and don't have to walk back into the VM and back out again? |
| 00:38:07 | dc_ leaves the room. | |
| 00:42:32 | srbaker leaves the room. | |
| 00:43:15 | dgtized | can we figure out a way for that ivar_index stuff to be defined in C++ automatically and then passed out to ruby so they don't show up looking weird and special? |
| 00:43:29 | ezmobius leaves the room. | |
| 00:43:29 | ezmobius_ leaves the room. | |
| 00:43:42 | evan | weird and special how? |
| 00:44:10 | avibryant enters the room. | |
| 00:44:55 | rue | dgtized: You are thinking that ivar lookups could be intercepted transparently for those? |
| 00:45:53 | ezmobius enters the room. | |
| 00:47:32 | dgtized | where is ivars_as_index defined? |
| 00:47:41 | evan | it's not |
| 00:47:44 | evan | it's a compiler directive. |
| 00:47:48 | dgtized | oh |
| 00:48:46 | dgtized | how many other compiler directives that look exactly like methods do we have? |
| 00:49:19 | evan | um. |
| 00:49:21 | evan | one i think |
| 00:49:23 | evan | Ruby.primitive |
| 00:49:39 | evan | the ivar_as_index stuff is a mistake |
| 00:49:42 | evan | it's too confusing. |
| 00:50:13 | dgtized | yea because I thought we were definining the tuple used to store that object right there |
| 00:50:22 | evan | nope |
| 00:50:54 | evan | plus, if you reopen, say, Array and try and access one of the sloted ivars |
| 00:50:59 | evan | it silently doesn't work. |
| 00:51:06 | dgtized | Ruby.primitive could just be written to rewrite the method the first time it was called instead of being a compiler directive right? |
| 00:51:48 | evan | no |
| 00:51:49 | dgtized | ah, because it's not actually adding those variables to the symbol table for that class |
| 00:51:52 | evan | not at all. |
| 00:52:15 | evan | having Ruby.primitive rewrite is so overly complicated. |
| 00:52:23 | evan | and Ruby.primitive is very isolated. |
| 00:52:36 | dgtized | ok |
| 00:53:44 | dgtized | wait so the problem with the ivars is that the compiler knows about them when they are first being used, but then later on, it doesn't have them in that first slot __ivars__ table because it only gets defined if something other then those variables get used? |
| 00:54:26 | dgtized | ie it knows about them at file compile time but not at user compile time? |
| 00:54:49 | evan | the hints aren't loaded when running user code. |
| 00:55:04 | evan | the hints say, "map @total in Array it slot 1" |
| 00:55:05 | dgtized | because they might do weird stuff compiling user code? |
| 00:55:06 | evan | for instance. |
| 00:55:18 | evan | because it doesn't make sense for a user code to do that. |
| 00:55:24 | evan | was my original thinking. |
| 00:55:38 | mkrauskopf leaves the room. | |
| 00:56:09 | dgtized | hmm seems like that makes the turtle stack unduly shallow |
| 00:56:12 | agardiner | hmmm... it looks like Rubinius doesn't support BEGIN blocks - is that right? |
| 00:56:23 | evan | agardiner: pretty sure thats true. |
| 00:56:25 | agardiner | i don't even see it appearing in the sexp |
| 00:56:34 | evan | dgtized: depends on your perspective. |
| 00:56:38 | evan | yeah |
| 00:56:44 | evan | BEGINs are dum |
| 00:56:45 | evan | b |
| 00:56:50 | evan | the parser puts them in a seperate sexp |
| 00:56:54 | agardiner | and used by rdebug... |
| 00:56:55 | evan | which we aren't exporting currently |
| 00:56:58 | agardiner | ah |
| 00:56:59 | evan | UG. |
| 00:57:02 | evan | it uses BEGIN? |
| 00:57:05 | evan | take that shit out. |
| 00:57:10 | agardiner | yeah, pretty clever actually |
| 00:57:19 | evan | how does it use it? |
| 00:57:30 | agardiner | it uses an eval around a BEGIN block to see if the user typed a valid expression for a breakpoint condition |
| 00:57:44 | agardiner | eval("BEGIN {return true}\n#{code}", nil, "", 0) |
| 00:57:45 | evan | THE HORROR |
| 00:57:49 | evan | MY EYES |
| 00:57:51 | evan | MYYYYYY |
| 00:57:54 | evan | EEEYYYYYEEES |
| 00:57:55 | agardiner | :-) |
| 00:57:55 | ezmobius | say THE HORROR |
| 00:57:55 | boyscout | THE HORROR |
| 00:57:56 | rubuildius_amd64 | THE HORROR |
| 00:57:56 | rubuildius_ppc | THE HORROR |
| 00:58:02 | jp_tix | lol |
| 00:58:22 | jp_tix | that actually got me out of lurking :) |
| 00:58:28 | evan | agardiner: i don't get how that works. |
| 00:58:33 | agardiner | that line is wrapped in a rescue |
| 00:58:36 | evan | jp_tix: NOW WE HAVE YOU. |
| 00:58:43 | agardiner | so, if the eval is successful, you get true |
| 00:58:55 | agardiner | if the rescue is invoked, it returns false |
| 00:59:06 | evan | why not put it in a begin/rescue |
| 00:59:25 | agardiner | because you don't want to invoke the user code, just test it is valid |
| 00:59:36 | avibryant | why not just return true\n#{code} |
| 00:59:36 | avibryant | ? |
| 00:59:41 | evan | yeah |
| 00:59:45 | evan | forget the begin |
| 00:59:49 | agardiner | i dunno, i didn't write it! |
| 00:59:56 | dgtized | wait is code a single lone |
| 00:59:58 | dgtized | line |
| 00:59:58 | evan | eval "return :awesome; #{code}" |
| 01:00:07 | dgtized | or the whole file? |
| 01:00:07 | agardiner | just found it doesn't work! :-) |
| 01:00:12 | evan | :) |
| 01:00:18 | agardiner | code is a single line |
| 01:00:28 | agardiner | e.g. break blah:4 if <code> |
| 01:00:49 | evan | it's just testing if +code+ is syntaticly correct? |
| 01:00:51 | bricolage leaves the room. | |
| 01:00:53 | agardiner | yeah |
| 01:01:03 | dgtized | oh just run it through Compile |
| 01:01:09 | agardiner | the method is called syntax_valid? |
| 01:01:12 | evan | begin; code.to_sexp; return true; rescue SyntaxError; return false; end |
| 01:01:15 | benstiglitz leaves the room. | |
| 01:01:29 | evan | or do what avibryant said |
| 01:01:32 | agardiner | i have no problem coming up with alternative ways of testing it, but this is in rdebug... |
| 01:01:33 | evan | nix the BEGIN |
| 01:01:38 | evan | so? |
| 01:01:41 | evan | we'll send in a patch. |
| 01:01:57 | agardiner | yeah, we could do that, but i wanted to avoid it |
| 01:02:07 | agardiner | this is the sort of stuff we'll have to deal with in code in the wild |
| 01:02:14 | evan | we should fix BEGIN though... |
| 01:02:15 | evan | :/ |
| 01:02:17 | evan | BLAH. |
| 01:02:17 | dgtized | evan: thank you for the illumination on ivars in ruby, I think I get it better now |
| 01:02:18 | evan | :) |
| 01:02:23 | evan | dgtized: cool. |
| 01:03:02 | agardiner | fyi what i am doing is building a rubinius implementation of the ruby-debug-base gem |
| 01:03:11 | agardiner | i don't want to touch ruby-debug at all |
| 01:03:12 | evan | sweeeet |
| 01:03:20 | agardiner | since it is supposed to be platform neutral |
| 01:03:37 | Maledictus leaves the room. | |
| 01:03:43 | agardiner | yeah, this allows us to leverage everything that rdebug provides |
| 01:03:53 | agardiner | remote debugging, IDE integration, etc |
| 01:04:02 | rue | What is an IDE? |
| 01:04:14 | agardiner | i dunno...? |
| 01:04:27 | evan | I Don't Edit |
| 01:04:28 | agardiner | its an acronym, so i fiugred it must be good!?! |
| 01:04:36 | agardiner | :-) |
| 01:06:13 | agardiner | ok, so on BEGIN - you say we aren't even getting the sexp out at present? |
| 01:06:29 | evan | yep. |
| 01:06:57 | agardiner | i may be able to monkey-patch this in ruby-debug-base, but i'm not sure what the load order is... |
| 01:08:19 | evan | agardiner: you should have zenspider see if he can help get the begin sexp out. |
| 01:08:26 | fabiokung enters the room. | |
| 01:08:41 | agardiner | so this is a parsetree fix needed? |
| 01:08:50 | radarek enters the room. | |
| 01:10:38 | agardiner | damn... can't monkey patch it, it seems, since it looks like my code is loaded before the code that uses BEGIN :-( |
| 01:17:08 | benny leaves the room. | |
| 01:17:29 | evan | agardiner: the version of parsetree we use, yeah. |
| 01:17:48 | agardiner | ok, will do |
| 01:21:59 | headius_ leaves the room. | |
| 01:22:56 | TheVoic1 enters the room. | |
| 01:23:03 | djwhitt_ enters the room. | |
| 01:23:30 | lopex_ enters the room. | |
| 01:24:18 | kevwil enters the room. | |
| 01:24:46 | jp_tix_ enters the room. | |
| 01:25:02 | TheVoice leaves the room. | |
| 01:25:02 | lopex leaves the room. | |
| 01:25:02 | smparke1 leaves the room. | |
| 01:25:02 | hornbeck leaves the room. | |
| 01:25:02 | joachimm leaves the room. | |
| 01:25:02 | Ingmar leaves the room. | |
| 01:25:02 | jicksta leaves the room. | |
| 01:25:02 | rue leaves the room. | |
| 01:25:02 | jp_tix leaves the room. | |
| 01:25:02 | goodney leaves the room. | |
| 01:25:02 | _goodney_ leaves the room. | |
| 01:25:02 | djwhitt leaves the room. | |
| 01:25:02 | Defiler leaves the room. | |
| 01:25:02 | brixen leaves the room. | |
| 01:25:50 | crafterm enters the room. | |
| 01:25:56 | Defiler enters the room. | |
| 01:26:37 | rue enters the room. | |
| 01:27:40 | rue | Weird |
| 01:28:02 | djwhitt_ leaves the room. | |
| 01:30:08 | djwhitt enters the room. | |
| 01:30:31 | smparke1 enters the room. | |
| 01:30:44 | avibryant leaves the room. | |
| 01:31:25 | Ingmar enters the room. | |
| 01:31:25 | TheVoice enters the room. | |
| 01:31:25 | lopex enters the room. | |
| 01:31:25 | joachimm enters the room. | |
| 01:31:25 | jicksta enters the room. | |
| 01:31:25 | brixen enters the room. | |
| 01:31:25 | goodney enters the room. | |
| 01:31:25 | _goodney_ enters the room. | |
| 01:33:22 | ctennis leaves the room. | |
| 01:33:25 | enebo enters the room. | |
| 01:34:07 | djwhitt leaves the room. | |
| 01:34:17 | djwhitt enters the room. | |
| 01:35:31 | rue | http://rubyforge.org/projects/rubob |
| 01:36:55 | tarcieri | whoa |
| 01:38:12 | lopex leaves the room. | |
| 01:39:43 | djwhitt leaves the room. | |
| 01:40:06 | djwhitt enters the room. | |
| 01:40:23 | rudebwoy enters the room. | |
| 01:40:52 | brixen_ enters the room. | |
| 01:40:53 | _goodney_ leaves the room. | |
| 01:40:53 | goodney leaves the room. | |
| 01:40:53 | joachimm leaves the room. | |
| 01:40:53 | Ingmar leaves the room. | |
| 01:40:53 | TheVoice leaves the room. | |
| 01:40:53 | brixen leaves the room. | |
| 01:40:53 | jicksta leaves the room. | |
| 01:40:59 | _goodney_ enters the room. | |
| 01:41:03 | Ingmar_ enters the room. | |
| 01:41:14 | goodney enters the room. | |
| 01:41:20 | joachimm enters the room. | |
| 01:42:17 | kevwil leaves the room. | |
| 01:45:58 | ctennis enters the room. | |
| 01:47:17 | twbray leaves the room. | |
| 01:47:17 | ctennis leaves the room. | |
| 01:47:38 | ctennis enters the room. | |
| 01:48:14 | headius enters the room. | |
| 01:49:30 | GMFlash leaves the room. | |
| 01:50:11 | benburkert leaves the room. | |
| 01:50:38 | jtoy enters the room. | |
| 01:55:00 | dlee leaves the room. | |
| 02:10:14 | sambo leaves the room. | |
| 02:11:08 | nicksieger enters the room. | |
| 02:11:16 | ctennis leaves the room. | |
| 02:11:16 | headius leaves the room. | |
| 02:11:16 | rue leaves the room. | |
| 02:11:16 | rubuildius_amd64 leaves the room. | |
| 02:11:16 | flori leaves the room. | |
| 02:11:16 | rudebwoy leaves the room. | |
| 02:11:16 | fabiokung leaves the room. | |
| 02:11:16 | rubuildius_ppc leaves the room. | |
| 02:11:16 | olabini leaves the room. | |
| 02:11:16 | VVSiz leaves the room. | |
| 02:11:16 | ttmrichter leaves the room. | |
| 02:11:16 | meanphil leaves the room. | |
| 02:11:16 | kAworu leaves the room. | |
| 02:11:16 | zenspider leaves the room. | |
| 02:11:16 | ko1_away leaves the room. | |
| 02:11:16 | maharg leaves the room. | |
| 02:11:16 | jammi leaves the room. | |
| 02:11:16 | smparke1 leaves the room. | |
| 02:11:16 | lopex_ leaves the room. | |
| 02:11:16 | mass leaves the room. | |
| 02:11:16 | oweff leaves the room. | |
| 02:11:16 | zf leaves the room. | |
| 02:11:52 | smparke1 enters the room. | |
| 02:11:52 | lopex_ enters the room. | |
| 02:11:52 | fabiokung enters the room. | |
| 02:11:52 | rubuildius_ppc enters the room. | |
| 02:11:52 | olabini enters the room. | |
| 02:11:52 | VVSiz enters the room. | |
| 02:11:52 | ttmrichter enters the room. | |
| 02:11:52 | meanphil enters the room. | |
| 02:11:52 | kAworu enters the room. | |
| 02:11:52 | zenspider enters the room. | |
| 02:11:52 | ko1_away enters the room. | |
| 02:11:52 | maharg enters the room. | |
| 02:11:52 | jammi enters the room. | |
| 02:11:52 | mass enters the room. | |
| 02:11:52 | oweff enters the room. | |
| 02:11:52 | zf enters the room. | |
| 02:12:42 | samruby enters the room. | |
| 02:12:42 | ctennis enters the room. | |
| 02:13:18 | headius enters the room. | |
| 02:13:18 | rue enters the room. | |
| 02:13:18 | rubuildius_amd64 enters the room. | |
| 02:13:18 | flori enters the room. | |
| 02:14:10 | trythil enters the room. | |
| 02:15:08 | boyscout | 1 commit by Adam Gardiner |
| 02:15:09 | boyscout | * Add unique ids to breakpoints; 171d4be |
| 02:15:16 | benny enters the room. | |
| 02:19:12 | headius leaves the room. | |
| 02:21:18 | ezmobius leaves the room. | |
| 02:22:25 | rubuildius_amd64 | Adam Gardiner: 171d4be20; 2097 files, 6770 examples, 24231 expectations, 0 failures, 0 errors; http://rafb.net/p/FP2cJo45.html |
| 02:23:27 | benburkert enters the room. | |
| 02:29:44 | radarek leaves the room. | |
| 02:30:16 | rubuildius_ppc | Adam Gardiner: 171d4be20; 2097 files, 6772 examples, 24257 expectations, 0 failures, 0 errors; http://pastie.caboo.se/paste/189705 |
| 02:32:54 | sambo enters the room. | |
| 02:32:55 | samruby leaves the room. | |
| 02:33:47 | lopex_ leaves the room. | |
| 02:40:05 | benburkert leaves the room. | |
| 02:41:55 | benburkert enters the room. | |
| 02:44:05 | headius enters the room. | |
| 02:44:57 | cored enters the room. | |
| 02:45:35 | VVSiz_ enters the room. | |
| 02:52:42 | rudebwoy enters the room. | |
| 02:54:11 | twbray enters the room. | |
| 02:54:55 | ezmobius enters the room. | |
| 02:55:28 | hornbeck leaves the room. | |
| 02:56:47 | headius_ enters the room. | |
| 02:57:27 | twbray leaves the room. | |
| 02:57:54 | headius leaves the room. | |
| 02:58:26 | benburkert leaves the room. | |
| 02:59:47 | anteaya enters the room. | |
| 03:00:06 | crafterm_ enters the room. | |
| 03:02:24 | crafterm leaves the room. | |
| 03:02:44 | brweber2 enters the room. | |
| 03:04:00 | VVSiz leaves the room. | |
| 03:04:22 | wdperson enters the room. | |
| 03:05:44 | AndrewO leaves the room. | |
| 03:07:25 | wmoxam enters the room. | |
| 03:08:31 | ezmobius leaves the room. | |
| 03:08:54 | sambo82 enters the room. | |
| 03:11:44 | AndrewO enters the room. | |
| 03:18:20 | rudebwoy leaves the room. | |
| 03:20:09 | twbray enters the room. | |
| 03:20:25 | KirinDave enters the room. | |
| 03:20:38 | wdperson leaves the room. | |
| 03:20:59 | ezmobius enters the room. | |
| 03:24:33 | knowtheory enters the room. | |
| 03:25:22 | agile leaves the room. | |
| 03:29:47 | sambo leaves the room. | |
| 03:31:39 | agile enters the room. | |
| 03:32:18 | sambo82 leaves the room. | |
| 03:39:23 | wycats_ enters the room. | |
| 03:42:34 | benburkert enters the room. | |
| 03:43:40 | vertiginous enters the room. | |
| 03:45:02 | twbray leaves the room. | |
| 03:50:43 | ko1 | http://www.infoq.com/news/2008/04/maglev-gemstone-builds-ruby |
| 03:50:56 | dysinger leaves the room. | |
| 03:51:03 | ko1 | no relation with rubinius? |
| 03:52:23 | xxi enters the room. | |
| 03:52:25 | brixen | ko1_: no relation, but we had talked with avi here today about core ruby libs |
| 03:52:52 | brixen | ko1_: you can read the logs here: http://www.donttreadonme.co.uk/rubinius-irc/rubinius.log.20080430.html |
| 03:53:19 | ko1 | thank you! |
| 03:53:26 | ko1 | so we have more rivals |
| 03:53:51 | brixen | heh indeed :) |
| 03:54:06 | brixen | ruby is so hot, all the cool kids on the block want one :) |
| 03:55:05 | djwhitt | rivals, nah, not as long as everyone colaborates |
| 03:55:40 | brixen | well, sort of like sibling rivalry |
| 03:55:43 | djwhitt | hehe |
| 03:55:53 | brixen | not like say U.S. vs U.S.S.R |
| 03:55:54 | brixen | :) |
| 03:56:03 | sambo enters the room. | |
| 03:56:14 | sambo leaves the room. | |
| 03:58:33 | evan | someone called me a 'snarky cow' on my Rubinius Retort post |
| 03:58:35 | evan | :/ |
| 03:59:19 | rue | Not cool, dude, you are a totally mellow cow |
| 03:59:57 | evan | chews the cud. |
| 04:01:19 | brixen | haha, snarky? evan? |
| 04:01:30 | brixen | maybe they're confusing you with headius :) |
| 04:01:40 | brixen | they got their wires crossed |
| 04:01:55 | vertiginous | I think they were talking about another commenter |
| 04:03:17 | ixx leaves the room. | |
| 04:04:20 | fabiokung leaves the room. | |
| 04:04:27 | knowtheory | i'm confused why there's snarkiness to begin with |
| 04:04:41 | headius | evan: give me back my snark. |
| 04:04:45 | knowtheory | seems like everyone's still cooperating |
| 04:05:02 | evan | headius: seriously. |
| 04:05:21 | evan | knowtheory: headius was having a slow monday |
| 04:05:23 | djwhitt | evan: yeah, pretty sure "Mr eel" was addressing "nothanks" with that snarky comment |
| 04:05:38 | knowtheory | headius: Liked your post, it's convinced me that i should be contributing to Rubinius :P |
| 04:05:49 | knowtheory | (perhaps not your intended effect ;) ) |
| 04:05:59 | brixen | heh |
| 04:06:27 | knowtheory | er, i think Mr. Eel is a mate of mine, should i ask for clarification? |
| 04:07:09 | headius | knowtheory: glad I could help |
| 04:08:02 | knowtheory | headius: I've been following the vm progress through your writings, which i greatly appreciate, so thanks! |
| 04:08:20 | headius | "the vm"? |
| 04:08:36 | knowtheory | Progress on the vm fronts generally |
| 04:09:11 | cored leaves the room. | |
| 04:10:35 | trythil_ enters the room. | |
| 04:10:35 | trythil leaves the room. | |
| 04:13:42 | dysinger enters the room. | |
| 04:16:37 | twbray enters the room. | |
| 04:17:41 | crafterm leaves the room. | |
| 04:26:33 | benburkert leaves the room. | |
| 04:28:00 | wmoxam leaves the room. | |
| 04:32:36 | crafterm enters the room. | |
| 04:37:34 | GMFlash enters the room. | |
| 04:37:58 | marnen enters the room. | |
| 04:38:39 | marnen leaves the room. | |
| 04:46:56 | brweber2 leaves the room. | |
| 04:48:21 | enebo leaves the room. | |
| 04:50:49 | MenTaLguY enters the room. | |
| 04:51:53 | headius | knowtheory: ahh ok, well glad to keep you up-to-date then |
| 04:54:10 | knowtheory leaves the room. | |
| 04:54:31 | AndrewO leaves the room. | |
| 04:54:31 | rudebwoy enters the room. | |
| 04:54:31 | knowtheory enters the room. | |
| 04:59:18 | jennyw enters the room. | |
| 05:22:13 | benburkert enters the room. | |
| 05:28:40 | ezmobius leaves the room. | |
| 05:30:47 | agardiner | drbrain: what should i be setting the platform to in a gem that is targeting rubinius? |
| 05:30:51 | femtowin enters the room. | |
| 05:30:54 | yugui enters the room. | |
| 05:30:56 | femtowin leaves the room. | |
| 05:31:08 | Erlang enters the room. | |
| 05:31:44 | Erlang leaves the room. | |
| 05:31:51 | Erlang000 enters the room. | |
| 05:34:51 | Erlang00t enters the room. | |
| 05:35:07 | Erlang00t | hello |
| 05:35:30 | Erlang00t | for rubinius io |
| 05:35:33 | drbrain | agardiner: I don't know |
| 05:35:34 | Erlang000 leaves the room. | |
| 05:35:45 | Erlang00t | something that io#read-->io#fill_from |
| 05:36:26 | Erlang00t | Scheduler.send_on_readable @channel ... |
| 05:36:34 | Erlang00t | obj=@channel.receive |
| 05:36:42 | agardiner | drbrain: does that mean there isn't any auto-detection for rubinius in gems yet? |
| 05:36:45 | tarcieri | hey ostensible Erlang lover guy |
| 05:36:57 | tarcieri | I'd like to do a Port(s) interface |
| 05:37:02 | drbrain | there is not |
| 05:37:04 | tarcieri | for any I/O object |
| 05:37:06 | Erlang00t | what does this mean? could someone please explain this? |
| 05:37:08 | Erlang00t | :) |
| 05:37:12 | Erlang00t | yes |
| 05:37:18 | tarcieri | that way you don't have to deal with Scheduler |
| 05:37:19 | Erlang00t | I supposed that for io to work |
| 05:37:33 | Erlang00t | you should have something like fd or FILE* |
| 05:37:34 | tarcieri | you just point a Port at the Actor you want to receive datagrams |
| 05:37:42 | tarcieri | and then the Actor deals with Scheduler for you |
| 05:37:47 | Erlang00t | or use stdc like getc or putc's routine |
| 05:37:49 | Erlang00t | stdio related |
| 05:37:59 | tarcieri | Ala Erlang active mode |
| 05:38:13 | Erlang00t | but I can't see the related code that in rubinius that implements File |
| 05:38:31 | tarcieri | If Ports worked for arbitrary IO objects you could use them with File |
| 05:39:13 | Erlang00t | I'm not sure, what does that mean? |
| 05:39:31 | tarcieri | Are you familiar with active once semantics? |
| 05:39:35 | rue | I am completely lost :P |
| 05:39:57 | rue | agardiner: Send a patch :) |
| 05:39:59 | Erlang00t | I'm not familiar with Actor |
| 05:40:05 | tarcieri | err |
| 05:40:09 | tarcieri | so do you know Erlang? |
| 05:40:22 | Erlang00t | but I checked out with the ruby implementation |
| 05:40:24 | Erlang00t | or MRI |
| 05:40:24 | tarcieri | Erlang processes follow the Actor model |
| 05:40:24 | Erlang00t | said |
| 05:40:29 | agardiner | rue: i might have to! :-) |
| 05:40:42 | Erlang00t | I just understands Erlang a bit:) |
| 05:40:53 | tarcieri | Erlang provides ports as an interfacing mechanism between Erlang processes and things that aren't Erlang processes |
| 05:40:54 | Erlang00t | not much, yes, about Actor, process send each other message |
| 05:40:56 | tarcieri | Like sockets |
| 05:41:04 | tarcieri | Or external programs |
| 05:41:10 | tarcieri | Or external programs which pretend to be sockets |
| 05:41:29 | Erlang00t | oh, yes, so what's related with IO? |
| 05:41:41 | Erlang00t | or what I want to understand is how ruby/rubinius implement File#read |
| 05:41:48 | tarcieri | Well, I guess I just assumed from your nickname there you were looking for a more Erlangesque approch to I/O |
| 05:41:50 | tarcieri | apparently not |
| 05:41:50 | tarcieri | heh |
| 05:42:05 | headius_ enters the room. | |
| 05:42:19 | Erlang00t | no, apparently not:) |
| 05:42:36 | tarcieri | Erlang: Scheduler provides what's effectively a message driven approach to I/O |
| 05:42:55 | wycats_ leaves the room. | |
| 05:43:34 | tarcieri | Scheduler sends messages to Channels when I/O events occur |
| 05:43:56 | tarcieri | this wakes up the associated Task and lets it process the incoming I/O event |
| 05:44:00 | antares enters the room. | |
| 05:44:25 | ryantmulligan leaves the room. | |
| 05:44:52 | Erlang00t | yes, for obj=@channel.receive to work |
| 05:45:08 | Erlang00t | but @channel.receive must delegate to something that fd.read, or FILE.read |
| 05:45:18 | MenTaLguY | @channel.receive doesn't |
| 05:45:21 | Erlang00t | I just want to find out the related code in order to understand more |
| 05:45:23 | MenTaLguY | Scheduler handles that |
| 05:45:41 | Erlang00t | oh, yes, so where is the code? |
| 05:45:45 | MenTaLguY | basically you enqueue a request to the scheduler to notify you when IO is ready |
| 05:45:53 | MenTaLguY | and then scheduler itself writes back on the channel you provided |
| 05:46:50 | Erlang00t | yes, so where's the code about scheduler work, writes the channel when IO is ready |
| 05:46:50 | tarcieri | it's so much like Ports already it'd be so easy to wrap up in an API designed to work directly with Actors |
| 05:47:06 | Erlang00t | there should be some code like fd.read or FILE.read in somewhere |
| 05:47:16 | tarcieri | Erlang: a lot of it is in C, or Ruby that generates C |
| 05:47:21 | tarcieri | afaik |
| 05:47:39 | tarcieri | the underpinnings are libev, which is a C library |
| 05:48:05 | tarcieri | (which works ala kernel poll in Erlang) |
| 05:48:32 | anteaya leaves the room. | |
| 05:48:33 | MenTaLguY | for the current VM, see shotgun/lib/cpu_event.c |
| 05:48:52 | MenTaLguY | cpu_event_wait_readable and _cpu_wake_channel_and_read |
| 05:49:46 | MenTaLguY | to see how reads work |
| 05:51:33 | Erlang00t | yes |
| 05:51:41 | Erlang00t | see something like while(1) |
| 05:51:47 | GMFlash leaves the room. | |
| 05:51:58 | Erlang00t | i = read(ti->fd, buf,sz) |
| 05:51:58 | GMFlash enters the room. | |
| 05:52:10 | Erlang00t | so seems to use libev-->Unix System Call |
| 05:52:23 | Erlang00t | is this correct? |
| 05:52:25 | tarcieri | yes |
| 05:52:35 | Erlang00t | while c ruby uses io#read-->stdio |
| 05:52:44 | tarcieri | select() |
| 05:52:53 | tarcieri | is the system call behind all MRI IO |
| 05:53:21 | tarcieri | and it's pretty much hardwired in all over the place |
| 05:53:31 | tarcieri | e.g. rb_thread_select() |
| 05:53:54 | tarcieri | that's the basis of how MRI schedules green threads alongside I/O events |
| 05:53:57 | MenTaLguY | well, pretty much any blocking operation really |
| 05:54:08 | tarcieri | it's ooooglaaay |
| 05:54:22 | MenTaLguY | if a thread needs to block it goes back into the select loop and another thread is scheduled from there |
| 05:54:41 | tarcieri | In Rev I effectively busy wait on the thread scheduler |
| 05:54:48 | tarcieri | in 1.8 at least |
| 05:54:51 | tarcieri | it's ooglaaaay |
| 05:54:55 | Erlang00t | I checked out the MRI, there's rb_io_readchar function |
| 05:54:57 | trythil_ leaves the room. | |
| 05:54:59 | tarcieri | 1.9 actually lets one thread make a blocking call |
| 05:55:09 | tarcieri | yes all of those type of calls ultimately call rb_thread_select() |
| 05:55:10 | trythil enters the room. | |
| 05:55:19 | Erlang00t | rb_io_readchar-->rb_io_getc |
| 05:55:19 | tarcieri | which calls rb_thread_schedule() alongside select() |
| 05:55:24 | Erlang00t | so it seems use stdio |
| 05:55:28 | tarcieri | yep |
| 05:55:31 | Erlang00t | you mean 1.9 he changes to use select()? |
| 05:55:33 | tarcieri | Ruby is hardwired into iolib |
| 05:55:42 | tarcieri | 1.8 uses select() |
| 05:56:00 | Erlang00t | 1.8? but in 1.8 I see rb_io_readchar-->rb_io_getc |
| 05:56:06 | Erlang00t | not seems to use select() |
| 05:56:24 | tarcieri | rb_io_getc() calls rb_io_wait_readable() |
| 05:56:29 | tarcieri | rb_io_wait_readable() calls rb_thread_select() |
| 05:56:40 | MenTaLguY | you can guess what rb_thread_select() calls |
| 05:56:55 | tarcieri | heh |
| 05:57:38 | tarcieri | rb_thread_select() is a busywaiting mechanism which runs green threads while polling the kernel with select() |
| 05:57:38 | Erlang00t | so you mean at the end he still use Unix System Call, not thru stdio? |
| 05:58:01 | tarcieri | if you ever strace/ktrace an MRI process doing I/O you'll see it calling select() an asston of times |
| 05:58:21 | Erlang00t | c=getc(f) |
| 05:58:23 | tarcieri | it's using select() to do event monitoring |
| 05:58:23 | MenTaLguY | I wouldn't really call it a busywaiting mechanism |
| 05:58:36 | headius leaves the room. | |
| 05:58:37 | MenTaLguY | since it blocks if there are no runnable threads and no ready events |
| 05:58:44 | Erlang00t | I see this in rb_getc(f) |
| 05:59:15 | tarcieri | MenTaLguY: Does it? I think it keeps calling rb_thread_schedule() regardless of if there's a runnable thread |
| 05:59:15 | yugui leaves the room. | |
| 05:59:33 | tarcieri | MenTaLguY: rb_thread_schedule() just doesn't do anything if there isn't a runnable thread |
| 05:59:50 | tarcieri | if there's a way to defer to a blocking state if there's no runnable threads in MRI I'd really love to hear it |
| 05:59:53 | tarcieri | it's such a hack in Rev now |
| 05:59:55 | Erlang00t | it first calls rb_thread_wait_fd, then called getc(f) |
| 06:00:25 | MenTaLguY | crap, it does keep calling select even when it's blocking |
| 06:00:26 | MenTaLguY | that's awful |
| 06:00:37 | tarcieri | yep |
| 06:01:28 | benburkert leaves the room. | |
| 06:01:31 | fleadope enters the room. | |
| 06:01:36 | tarcieri | rb_thread_blocking_region() in 1.9 is nice |
| 06:01:44 | tarcieri | it lets you actually make blocking syscalls |
| 06:02:04 | tarcieri | Rev is a *lot* faster on 1.9 |
| 06:02:14 | tarcieri | like 4X faster |
| 06:02:51 | Erlang00t | Rev, what's Rev? |
| 06:03:08 | MenTaLguY | event-driven IO library |
| 06:03:15 | tarcieri | It's a libev binding for MRI/YARV |
| 06:03:45 | KirinDave leaves the room. | |
| 06:03:46 | Erlang00t | yes |
| 06:04:01 | ko1 | wow |
| 06:04:33 | tarcieri | hey ko1 |
| 06:04:39 | tarcieri | YARV is nice for I/O |
| 06:04:41 | tarcieri | :) |
| 06:05:43 | ko1 | does it have portability? |
| 06:05:53 | ko1 | i mean that it works on windows? |
| 06:06:07 | tarcieri | libev works on Windows |
| 06:06:10 | tarcieri | supposedly |
| 06:06:13 | tarcieri | with mingw maybe |
| 06:06:24 | ko1 | great |
| 06:06:25 | tarcieri | Rev does not build on Windows right now |
| 06:06:50 | fleadope enters the room. | |
| 06:07:00 | ko1 | Rev is wrapper? |
| 06:07:03 | tarcieri | yes |
| 06:07:04 | fleadope leaves the room. | |
| 06:07:04 | ko1 | or scratch? |
| 06:07:07 | ko1 | i see |
| 06:07:33 | tarcieri | it uses rb_thread_blocking_region() on YARV |
| 06:07:42 | tarcieri | on MRI it busy-waits and calls rb_thread_schedule() |
| 06:08:29 | ko1 | it's my purpose :) |
| 06:08:47 | tarcieri | yeah it's certainly been fast for us |
| 06:09:29 | ko1 | completely replace default I/O? |
| 06:09:39 | tarcieri | yep |
| 06:09:39 | ko1 | or can be use as extension library? |
| 06:09:45 | wycats_afk leaves the room. | |
| 06:09:54 | tarcieri | it's a C extension + a bunch of Ruby |
| 06:09:58 | tarcieri | available as a gem |
| 06:09:59 | tarcieri | "rev" |
| 06:10:23 | ko1 | i see |
| 06:10:23 | tarcieri | but it does act as a replacement for default I/O when you use it |
| 06:10:29 | tarcieri | since it calls the thread scheduler directly |
| 06:10:36 | tarcieri | in MRI at least |
| 06:10:49 | tarcieri | on YARV it just does blocking calls |
| 06:11:12 | tarcieri | the Ruby on top is a full fledged Reactor library |
| 06:11:20 | tarcieri | sort of like EventMachine |
| 06:11:24 | tarcieri | or Twisted |
| 06:12:11 | tarcieri | but unlike EventMachine it works directly with Ruby IO objects |
| 06:12:20 | tarcieri | And Ruby openssl |
| 06:12:41 | Erlang00t | just looks some code of MRI 1.8 |
| 06:13:05 | Erlang00t | rb_getc calls rb_thread_wait_fd which calls rb_thread_schedule |
| 06:13:15 | Erlang00t | and then rb_getc called getc(fd) |
| 06:13:26 | tarcieri | what version are you lookning at? |
| 06:13:30 | Erlang00t | so it seems that it will first invoke something like select() to wait |
| 06:13:35 | tarcieri | I'm looking at 1.8.6 p111 |
| 06:13:41 | tarcieri | but yes |
| 06:13:45 | Erlang00t | 1.8.6 |
| 06:13:45 | tarcieri | that's what it does |
| 06:14:08 | Erlang00t | and then getc(fd) |
| 06:14:17 | tarcieri | uses select() to wait for the event, then getc() to consume it |
| 06:14:20 | Erlang00t | so actually it still uses stdio to implement File#read |
| 06:14:27 | Erlang00t | yes |
| 06:14:28 | tarcieri | yes |
| 06:14:33 | Erlang00t | that's what I want to ask |
| 06:14:33 | Erlang00t | yes |
| 06:14:34 | tarcieri | select() for the event waiting |
| 06:14:37 | tarcieri | heh |
| 06:14:46 | tarcieri | yes, maybe I wasn't clear as iolib is kind of a glibc thing |
| 06:14:51 | Erlang00t | because the Unix call it self is too low level and ugly |
| 06:14:56 | tarcieri | yep |
| 06:14:58 | Erlang00t | the read() call |
| 06:15:01 | tarcieri | not the only place Ruby is like that |
| 06:15:08 | Erlang00t | harder use than stdio |
| 06:15:17 | Erlang00t | though stdio of course implements thru it |
| 06:15:24 | tarcieri | I/O is an afterthought for most people and Ruby didn't wrap it up very well |
| 06:15:29 | Erlang00t | and for windows system, it of course doesn't have the Unix call |
| 06:15:39 | tarcieri | yeah it uses some sort of compatibility library |
| 06:15:41 | Erlang00t | so, the natural questions come to me |
| 06:15:46 | tarcieri | Rubinius is trying to avoid that |
| 06:15:47 | tarcieri | I believe |
| 06:15:54 | Erlang00t | is how do ruby implement that |
| 06:15:59 | tarcieri | and reimplement the POSIX semantics without relying on the underlying POSIX syscalls |
| 06:16:04 | Erlang00t | so it turns out using stdio, which is quite natural |
| 06:16:07 | tarcieri | mostly in Ruby, I think |
| 06:16:10 | Erlang00t | and not use Unix call directly |
| 06:16:15 | tarcieri | I haven't looked at the code so I may be speaking out my ass here |
| 06:16:23 | Erlang00t | rubinius? |
| 06:16:24 | tarcieri | s/syscalls/library calls/ |
| 06:16:48 | Erlang00t | because the problem with direct calling open() calls, is first, is too low level |
| 06:16:53 | Erlang00t | second, can't handle windows |
| 06:17:16 | Erlang00t | but I see some code read() in rubnius |
| 06:17:20 | tarcieri | Ruby's using POSIX extensions to ANSI C |
| 06:17:36 | tarcieri | That let you get to the underlying open() syscall that fopen() is using |
| 06:17:39 | Erlang00t | just MentaLu refered in cpu_event |
| 06:17:43 | tarcieri | e.g. IO#fileno |
| 06:18:50 | Erlang00t | I'm not sure, the IO#fileno is more like an ANSI C, (C standard thing) |
| 06:19:00 | Erlang00t | or more like some common Unix call,like POSIX thing |
| 06:19:13 | Erlang00t | POSIX make all Unix work, but just Unix |
| 06:21:14 | tarcieri | fileno() isn't ANSI C because file descriptors aren't ANSI C |
| 06:21:28 | tarcieri | stdio is ANSI C |
| 06:21:36 | Erlang00t | yes, so a POSIX thing |
| 06:21:39 | tarcieri | yep |
| 06:21:47 | tarcieri | a POSIX thing that's hardwired into Ruby |
| 06:22:12 | tarcieri | not the only place |
| 06:22:22 | Erlang00t | yes, you are talking about MRI? |
| 06:22:43 | tarcieri | yes |
| 06:23:36 | Erlang00t | so how does it handles windows? |
| 06:23:56 | tarcieri | some sort of compatibility library |
| 06:24:01 | tarcieri | I don't really know |
| 06:24:05 | tarcieri | I've never used Ruby on Windows |
| 06:24:10 | Erlang00t | yes |
| 06:24:19 | Erlang00t | some sort of thought experiment here |
| 06:24:32 | Erlang00t | it ANSI c can run both on Unix and windows |
| 06:24:38 | Erlang00t | and already can handle file |
| 06:24:50 | Erlang00t | then MRI just directly uses ANSI c to handle file |
| 06:24:54 | Erlang00t | then it's done |
| 06:24:57 | Erlang00t | no need to use POSIX |
| 06:25:07 | Erlang00t | just some sort of thought experiment here |
| 06:25:29 | tarcieri | umm |
| 06:25:35 | Erlang00t | but for rubnius, because it uses read() call, that's what makes me confuse here. |
| 06:25:36 | tarcieri | I kind of just explained the problem there |
| 06:25:42 | tizianobis enters the room. | |
| 06:25:48 | tarcieri | Being able to multiplex FILEs with select() |
| 06:25:49 | wycats enters the room. | |
| 06:25:51 | tarcieri | uses fileno() |
| 06:25:54 | tarcieri | which is a POSIXism |
| 06:26:05 | Erlang00t | yes, you can see that as an optimization for Unix |
| 06:26:06 | tarcieri | the entire mechanism by which the scheduler waits for I/O is based around POSIX semantics |
| 06:26:24 | Erlang00t | yes, can see that as an optimzation for Unix |
| 06:26:48 | tarcieri | You pretty much have to do something to that effect on Unix |
| 06:27:02 | tarcieri | Convert an IO object to its file descriptor |
| 06:27:14 | tarcieri | and hand that to whatever you're using as your scheduler |
| 06:27:37 | Erlang00t | you means windows or Rubinius? |
| 06:27:50 | tarcieri | for any program you write in a Unix environment |
| 06:27:55 | tarcieri | POSIX environment |
| 06:28:23 | Erlang00t | well, yes, I don't care |
| 06:28:30 | Erlang00t | if ANSI c lib's implemetation |
| 06:28:38 | Erlang00t | like getc() underlying uses read() |
| 06:28:46 | Erlang00t | but if you uses ANSI c's getc() directly |
| 06:28:51 | tarcieri | it uses select() to know when to read() |
| 06:29:02 | Erlang00t | then your program is directly portable on everything supports ANSI c |
| 06:31:03 | tarcieri | no it's not |
| 06:31:07 | tarcieri | because the scheduler isn't portable |
| 06:31:15 | tarcieri | and that's way more important than how it interfaces with files |
| 06:31:46 | Erlang00t | scheduler, you mean in MRI? |
| 06:31:50 | tarcieri | yes |
| 06:31:57 | KirinDave enters the room. | |
| 06:32:12 | Erlang00t | rubinius seems to use read() system call directly? |
| 06:32:18 | tarcieri | Rubinius uses libev |
| 06:32:23 | tarcieri | for its scheduler |
| 06:32:40 | Erlang00t | yes, but for real call? real getting the char |
| 06:32:47 | Erlang00t | ignore the scheduler now here |
| 06:33:24 | tarcieri | the point is you're not going to implement a virtual machine for any language that supports I/O without some way of scheduling I/O alongside the rest of what you're doing |
| 06:33:45 | tarcieri | and there's no portable way of doing that short of something like libevent/libev |
| 06:36:04 | Erlang00t | yes |
| 06:36:54 | Erlang00t | I'm confused by how the real getting char is |
| 06:37:07 | tizianobis_ enters the room. | |
| 06:37:09 | Erlang00t | then you are making me more confused by the scheduler ..:) |
| 06:37:13 | tarcieri | haha |
| 06:37:25 | tarcieri | on Unix it's calling getc() which is calling read() |
| 06:37:34 | Erlang00t | yes, I know |
| 06:37:40 | tarcieri | on Win32 it's probably calling the Win32 ANSI getc() |
| 06:37:40 | Erlang00t | in unix getc() underlying uses read() |
| 06:37:48 | Erlang00t | but getc() also works in win32 |
| 06:37:48 | tarcieri | for files |
| 06:37:52 | tarcieri | and something else for sockets |
| 06:37:55 | Erlang00t | yes, that's what I mean |
| 06:38:00 | tarcieri | which is probably all abstracted in some compatibility later somewhere |
| 06:38:04 | tarcieri | so you want to know about Windows |
| 06:38:06 | tarcieri | well don't ask me |
| 06:38:08 | tarcieri | I don't really know |
| 06:38:10 | tarcieri | I can just guess |
| 06:38:19 | Erlang00t | haha |
| 06:38:34 | Erlang00t | because rubinius uses read() unix call direclty |
| 06:38:39 | tarcieri | just put it at: Windows was an afterthought |
| 06:38:44 | Erlang00t | so I wonder how future rubinius is going to support windows |
| 06:38:47 | tarcieri | Rubinius isn't portable to Win32 yet |
| 06:38:53 | tarcieri | as in the API |
| 06:39:00 | tarcieri | people are trying to get it going through Cygwin I think |
| 06:39:30 | Erlang00t | yes |
| 06:39:37 | Erlang00t | kind of getting the problem here |
| 06:39:46 | Erlang00t | for real getchar, MRI uses getc() |
| 06:39:50 | Erlang00t | so it's not a problem |
| 06:39:54 | Erlang00t | where rubinius uses read() |
| 06:39:56 | Erlang00t | so there's a problem |
| 06:40:04 | Erlang00t | ok, then the scheduler |
| 06:40:16 | Erlang00t | for scheduler, yes, I can agree with that no portable way |
| 06:40:32 | tarcieri | Rubinius is trying to reimplement the POSIX semantics in Ruby rather than have a big nasty portability mess in C |
| 06:40:42 | tarcieri | afaik |
| 06:40:49 | Erlang00t | but something like #ifdef windows windows_way_of_scheduler #ifdef unix posix_way_of_scheduler |
| 06:41:00 | tarcieri | that's already abstracted in libev |
| 06:41:06 | Erlang00t | something like that, just mental model |
| 06:41:14 | tarcieri | (kind of) |
| 06:41:17 | Erlang00t | libev is portable to windows? |
| 06:41:21 | tarcieri | yes |
| 06:41:35 | tarcieri | although the backend isn't enabled per default |
| 06:41:36 | tarcieri | which is silly |
| 06:41:47 | jennyw leaves the room. | |
| 06:42:00 | tarcieri | by default libev on Windows uses select() which is part of Winsock and thus only works with sockets |
| 06:42:28 | irbwoy enters the room. | |
| 06:43:25 | Erlang00t | yes, so for the scheduler, I guess there shouldn't be a problem |
| 06:43:25 | Erlang00t | but to use the scheduler, you are targeting a high performance? |
| 06:43:25 | Erlang00t | because directly implement |
| 06:43:25 | Erlang00t | like in rubinius directly implemnt File#read |
| 06:43:25 | Erlang00t | I would just File#read --> getc(fd) |
| 06:43:26 | Erlang00t | then it's ok |
| 06:43:28 | Erlang00t | no need to go thru scheduler, or event or something |
| 06:43:32 | Erlang00t | that's my mental model here |
| 06:44:44 | tizianobis__ enters the room. | |
| 06:46:30 | evan | Erlang00t: you a big erlang guy I suppose. |
| 06:46:42 | Erlang00t | no |
| 06:46:48 | rue | Muhahaa. I have now opened 1200 buffers in this vim session |
| 06:46:50 | Erlang00t | I do not know Erlang too much.. |
| 06:47:11 | evan | ooh look at everything I missed |
| 06:47:11 | yugui enters the room. | |
| 06:47:18 | evan | drbrain and I were killing eachother in GTA4 |
| 06:48:21 | headius leaves the room. | |
| 06:48:38 | headius enters the room. | |
| 06:49:21 | headius leaves the room. | |
| 06:49:37 | headius enters the room. | |
| 06:49:39 | tarcieri | haha evan |
| 06:49:52 | tarcieri | I should really go play GTA4 |
| 06:50:06 | evan | multiplayer is good |
| 06:50:11 | evan | probably more fun with a ton of people though |
| 06:50:11 | tarcieri | so I've heard |
| 06:50:12 | headius_ enters the room. | |
| 06:50:14 | evan | than with just 2 |
| 06:50:16 | tarcieri | nice |
| 06:50:17 | smparke1 leaves the room. | |
| 06:50:18 | evan | because you have access to the entire map |
| 06:50:21 | tarcieri | there's like a coop free-for-all mode? |
| 06:50:26 | evan | and helicopters, boats, the whole gamit |
| 06:50:27 | evan | yep |
| 06:50:34 | tarcieri | you're both PS3? |
| 06:50:42 | MenTaLguY | Erlang00t: anyway, the trouble with doing File#read directly is that nothing else can happen in that thread while it is waiting for the read to be ready/complete |
| 06:50:42 | headius | blast |
| 06:50:44 | headius | brb |
| 06:50:46 | rue | "Misdemeanor Jaywalking 3" is more my speed |
| 06:50:59 | evan | tarcieri: y.p |
| 06:51:16 | tarcieri | well uhh, let me know next time you're playing |
| 06:51:17 | headius | gamut |
| 06:51:21 | headius | wow...wtf |
| 06:51:21 | tarcieri | I should really go beat some more missions |
| 06:51:23 | headius | some kind of screwball lag |
| 06:51:24 | tarcieri | I don't even have a gun yet |
| 06:51:25 | headius | maybe irc dropping issues aren't my problem |
| 06:51:38 | tarcieri | I assume I'm about to get one already, ugh |
| 06:52:01 | tarcieri | I mean, i took one from a cop, and uhh, drove around for awhile and shot some stuff |
| 06:52:12 | Erlang00t | MentaLguY: but I guess for the programmer to write simple ruby program |
| 06:52:27 | Erlang00t | some ruby logic-->read some file-->anyway,there's already a block call here |
| 06:52:27 | evan | tarcieri: sure, we'll let ya know |
| 06:52:29 | tarcieri | MenTaLguY: so how about something like Actor.bind(IO) -> Port |
| 06:52:32 | evan | we're going to play coop tomorrow evening I think |
| 06:52:34 | evan | if you're around. |
| 06:52:39 | Erlang00t | the programmer anyway assumes need to read something |
| 06:52:42 | tarcieri | evan: cool |
| 06:53:12 | MenTaLguY | tarcieri: can you try it in Rubinius, see how it works? |
| 06:53:23 | MenTaLguY | lib/actor/port.rb or something |
| 06:53:29 | tarcieri | ok |
| 06:53:36 | tarcieri | I'm just wondering where I should be interfacing |
| 06:53:38 | tarcieri | which Channel |
| 06:53:39 | tarcieri | @ready? |
| 06:54:02 | MenTaLguY | oh, hm |
| 06:54:06 | tarcieri | The idea is to let an Actor directly receive I/O events from scheduler |
| 06:54:09 | MenTaLguY | it should be part of the normal message stream shouldn't it? |
| 06:54:29 | tarcieri | Without any middleman |
| 06:54:33 | tarcieri | There doesn't need to be |
| 06:54:46 | tarcieri | The semantics are practically there already |
| 06:54:48 | MenTaLguY | I'm not sure how to do this without a middleman right now |
| 06:54:52 | tarcieri | Just needs a pretty face for Actors |
| 06:55:07 | tarcieri | whatever Channel is waiting for message events |
| 06:55:14 | MenTaLguY | I think it's more feasible for an actor that doesn't have to implement termination-on-exit |
| 06:55:14 | tarcieri | have Scheduler send messages there |
| 06:55:19 | tizianobis leaves the room. | |
| 06:55:42 | MenTaLguY | Well, the thing is that in order to implement terminate-on-exit, there isn't really a channel waiting for messages anymore |
| 06:55:58 | tarcieri | so what does an Actor do when it calls receive now? |
| 06:56:01 | MenTaLguY | it's more of a "conceptual" channel cobbled out of a couple real ones |
| 06:56:07 | tarcieri | and please note GTA4 is calling |
| 06:56:09 | tarcieri | heh |
| 06:56:18 | headius leaves the room. | |
| 06:56:29 | MenTaLguY | well, it acquires the semaphore encoded by @lock |
| 06:56:39 | MenTaLguY | checks to see if there's anything of interest in the mailbox |
| 06:56:42 | tarcieri | semaphore implemented on top of a Channel? |
| 06:56:55 | MenTaLguY | if not, it sets up @ready, indicates that it's waiting, and then releases @lock |
| 06:57:22 | MenTaLguY | and waits on @ready to get either true or false, to indicate timeout or not (or is it the other way around?) |
| 06:57:32 | MenTaLguY | either way it re-acquires @lock |
| 06:57:45 | twbray leaves the room. | |
| 06:57:46 | MenTaLguY | queues up the action to do |
| 06:57:48 | MenTaLguY | releases @lock |
| 06:57:51 | MenTaLguY | and then does the action |
| 06:57:59 | MenTaLguY | in the kitchen |
| 06:58:01 | MenTaLguY | with the candlestick |
| 06:58:09 | tarcieri | heh |
| 06:58:38 | MenTaLguY | but, yes, a semaphore is just a channel where we ignore the value written |
| 06:58:42 | MenTaLguY | conceptually |
| 06:59:00 | MenTaLguY | the count of a semaphore is really just a count of unconsumed writes |
| 06:59:01 | tarcieri | okay, well... could that be changed to be interruptable |
| 06:59:04 | tarcieri | by an I/O event |
| 06:59:08 | tarcieri | in addition to a timeout |
| 06:59:21 | MenTaLguY | you'd need to be very careful in that case |
| 06:59:28 | MenTaLguY | since you don't want stale stuff in @ready |
| 06:59:39 | MenTaLguY | note the care that is taken to "reset" it to a pristine state after use |
| 07:00:33 | tarcieri | well, the next Scheduler event would be triggered by the first being processed... although it's possible spurious events could occur if whatever triggered the event were processed elsewhere |
| 07:00:55 | MenTaLguY | that and you could have multiple events triggering I think? |
| 07:01:05 | tarcieri | yes, but they'd have a unique fileno |
| 07:01:13 | tarcieri | just read events |
| 07:01:18 | MenTaLguY | yes, but the rest would still get written to the channel too |
| 07:01:29 | tarcieri | the problem I forsee |
| 07:01:37 | tarcieri | you have an "active" Port |
| 07:01:43 | tarcieri | it becomes readable |
| 07:01:48 | drbrain | somebody should right all this down in RDoc somewhere... |
| 07:01:51 | tizianobis_ leaves the room. | |
| 07:01:55 | tarcieri | okay, well, the solution to the problem |
| 07:02:07 | tarcieri | Ports should only be "active" during Actor.receive |
| 07:02:16 | tarcieri | that's how you prevent spurious messages |
| 07:02:32 | MenTaLguY | drbrain: write what, exactly? the parts of the conversation so far that aren't a literal narration of the code are speculative |
| 07:03:10 | MenTaLguY | I do think, semantically, that the port notifications do need to be submitted via the normal actor system as well |
| 07:03:12 | drbrain | MenTaLguY: well, if you figure something out that's concrete, I guess you should write that down |
| 07:03:14 | tarcieri | when Actor.receive completes, it needs to cancel all the I/O wait events |
| 07:03:24 | tarcieri | and that's where it'd be nice to have nested event loops |
| 07:03:24 | drbrain | I certainly don't know how it works :( |
| 07:05:19 | MenTaLguY | tarcieri: I think we'll need to hash this out more than we can do tonight |
| 07:05:42 | evan | drbrain: it's pretty crazy you can go anywhere on the map in deathmatch mode |
| 07:05:49 | evan | and a bitch that you always start in the same palec. |
| 07:05:50 | evan | place. |
| 07:05:51 | drbrain | yeah |
| 07:06:10 | drbrain | flying the helicopter is still hard |
| 07:06:16 | evan | yea |
| 07:06:17 | drbrain | I tried to shoot at you some |
| 07:06:23 | drbrain | but I was too unstable |
| 07:06:26 | evan | from the helicopter? |
| 07:06:31 | evan | what weapon? |
| 07:06:35 | tarcieri | MenTaLguY: I think it's doable now if you used sent a marker object, cancelled all the I/O events, and reaped everything upto it |
| 07:06:41 | drbrain | the helicopter guns |
| 07:06:55 | tarcieri | MenTaLguY: that'd ensure it's flushed clean after Actor.receive finishes |
| 07:07:21 | evan | drbrain: i didn't realize it had dedicated guns. |
| 07:07:25 | evan | i wonder if there is a tank. |
| 07:07:27 | drbrain | the nothernmost part of the starting building has a helicopter with guns on it |
| 07:07:37 | drbrain | probably somewhere |
| 07:07:38 | tarcieri | just needs to look up cheat codes |
| 07:07:40 | tarcieri | and go do that |
| 07:07:42 | MenTaLguY | tarcieri: well, yeah, that is the approach used for timeouts right now actually |
| 07:07:45 | agardiner | evan: want me to commit a fix for Tuple#to_a as discussed yesterday? |
| 07:07:51 | evan | pleas |
| 07:07:55 | agardiner | ok |
| 07:08:11 | tarcieri | MenTaLguY: well, as timeouts are already a type of interrupt, I can probably just piggyback on that, and have I/O events be a new type of interrupt |
| 07:08:51 | drbrain | although, you can probably shoot out of the helicopter with the SMG or pistol |
| 07:08:57 | drbrain | L1 shoots while in a car |
| 07:09:02 | tarc |