Author Topic: Thoughts on licensing issue  (Read 7121 times)

Offline chaos

  • BFF
  • ***
  • Posts: 291
  • Job, school, social life, sleep. Pick 2.5.
    • View Profile
    • Lost Souls
Re: Thoughts on licensing issue
« Reply #15 on: April 02, 2013, 05:00:27 pm »
Yeah, that's me except I use SecureCRT.

Offline wodan

  • BFF
  • ***
  • Posts: 434
  • Drink and code, you know you want to!
    • View Profile
Re: Thoughts on licensing issue
« Reply #16 on: April 02, 2013, 05:23:13 pm »
If you want to do debugging from in the mud, we'd have to get multithreading first :), also a good idea for any other form of stepping through the code as you'd lag everyone horribly otherwise!

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Thoughts on licensing issue
« Reply #17 on: April 02, 2013, 09:11:00 pm »
Obviously, you'd not stop the world on the main port.  Gdb does this quite well in c/c++: stop the world, as it were, and do all sorts of stuff.  On some machines, and in some configurations, you can even rewind with gdb.  Obviously, do debugging on a test port when possible.  Halting just a few objects would be extremely tricky, and I don't even want to think about how hard that would be to implement or work with in the mudlib (here comes the new is_halted function, and it's now in every piece of code everywhere, for instance, at the mudlib side of things).

    A properly coded c/c+ base, or fill-in-the-language base will not have the problem of outside code.  Everything should be modular anyway, and all communication should probably happen through chokepoints, to borrow someone Else's term for it.  In the current c/c++ codebases, this is a problem.  If you take some code and pass it through 20 different coders, or so, and start having everyone instal snippets written by other coders, you start having problems.  I'm sure everyone understands why dikurivatives are ugly.  We no longer need to maintain a list of unused player objects.  We no longer need to manually handle memory allocation ourselves, at least not in most cases.  Diku does all this coupled with generally sub-par coding style and design decisions, by today's standards, and therein lies the problem.

    I, personally, understand the appeal of just editing everything on the server, and if my screen reader were a bit better at handling cursor tracking in terminal sessions, I probably would.  That said, most new coders aren't going to...the days of coding in a terminal and invoking the compiler on the command line aren't gone, but they're headed that way.

    I will still have to defend the point about tools, though.  if I press compile, and something's going to not work because I forgot a semicolon, I'm going to know right away.  This is true, depending on mudlib, in lpc.  What lpc doesn't have, just for starters, is the ability to warn me about 500 different things that it thinks I probably don't actually want to do.  A good compiler optimizes my code, as well, which is always nice to have--especially if considering extremely complex features with large processing requirements.  Not as needed in the mudding world, not with all this extra computing power, but nice to have.  I am in no way calling Chaos a bad coder, quite the contrary, but if lpc had an optimizer, or if Lost Souls were written in c/c++ where good optimizers are available, it would probably not lag for the first two hours after boot (it may not now, as I've not played since the server upgrade).  Today's compilers are very, very, very smart--I tried to understand the kinds of things they do in the optimizing stage, and gave up quickly.  Clang claims to be able to tell if my code is likely to have bugs, even.
    I can't effectively argue an IDE, because I don't use half the features.  Eclipse is miles ahead of visual studio.  I don't care about syntax highlighting, but it's nice to be able to do project-wide searches and rename methods on the fly, and nothing beats being able to click an error and jump right to it.  I'm visually impaired, to the extent that I might as well not have a computer screen, and I still get enough out of an IDE that I will use one when I can.  If using modern c/c++, and boost, I can just press the run button in my IDE of choice and the mud will load up, ready to go, on any platform I choose to use.

Offline quixadhal

  • BFF
  • ***
  • Posts: 642
    • View Profile
    • WileyMUD
Re: Thoughts on licensing issue
« Reply #18 on: April 03, 2013, 09:40:41 am »
If you want to do debugging from in the mud, we'd have to get multithreading first :), also a good idea for any other form of stepping through the code as you'd lag everyone horribly otherwise!

Actually, you don't need multithreading.  You need to not abort LPC thread execution when the time's up, but save the stack machine's state for that object and context switch to the next one.

Right now, if a thread exceeds their eval ticks, it just gets killed.  How hard would it be to save state and restore it next time around the loop?

Offline Dworkin

  • Acquaintance
  • *
  • Posts: 34
    • View Profile
Re: Thoughts on licensing issue
« Reply #19 on: April 03, 2013, 10:12:34 am »
Actually, you don't need multithreading.  You need to not abort LPC thread execution when the time's up, but save the stack machine's state for that object and context switch to the next one.

Right now, if a thread exceeds their eval ticks, it just gets killed.  How hard would it be to save state and restore it next time around the loop?

That is so 20th century.  Event-driven, non-blocking, asynchronous I/O models are the height of fashion now: Node.js, Akka, Vert.x.

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Thoughts on licensing issue
« Reply #20 on: April 03, 2013, 11:18:19 am »
Just have the driver handle the debugging entirely, and stop the world when the mudlib says it's time to debug.  The entire thing is, iirc, a stack machine, so it's not like it's a huge deal to go line by line if the appropriate information is available.  Not small, but not huge either.  I'd argue that, in this case, multithreading is not worth the large added complexity--what happens if something on another thread wants to change a variable in the object being debugged?  Do I progressively stop the mud as things call into what I'm debugging?  The list goes on.  I am pro-multithreading, or at least used to be, but...I'd not even consider that here.

Offline quixadhal

  • BFF
  • ***
  • Posts: 642
    • View Profile
    • WileyMUD
Re: Thoughts on licensing issue
« Reply #21 on: April 03, 2013, 12:19:53 pm »
what happens if something on another thread wants to change a variable in the object being debugged?

Can't happen.  Variables can only be modified by things in the same object... access from outside requires a function call.  So, if you're debugging object A and object B makes a call into A, B will have to sit and wait OR get an error state as if one of the valid_ applies failed.

Note I'm not suggesting multithreading.  I'm suggesting doing what the driver already does, but saving state for unfinished threads, rather than aborting them.

Offline wodan

  • BFF
  • ***
  • Posts: 434
  • Drink and code, you know you want to!
    • View Profile
Re: Thoughts on licensing issue
« Reply #22 on: April 03, 2013, 02:43:28 pm »
can't be done, as there's C state in the call stack as well, you could be half way sorting an array (efun in C) in an lpc value comparing function, you'd need as much work to safely stop and restore that as you need for full multithreading, it's really the same problem :)

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Thoughts on licensing issue
« Reply #23 on: April 03, 2013, 02:49:05 pm »
I forgot that, my bad.  The point still remains: that raises a whole bunch of questions.  Now it's functions being stopped, but that's the same problem.  Debugging the mud is changing the state of the mud in a very nondeterministic way: I imagine that this approach, for starters, could very easily screw up timing.  Consider:
I debug the room I'm standing in.
I type look--my player object calls the room's description function.
My player object now freezes, because it's called into the room.
The mud calls my player object to tell it that there's new input, probably from wherever we handle networking.
My player object is frozen, because it called into the room we're debugging.
The network handler consequently freezes because my player object shares the called-debugging-code flag thing.
    So, here's the problem.  There's no reason it shouldn't freeze the dragon of eternal killing-the-players, but it just froze all input.  Said dragon, for example, has a 3 turn warm-up time for his breath of slaying, in which we're supposed to flee, or hold up the shield of reflection, or who knows what.  But the players can't because our mud isn't processing networking.  I suppose verbs could handle this more appropriately, but it snowballs.  What if I'm standing in the adjacent room?  What if a player innocently wanders in?  The point of debugging isn't to complicate the code, so making it such that we have to check for debugging before doing anything, or check the return calls of functions that are designed to quite literally never fail--a simple query_description function that just returns a string, or get input back like null descriptions.  The approach being discussed here seems like it would cause a *lot* of problems, and no one would use it just because it's difficult to understand.  Lpmuds don't usually have testports, but the whole point of a testport is that you can, if needed, stop the entire world.  Miss the error checking in one place only, and it could very easily corrupt game state.  I would just leave it at stop the entire world, and we recommend a testport somewhere in the docs.

Offline wodan

  • BFF
  • ***
  • Posts: 434
  • Drink and code, you know you want to!
    • View Profile
Re: Thoughts on licensing issue
« Reply #24 on: April 03, 2013, 02:55:18 pm »
btw, if you really love your gdb sessions, you can set a breakpoint at break_point() (in DEBUG drivers) and investigate the lpc stack after each (LPC)semicolon, (all vars are on the stack so that's all state there is), it could do with a way to get the current lpc file and linenumber though, or maybe there is and I just don't know it.

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Thoughts on licensing issue
« Reply #25 on: April 03, 2013, 04:24:13 pm »
Are the variable names there?  I thought they all just got slots internally, which leads us into investigating other things to determine which slot is which variable.  Being able to debug it is important in my opinion, but if i'm going to do that--why bother? I can do it in c/c++/any other language with a good debugger, and get a lot more out of it.  Also, compiling the driver with debugging enabled is supposed to slow things down, generally, so that might be significant (I'm not sure that allowing for the debugging of lpc would be much better, but lpc isn't optimizing anyway to my knowledge, so we don't lose much).  I'm not talking about me, I'm talking about everyone, and to do that requires knowing driver internals, to some extent anyway, and slowing down the driver in that way may matter for some muds (if we're on a testport, maybe not).

Offline FallenTree

  • BFF
  • ***
  • Posts: 485
    • View Profile
Re: Thoughts on licensing issue
« Reply #26 on: April 04, 2013, 05:41:21 am »
I havn't got around to try the debug_point() yet. But let me share my understanding of how can we add concurrency into FluffOS, and it is doable, IMHO.

LPC is compiled into a list of "instructions", and interpret.c simulate a stack machine, and execute instructions one by one.  new function calls will push the stack  and generally just change pc* (current program) and sp* (current stack) and repeat this instruction. On the other hand,  simulate.c maintain a while(true) loop, each "world turn", every object's heart_beat() get's called, much same as a new function call.

There is two aspect where you can possibly parallelize:
1) in eval_instructions, within each LPC function,  you can probably do something like parallelize loop execution if you are confident that there is no side-effect. This is doable, but very hard, and pretty interesting to think about if you are into this kind of thing. However, since I don't think anyone is using LPC for a lot of math, the saving is not going to be great.

2) The second part is interesting,  each "turn", every object's heart_beat() needs to be called.   it should be able to parallelize the execution of the individual object's heart_beat() function. 

However, there is a catch,  There might be side-effect if their heart_beat() function will call other object's function, like if two object is in combat, they will call COMBAT_D->do_attack() to each other, you can't execute them both in parallel, it must be done in-serial (doesn't matter who execute first, they just can't execute together).  Same thing applies if A calls environment(A)->present("B")  while A and B is in same room. But, there must be objects that have no involvement to each other and their execution can be safely parallelized.

Thus, driver must have knowledge of object relationship by analyzing the reference tree of the target code , and each efun has to define whether it is self-constrained or will reference other object (much like an const modifier on a c++ function). This is also a very interesting project to work on, and think about.

It is also possible to just have driver host several stack machine in parallel , and these world shares master_ob / simul_efun ob (access to that will be mutex protected, or better, if a LPC function can be marked as const (side-effect free), it can be accessed in parallel! ),  That way you can run your FTP server on this parallel universe without affecting your mud world. Or you can even dynamic create and destruct world (think of a HTTP server with per request world).  I think this is going to be great to implement, even without the heart_beat()

Actually, 3) maybe my goal to implement in FluffOS 3.0, provided enough people thinks it will be useful.


Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Thoughts on licensing issue
« Reply #27 on: April 04, 2013, 12:05:51 pm »
In no particular order (save as I thought of them):

If we really want to go here, it shouldn't be up to the driver.  Parallelizing code automatically is hard, probably doctorate level work, and you could go make this your college degree.  If this happens, it's headed over to Dgd in terms of complexity--that is, there will be all sorts of "this function must" cases that creep in over time.  I like Dgd, but it is definitley more complex.
    If parallel execution is something that you *really* want, and I really don't see the point--just fake it in the driver, and that's good enough for most muds--let the mudlib do it, not you.  Tell the mudlib authors that if they want it they need to handle heartbeat themselves, and maybe add in some more hooks to control it.
    I would love to see an optimizer, and automatically parallelizing code would be cool and 21st century and all that, but I don't expect these things in the near future.  They are hard to do.
    Perhaps the best approach is a new thread block, something like:
thread {
threaded code goes here
}
    Or, for explicit thread control,
handle = thread {
...
}
    In all honesty, I think that to take advantage of this would require centralizing the mudlib anyway, and moving to a diku-style design philosophy: everything is handled by centralized daemons.  No mudlibs, to my knowledge, do this.
    Http connections don't stay open.  Having thread support might let you do interesting web stuff, but it won't effect http that much.  I'm having trouble parsing your statement about http to figure out what exactly you mean.
    I would not personally integrate ftp into the mud.  It is an appealing thought, but sounds like a whole lot of trouble to get right in terms of security, outweighed by the fact that we can use the mud's security systems.
    The gains of threading may be lost by the code that determines if we can.  It's not a one-time compilation, it's an ongoing process, and objects can be replaced at any time.  In the best case, the code must examine the object to be parallelized and all direct references to it.  I am not up to date on how that works, but it seems to me--with the naive approach--that you would end up examining at least one level of references (that is, the references to the object directly).  This would then snowball out until we've either examined the whole world or determined that we can parallelize a function call.
    If this is such a big deal, don't use const, use pure.  A pure function will always return the same output for the same inputs, and will never have any side-effect.  Pure functions can be parallelized and inlined elsewhere without a problem, and determining purity is simpler.  Allow the mudlib author to mark a function as pure, and (this is important) have the driver enforce it.  A pure function is a function that contains mathamatical operations only, excluding assigning to its parameters, or that contains both math and function calls only to other pure functions.  The definition then becomes recursive, and all pure functions should be verifiably pure.  In addition, This means that the return value can also be cached.  The degree of "purity" needed, if I may be allowed the liberty of inventing some terminology, is only such that the function is read-only; read-only functions that do nothing save return a value after reading a bunch of stuff may be parallelized with other read-only functions with no extra mechanisms, and parallelized with functions that change state via the use of locks.
    Finally, you're going to be sending deterministic coding out the window.  It does matter who gets do_attack called on them first.  In close battles, whether I attack first or you attack first matters, as we might both be one attack away from death.  In a worse case, if I cast a spell that, say, applies a barrier to me that destroys weapons, and the multithreading decides to do the next round of my enemy's attack first...this will cause all sorts of trouble, and has been the main objection I've seen to multithreading when I've brought it up.  Game mechanics then gain a high degree of not really randomness and can't be easily documented in a consistent fashion.

Offline wodan

  • BFF
  • ***
  • Posts: 434
  • Drink and code, you know you want to!
    • View Profile
Re: Thoughts on licensing issue
« Reply #28 on: April 04, 2013, 01:18:23 pm »
ftp works just fine from lpc, as does the web (both run from lpc on discworld).

all suggested threading solutions have one thing in common: an LPC interpreter that allows running in multiple threads at the same time, this happens to be the hardest part to do for all of them. however it would be useful to be able to have things run on the side without having to split it up in call_out loops or heart_beat()s, so maybe the effort for it should be done (it's also the only way to get real performance improvements, cpu cores are getting faster at an extremely slow rate these days).

after that adding fun stuff that uses it should be easy, you could have a foreachparallel(), mutex efuns (would definitely need to include deadlock detection), etc.

but none of it will work without that first step.

Offline FallenTree

  • BFF
  • ***
  • Posts: 485
    • View Profile
Re: Thoughts on licensing issue
« Reply #29 on: April 04, 2013, 01:24:23 pm »
wodan: The interpreter only uses a couple pointers and a array for stack, should be pretty easy to duplicate.

I would hope we can discuss more of how to implement what I said in point 3, having ability to create a object in a separate interpreter stack that runs independently of the main world.