code logs -> 2011 -> Sat, 15 Oct 2011< code.20111014.log - code.20111016.log >
--- Log opened Sat Oct 15 00:00:11 2011
00:02 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
00:15 Phox [Phox@Nightstar-3e5deec3.gv.shawcable.net] has joined #code
00:18 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
00:19 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
00:22 You're now known as TheWatcher[T-2]
00:22
< Rhamphoryncus>
Well, it's not clear what you're reading/writing
00:23
< Rhamphoryncus>
Is *all* access to the pointer via atomic reads and writes and you're just using the mutex for the fence effect?
00:24 You're now known as TheWatcher[zZzZ]
00:26
< McMartin>
Typically, writes need to use mutexes to protect the list from each other, but not from readers.
00:27
< kwsn>
i hate WDTs sometims
00:27
< kwsn>
*sometimes
00:28
< Rhamphoryncus>
eh, that's not legal then. Just lucky that the current compiler implementation lets it work
00:30
< kwsn>
reader/writer problem?
00:30
< Namegduf>
Rhamphoryncus: Huh?
00:30
< Rhamphoryncus>
I'm really pedantic though
00:30
< Namegduf>
What's not legal?
00:31
< Namegduf>
Given that the Mutex is implemented through assembly instructions
00:31
< Rhamphoryncus>
A read is not atomic
00:31
< Namegduf>
Yes it is.
00:31
< Namegduf>
It uses both a mutex to protect itself from other writers and to create a memory fence so stuff picks up the write
00:31
< Rhamphoryncus>
It happens to be implemented that way, usually, but it's not defined as such
00:31
< Namegduf>
A "read" is not atomic, the *write* is
00:31
< Rhamphoryncus>
The read acquires a mutex first?
00:31
< Namegduf>
No
00:32
< Namegduf>
The write uses an atomic write instruction
00:32
< Namegduf>
Specifically, Compare-And-Swap
00:32
< Rhamphoryncus>
So the writer grabs a mutex, does an atomic write, releases mutex. The memory was updated sanely. However, the reader had no idea this was going on and may have done a partial read or any of various other insane things
00:32
< Namegduf>
No, it can't.
00:32
< Namegduf>
Because the write was atomic.
00:33
< Namegduf>
YOu can't half-read an atomic write operaiton
00:33
< Rhamphoryncus>
It happens, particularly on x86, that the most common read instruction also happens to be atomic
00:33
< Namegduf>
It happens that atomic operations are architecture-specific
00:34
< Namegduf>
So to talk about safety in general terms is nonsensical
00:34
< Namegduf>
On the architectures these atomic operations support and are used (x86 and x86_64, ARM I'm not sure has the full fence behaviour in its mutex implementation, I don't understand that one well), they guarantee that partial reads won't happen
00:35
< Namegduf>
"they" being the instructions used to implement them
00:35
< Rhamphoryncus>
The instruction is fine but there's no guarantee the compiler will produce exactly that
00:35
< Namegduf>
Uh
00:35
< Namegduf>
There is because it is *written in assembly*
00:35
< Namegduf>
The atomic write is written in assembly
00:36
< Namegduf>
And AFAIK there is no read instruction the compiler could possibly use that could violate it without using multiple read instructions, which is all kinds of stupid
00:36
< Rhamphoryncus>
It's C. It EXCELS at stupid.
00:36
< Rhamphoryncus>
I love strict aliasing rules :P
00:37
< Namegduf>
Actually, it's Go, but same difference
00:37 * Namegduf was writing a silly concurrent shared state heavy server
00:37
< Rhamphoryncus>
I have no idea about Go
00:38
< Namegduf>
It has very little by way of guarantees, similar to C
00:38
< Namegduf>
I suppose technically I could write a "read pointer" function in assembly
00:38
< Rhamphoryncus>
That's what I'm arguing
00:38
< Namegduf>
Which just did exactly what the compiler would sanely do anyway to read the pointer
00:38
< Rhamphoryncus>
yup
00:39
< Namegduf>
But seeing as I'm already leaning on the mutex implementation, I don't see going for implementation independence as useful
00:40
< Namegduf>
Not in the short term, anyway.
00:40
< Namegduf>
But okay, you pointed out something the compiler could do that was so stupid I hadn't thought of it; use multiple read instructions to read a pointer.
00:41
< Namegduf>
So there was another implementation detail I hadn't thought of being relied on there.
00:41
< Rhamphoryncus>
I'd do it just because it's the Right thing to do. Don't rely on compiler implementation when you don't have to. You'll never debug it if it fails.
00:43
< Rhamphoryncus>
It can actually do other really perverse things, like duplicate that line of code, read it once for a branch test, then read it again to actually use the value, which of course gets different results
00:43
< Rhamphoryncus>
Which'd give impossible behaviour
00:44
< Namegduf>
Hmm. In general it can't do that anyway.
00:44
< Namegduf>
I mean, branch based on values and actually assume them to be that within the branch.
00:44
< Namegduf>
Other code elsewhere is allowed to change state underneath it.
00:45
< Namegduf>
But okay, point taken.
00:46 Attilla [Some.Dude@Nightstar-f29f718d.cable.virginmedia.com] has quit [Ping timeout: 121 seconds]
00:48 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
00:48
< Rhamphoryncus>
On the contrary, the value can only change *if you call other code*. This is assume a series of primitive operations within a single function, or even a single file. Only calling a function in a separate file triggers the "anything can happen" behaviour that C has to protect itself from
00:48 Derakon[AFK] is now known as Derakon
00:48
< Namegduf>
Threading.
00:48
< Rhamphoryncus>
btw, link-time optimization is also possible and is done by clang :P
00:48
< Namegduf>
And yes, potentially any other file in the project
00:49
< Rhamphoryncus>
threading doesn't matter
00:49
< McMartin>
Not to interject on this flamewar
00:49
< Rhamphoryncus>
Mutexes are basically language extensions that behave similar to the "anything can happen". Often less than anything though, for performance reasons.
00:50
< Rhamphoryncus>
McMartin: I thought I was being rather polite about it
00:50
< McMartin>
But if you're doing atomic writes, it's via a function named atomic_write, that is explicitly standardized and that is required to be implemented in a way that is atomic.
00:50
< McMartin>
Bitching about having to trust the compiler here is like saying "I don't like to use printf because I have no guarantee that somebody's libc doesn't link _printf to _format_hard_drive"
00:51
< McMartin>
And, it's true! You don't!
00:51
< McMartin>
But that's their problem, not yours.
00:51
< Rhamphoryncus>
McMartin: atomic_write works just fine if and only if paired with atomic_read
00:52 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
00:53
< McMartin>
Also, mutexes aren't language extensions, they're libraries.
00:53
< McMartin>
So are lock-free atomic ops.
00:53
< McMartin>
So, for that matter, is floating point division.
00:53
< McMartin>
As a developer the only thing that matters is that the capability's there.
00:54
< Rhamphoryncus>
They're both. The memory model specified in C is insufficient so they inherently must rely on language extensions, even if implicit.
00:54
< Namegduf>
Or, you know, assembly
00:54
< McMartin>
Um
00:54
< Rhamphoryncus>
Assembly would be such an extension
00:54
< McMartin>
You seem to be confusing "extension" with "system call"
00:55
< Namegduf>
I'm not sure I'm willing to call "linking with a library which happens to be written in another language" an "extension"
00:55
< McMartin>
WaitOnSingleObject and pthread_mutex_lock are neither of them language extensions.
00:55
< Namegduf>
But nevermind, not worth it
00:55
< McMartin>
Also, my understanding for C is that if you're reading something the size of a system word it *is* atomic because this is what "size of a system word" means.
00:56
< Rhamphoryncus>
McMartin: see also: volatile sig_atomic_t
00:56
< Rhamphoryncus>
(which isn't strictly thread-safe either!)
00:57
< McMartin>
"strictly thread safe" does not mean "you can do whatever and it is consistent"
00:58
< Rhamphoryncus>
Sorry, I should have said it's completely irrelevant to thread-safe atomics :P
00:58
< McMartin>
(sig_atomic_t does not appear to be in my stdint.h, either)
00:59
< Rhamphoryncus>
Dunno what file it's in
00:59
< Namegduf>
"You can also assume that pointer types are atomic; that is very convenient. Both of these assumptions are true on all of the machines that the GNU C library supports and on all POSIX systems we know of."
00:59
< Rhamphoryncus>
It's for signal handlers though. It is safe for them.
00:59
< Namegduf>
http://www.gnu.org/s/hello/manual/libc/Atomic-Types.html
00:59
< Namegduf>
(On sig_atomic_t)
01:00
< Namegduf>
Apparently sig_atomic_t exists for being "safe" on all architectures, although everywhere it currently exists int and pointer are also safe anyway
01:00
< Rhamphoryncus>
That's their implementation
01:00
< McMartin>
It's true that the only examples I can come up with where they are not are in fact targetable by GNU C
01:00
< McMartin>
To wit: 16-bit DOS, and old macros with 8-bit ALUs but 16-bit address spaces
01:00
< McMartin>
Rhamphoryncus: I'm pretty sure we've had this discussion before, but...
01:01
< McMartin>
... you can't link against the standard.
01:01
< Rhamphoryncus>
Yeah, I think we did
01:01
< McMartin>
If something is true across the most common implementations, then the failure of other implementations to match is a bug in those other implementations.
01:01
< Rhamphoryncus>
We disagreed on what's a reasonable assumption to make
01:02
< Namegduf>
But hold on
01:02
< Namegduf>
If the C compiler is allowed to do multiple instruction reads
01:02
< Namegduf>
Then how can that "int and pointer is atomic on everything we support" thing be true? Is it only true of GCC?
01:02
< McMartin>
It's true of GCC, MSVC, icc, and the old Watcom 6.
01:03
< Rhamphoryncus>
Namegduf: can and does in other cases. GCC doesn't exist on all hardware.
01:03
< McMartin>
The failure mode, is basically, this:
01:03
< McMartin>
If pointers are larger than the size of your registers...
01:03
< Namegduf>
Yes, but given I have to write assembly for x86 and x86_64 anyway, I don't care about hardware
01:03
< Namegduf>
To add new hardware already requires additional assembly
01:03
< McMartin>
Then you load half the address, then there's an interrupt that changes the address, then you resume and load the other half.
01:04
< Namegduf>
For the atomic write ops.
01:04
< McMartin>
Any system that does this is intrinsically unthreadsafe for all operations.
01:04
< McMartin>
Unless it can ensure that thread switches only happen at defined points.
01:05
< Rhamphoryncus>
Or you need to use explicitly atomic ops when you need it
01:05
< McMartin>
Well, no.
01:05
< McMartin>
Because the operation is dereferencing a pointer, which is to say, any access to any variable that is not a global.
01:05
< McMartin>
If you put mutexes on those operations, one, those implementations can't use variables, and two, your performance will be entirely unacceptable.
01:06
< Rhamphoryncus>
what?
01:07
< McMartin>
A non-atomic read means that you are not guaranteed, when loading a value, that that value was ever written to that space, unless you wrap the reads with a mutex of some kind.
01:07
< McMartin>
These mutexes themselves can't be loaded as something to read, because you are not guaranteed, when loading a value, etc.
01:08
< Rhamphoryncus>
So if you have an array of pointers to structs and each struct contains a mutex for the rest of itself.. access to the array would have to have atomic reads/writes or be entirely wrapped in a mutex
01:08
< McMartin>
In sort, if you don't have atomic memory read you don't have multithreading capability at all, because making sure that data isn't corrupt requires a global system lock, which in turn means that you don't really get multithreading in any meaningful sense.
01:08
< McMartin>
No
01:08
< McMartin>
Because you can't get at the mutex safely
01:09
< Rhamphoryncus>
You mean a single global mutex for the array?
01:09
< McMartin>
You'd have to load it out of that struct, which requires the very operation you nede the mutex to protect.
01:09
< McMartin>
Yes, globals with fixed addresses are the only safe unprotected memory reads if you can't ensure that the read of an address is atomic.
01:09
< McMartin>
(Or, if we're being realistic, if you can't ensure that nobody else can write your pointer)
01:10
< McMartin>
(This being the solution for the old micros.)
01:10
< McMartin>
The global lock that controls all operations is what Python does, which is why there are five or six reimplementations of it that try to remove this restriction.
01:10
< Rhamphoryncus>
It has nothing to do with being a global with fixed address
01:11
< McMartin>
How exactly are you imagining non-atomic reads being unsafe?
01:11
< Rhamphoryncus>
It has everything to do with that memory being synchronized properly, such as the write being done before you spawn any threads
01:11
< McMartin>
That qualifies as "ensuring that nobody else can write your pointer".
01:12
< McMartin>
That doesn't let you carry it in a struct, though, because which struct you think you're reading can change mid-read.
01:13
< Rhamphoryncus>
I still don't understand what you mean
01:13
< McMartin>
The danger with nonatomic reads comes from compiling (*x)
01:13
< McMartin>
Which, in a modern system, compiles to "load address. load memory from address"
01:14
< McMartin>
Actually, no
01:14
< McMartin>
It compiles to "load address. load memory from address. load memory from result of step 2, which was an address".
01:14
< McMartin>
Assuming x is not a global.
01:15
< McMartin>
On 16-bit DOS with far pointers, it is "load address. load first half of x's address from that. modify first address. load second half of x's address from that. load memory from the combination of steps 2 and 4".
01:15
< McMartin>
Steps 2 and 4 are the ones that need to ensure no write happens between them, and you can't do that if you're a slave to the clock interrupt, which can change the address you're working off of.
01:16
< McMartin>
On such an architecture, synchronization is literally impossible and the best you can do is drop a hammer on it by refusing to permit huge classes of writes under any circumstances at all, because there is no such thing as 'wait until it's safe'.
01:17
< Rhamphoryncus>
You're worried that the address of x will change? The value of x will change? What?
01:17
< McMartin>
That the value of x - and thus, the address that you are dereferencing - will be changed by some other thread, yes.
01:18
< McMartin>
If pointer size is the same as atomic-read size, you are guaranteed that under all possible interleavings, you get either the first value of x, or the second value of x.
01:18
< McMartin>
I should say atomic-access, here.
01:19
< Namegduf>
Wasn't the complaint more about compilers doing stupid stuff like multiple reads of the same value to a single reference in source code?
01:19
< McMartin>
If, for whatever reason, reads can atomically access more than writes, you could take the value of x to read halfway through the update of x, which would produce an equally invalid address.
01:19
< Rhamphoryncus>
You have to use another mutex to protect access to x itself, yes. That's exactly the model that pthreads presents
01:19
< McMartin>
Yes, but that mutex is itself represented by a pointer you have to reference. There is an infinite regress here.
01:20
< Rhamphoryncus>
No, because you're not changing that one arbitrarily
01:20
< McMartin>
And you have to lock any access to anything, which hard-seralizes your code and means that the code would be faster single-threaded.
01:20
< McMartin>
Your whole point is that you can't trust that to be the case.
01:21
< Rhamphoryncus>
There certainly are cases that perform vastly better with atomic reads/writes rather than mutexes, but they're not nearly as prevalent as you suggest
01:24
< Rhamphoryncus>
(prevalent enough. That's why nobody is satisfied with just mutexes.)
01:25
< Namegduf>
Are we talking "just the platforms it's possible to build GCC on", then?
01:25
< Namegduf>
:P
01:26
< Rhamphoryncus>
eh?
01:48
< McMartin>
It's true that unless there are some specific subsets of machine instructions available, multithreading is impractical.
01:48
< McMartin>
If you don't at least have test-and-set or compare-and-swap you're just screwed from the word go.
01:49
< Rhamphoryncus>
to implement a mutex you mean?
01:50
< McMartin>
Or a semaphore, or something, yes.
01:53
< Rhamphoryncus>
some reading, if you're still interested: http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/
01:54
< McMartin>
Ah, good, they did standardize the atomic ops this time.
01:54
< Rhamphoryncus>
But the language specs specifically allow for hardware without pointer sized atomic stores
01:55
< Rhamphoryncus>
I think we're coming from different worlds here
01:56
< McMartin>
Sort of.
01:57
< McMartin>
You mention pointer-sized atomic stores, which are still legion but Bad Ideas for anything serious - I can't think of any that, if I were to target them, would not be with for-all-practical-purposes single-threaded code
01:57
< McMartin>
It's the lack of pointer-sized atomic *loads* that is what I've been claiming makes you lose at everything forever.
01:57
< McMartin>
... in a multithreaded world.
01:58
< McMartin>
I'm not positive, but I *think* that ARM-THUMB would qualify there, and I know GCC can target it because I've done so.
01:58
< Rhamphoryncus>
I'm not very confident about that comment in that sig_atomic_t docs btw :P
01:59
< Rhamphoryncus>
It's a huge statement to make and it's done casually, buried somewhere.
02:00 * McMartin also notes that his ARM-THUMB programming was indeed All Singlethreaded All The Time.
02:00
< McMartin>
If you're writing multithreaded code targeting the GBA you're doing something terribly wrong.
02:00
< Rhamphoryncus>
heh
02:01
< Rhamphoryncus>
My world is one of a language designer, trying to understand how it fully works
02:02
< Rhamphoryncus>
And for threads.. every question comes back with 6 more questions
02:02
< McMartin>
Right, I'm more on the "compiler implementor" and "application developer" side.
02:03
< McMartin>
For the former - what's compliant, and what will produce programs people will want to run as oppose to using some other dev system
02:03
< McMartin>
For the latter - people need to be able to use the end products.
02:04 celmin|away is now known as celticminstrel
02:04
< Namegduf>
Well, I just remembered that I originally did it the way I did because one of the authors of Go wrote that they could fix various multiword structures being possible to corrupt by basically making pointers point to them, because pointers couldn't have partial reads. I hadn't realised that that was implicitly dependent on the rest of the current implementation and the current hardware when talking about it, technically speaking.
02:05 * Rhamphoryncus nods
02:05
< Namegduf>
(The language is otherwise "safe"; it is impossible to derive a bad address/reference. They solved this for App Engine by barring multiple threads)
02:06 * McMartin is pretty sure that allowing partial reads normally means you find whoever designed the architecture and hit them with sticks until they stop.
02:06
< McMartin>
Even ARM THUMB has a mode where they are~
02:06
< Namegduf>
Ditto if the compiler emits multiple read instructions for a single reference in the source code?
02:07
< Namegduf>
(Except to be fair, not cruel, you should probably go after the compiler author there)
02:07
< McMartin>
Depends on the construct.
02:07
< Rhamphoryncus>
Namegduf: nope, there's cases where it's justified
02:07
< Rhamphoryncus>
spurious stores exist too
02:07
< McMartin>
There are cases where it's mandatory.
02:07
< Namegduf>
Hmm.
02:07
< McMartin>
(hi, cpp, can you die yet? please?)
02:07
< Namegduf>
I doubt it's compulsory to ever actually assemble a value out of two halves of a smaller read
02:07
< McMartin>
That, no.
02:07
< Rhamphoryncus>
For instance a loop that updates on every iteration, but what happens if you have a count of 0? Well the compiler may have hoisted the store out of the loop
02:08
< McMartin>
But multiple reads from a single point of code is mandatory if call-by-name semantics are in the language.
02:08
< McMartin>
Rhamphoryncus: Spurious store? That's unsafe.
02:08
< McMartin>
Spurious load is safe.
02:08
< Namegduf>
Can they be beaten with sticks for generating partial rather than inconsistent reads?
02:08
< McMartin>
Mmm.
02:08
< Namegduf>
(i.e. doing that gluing-together thing)
02:09
< McMartin>
Well
02:09
< McMartin>
If you're passing a complex datatype by value, that's basically how you do it
02:09
< McMartin>
Since those can be arbitrarily large, at *some* point it becomes a memcpy
02:09
< Rhamphoryncus>
spurious load is almost always safe. There's cases where it can blow up
02:09
< Namegduf>
This is for a pointer
02:09
< McMartin>
Oh
02:09
< McMartin>
The only cases I can think of for that are cases where the instruction set mandates it.
02:09
< Namegduf>
My original statement was overly broad, sorry. XD
02:09
< McMartin>
See: 16-bit x86.
02:09
< Rhamphoryncus>
I believe C++0x prohibits that kind of loop optimization for that reason
02:10
< McMartin>
Rhamphoryncus: Well, yes, if the pointer is invalid >_>
02:10
< McMartin>
(a far pointer in x86 is 32 bits wide, but you can only load 16 bits at at ime.)
02:10
< Rhamphoryncus>
I was thinking off the end of an array that goes to a different page.. or a float value that's invalid and traps..
02:10 Derakon is now known as Derakon[AFK]
02:10
< McMartin>
(They fixed this, eventually, in the 80386 with its flat memory model mode - this is also why the 386 is the first *truly* 32-bit x86)
02:13 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
02:14 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
02:40 Kindamoody[zZz] is now known as Kindamoody
02:43 Rhamphoryncus [rhamph@Nightstar-14eb6405.abhsia.telus.net] has quit [Client exited]
03:08 Reivles [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
03:09 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
03:18 Reivles [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
03:19 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
03:55 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
04:00 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
04:10 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
04:11 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
04:34 Vash [Vash@Nightstar-f03c5637.sd.cox.net] has joined #code
05:06 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
05:07 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
05:08 Stalker [Z@Nightstar-3602cf5a.cust.comxnet.dk] has quit [Ping timeout: 121 seconds]
05:19 Vornotron is now known as Vornicus
05:19 mode/#code [+qo Vornicus Vornicus] by ChanServ
05:23 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Connection reset by peer]
05:23 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
05:27 Vash [Vash@Nightstar-f03c5637.sd.cox.net] has quit [[NS] Quit: I <3Lovecraft<3 Vorn!]
05:32 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
05:33 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
05:37 kwsn [kwsn@Nightstar-635d16fc.org] has quit [Ping timeout: 121 seconds]
05:41 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
05:47 kwsn [kwsn@Nightstar-635d16fc.org] has joined #code
05:47 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
06:44 You're now known as TheWatcher
07:03 Janus [NSwebIRC@Nightstar-cc84f6e9.res.rr.com] has joined #code
07:04 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
07:04 * Janus almost has it. ... sort of anyway. http://dl.dropbox.com/u/3108480/notquitebutalmost.png
07:09 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
07:15 Derakon[AFK] is now known as Derakon
07:17<~Vornicus> Yeah that's... not quite it.
07:22
< Janus>
... mmf! Got it! http://dl.dropbox.com/u/3108480/Okayherewego.png
07:24<~Vornicus> Glorious, but why are you splitting lines?
07:26
< Janus>
They're artifacts between the triangle strips they're decomposed to, and the convex polygon rebuilder. ... I guess that's next on the list of things to fix
07:27
< Janus>
I'm just glad it does that much at this point though. So many days sunk into it, whewww
07:30
< Janus>
... at least I think that's why. Ummm! Wish I could make it stop segfaulting every other time, so I could show you the .exe
07:31
< celticminstrel>
Oh, it's you again.
07:31
< celticminstrel>
Interesting filenames. :P
07:34
< Janus>
http://dl.dropbox.com/u/3108480/itworksitworksitworkswhoohoooooo.png
07:35<~Vornicus> that doesn't look very worky
07:35
< Janus>
10 minutes ago, any time I tried to do that, it'd instantly fill the screen with pancakes
07:36
< celticminstrel>
XD
07:36
< Janus>
... on second thought, this is a de-provement.
07:37 celticminstrel [celticminst@Nightstar-5d22ab1d.cable.rogers.com] has quit [Connection closed]
07:43 Derakon is now known as Derakon[AFK]
07:45 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
07:50 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
07:51 You're now known as TheWatcher[afk]
08:02 Attilla [Some.Dude@Nightstar-f29f718d.cable.virginmedia.com] has joined #code
08:29 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
08:42 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
08:49 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
08:54 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
09:02 Attilla [Some.Dude@Nightstar-f29f718d.cable.virginmedia.com] has quit [Ping timeout: 121 seconds]
09:09
< Janus>
I got a non-crashing .exe if you'd like to see Vorn! ... well. Non-crashing in the sense that there's no segfaulting I think
09:11 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
09:16<~Vornicus> I'd prefer source~
09:23
< Janus>
Oh god. If you seen the source, you'd pants me and drag me around the track
09:24<~Vornicus> Probably, but that's why you should be prepared to reveal the source
09:24<~Vornicus> So that you learn how not to get pantsed.
09:25 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
09:27
< Janus>
It's pretty much the entire project. Plus... all the libraries. ALL the libraries too. Maybe... the function itself will provide enough shame. http://pastebin.starforge.co.uk/483
09:30<~Vornicus> holy shit dude refactor
09:33 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
09:33
< Janus>
I kind of... get carried away whenever I do these function bodies. I guess all the stuff causing problems would surface if I did that, huh
09:33<~Vornicus> Yes.
09:33<~Vornicus> The less that is going on in any individual function, the less trouble you'll have figuring out what is going /wrong/.
09:37 Vornicus is now known as Vornicus-Latens
09:37<~Vornicus-Latens> I can have a look later but I suspect my response will be "let me see what I can write for this" and then that will be that.
09:39
< Janus>
Okay. Though to be honest, I was just in a hurry to see how it might sort of look by it's end. Which... isn't as impressive as I thought. I might wanna do something totally different/non-extremely-obtuse/hard
09:39
< Janus>
Thanks for lookin!
09:43 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
09:57 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
09:57 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
10:14 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
10:22 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
10:23
< cpux>
Better than my method of 'Your code is stupid.'
10:26 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
10:29 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
10:31 Reivles [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
10:33 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
10:50 gnolam [lenin@Nightstar-202a5047.priv.bahnhof.se] has joined #code
11:03 AnnoDomini [annodomini@FFB3F3.4C5BE8.2014E2.DC0864] has joined #code
11:28 Reivles [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
11:33 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
11:39 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
11:45 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
11:55 Rhamphoryncus [rhamph@Nightstar-14eb6405.abhsia.telus.net] has joined #code
12:19 cpux [cpux@Nightstar-c5874a39.dyn.optonline.net] has quit [Client closed the connection]
12:59 Kindamoody is now known as Kindamoody|out
13:00 Stalker [Z@Nightstar-3602cf5a.cust.comxnet.dk] has joined #code
13:03 AnnoDomini [annodomini@FFB3F3.4C5BE8.2014E2.DC0864] has quit [[NS] Quit: I'm off!]
15:09 Attilla [Some.Dude@Nightstar-f29f718d.cable.virginmedia.com] has joined #code
15:12 You're now known as TheWatcher
15:20 ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has quit [Operation timed out]
15:24 ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has joined #code
16:44 Derakon[AFK] is now known as Derakon
17:05 * Derakon quietly amuseds at the name he came up with for a project he probably won't take on.
17:05
< Derakon>
pyrl
17:05
< Derakon>
A.k.a. Python Roguelike.
17:10
< Tarinaky>
The lambda function bit you.
17:11
< Derakon>
Mostly the amusement comes from the name conflict with perl.
17:16
< gnolam>
http://media.zenfs.com/en_us/News/ucomics.com/bor111014.gif
17:20 cpux [cpux@Nightstar-c5874a39.dyn.optonline.net] has joined #code
17:35 Stalker [Z@Nightstar-3602cf5a.cust.comxnet.dk] has quit [Client closed the connection]
17:49 celticminstrel [celticminstre@Nightstar-5d22ab1d.cable.rogers.com] has joined #code
18:30 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
18:32 Reivles [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
19:11 Reivles [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
19:12 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
19:13 Kindamoody|out is now known as Kindamoody
19:43 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
19:44 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
19:46 Vornicus-Latens is now known as Vornicus
20:29 Kindamoody is now known as Kindamoody[zZz]
20:38 Rhamphoryncus [rhamph@Nightstar-14eb6405.abhsia.telus.net] has quit [Client exited]
21:04 Janus [NSwebIRC@Nightstar-cc84f6e9.res.rr.com] has quit [[NS] Quit: okag slep fime ]
21:50 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
21:51 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
22:14 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
22:18 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
22:48 Stalker [Z@Nightstar-5aa18eaf.balk.dk] has joined #code
22:56 You're now known as TheWatcher[T-2]
23:04 You're now known as TheWatcher[zZzZ]
23:41
< gnolam>
"To the police surveillance van outside our flat, renaming your wifi would make you stealthier http://pic.twitter.com/PjzcSX2v"
23:41
< gnolam>
http://twitter.com/matclayton/status/124932160493850624
23:48
< Namegduf>
XD
23:53 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has quit [Ping timeout: 121 seconds]
23:54 Reiver [orthianz@3CF3A5.E1CD01.C6689C.33956A] has joined #code
--- Log closed Sun Oct 16 00:00:28 2011
code logs -> 2011 -> Sat, 15 Oct 2011< code.20111014.log - code.20111016.log >

[ Latest log file ]