Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

rjmccall posted:

Creating a new kernel-scheduled thread is actually a really expensive operation on almost every established operating system, but IIRC that's especially true on Windows.

I miss BeOS, where creating threads was so cheap that the general rule of thumb was, "when in doubt, spawn another thread." :eng99:

Adbot
ADBOT LOVES YOU

feedmegin
Jul 30, 2008

rjmccall posted:

Creating a new kernel-scheduled thread is actually a really expensive operation on almost every established operating system, but IIRC that's especially true on Windows. This is why people tend to recommend offloading work onto a thread pool instead of creating a new thread. There are definitely languages/environments with really cheap threads, but they use M-to-N threading, and they overwhelmingly tend to not be C environments.

Hmm. This does raise the question of why M:N schedulers for Posix threads have not generally been as successful/performant as modern Linux's 1:1 threading. I know it was tried for Linux too before the current approach won out..what about other languages makes that easier?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
The Linux story in particular is pretty complex, and there are both technological and social reasons why the latest efforts have been more successful beyond just the inherent difficulties of M:N threading in C. But there are some inherent difficulties with user-land threads, which basically all come down to three things:

1. The POSIX C environment does make some threading guarantees and operations that your threads library has to provide. This means things like thread-local variables, pthread_setspecific, pthread_self, and so on, each of which may increase the overhead of your library beyond what a language with fewer operations and guarantees might need.

2. C is not traditionally a managed environment in the sense of limiting what operations you can perform directly.

A user-land threads library needs to be very careful about anything that might tie up a thread, because you don't want to stop running user threads just because M of them happen to be performing blocking syscalls. Generally this means that you need to intercept everything that might block and either (a) ideally do something behind the scenes that doesn't block the actual kernel thread or (b) at least spin up a new kernel thread to schedule things on while the other is blocked. If you miss anything, you can get terrible performance or potentially even deadlock if the blocking operation is waiting for something to happen on some runnable-but-unscheduled user thread. All of this is easier in a managed environment which tightly limits its interactions with the rest of the system, because you just make sure those points are more careful about blocking. In C, that's the entire program, most of which is evolving without any regard for you. Any blocking syscall or lock implementation that you don't know about is a major catastrophe waiting to happen.

3. C is not traditionally a managed environment in the sense of instrumenting anything about the code. There are expectations about how code is compiled in C that can really complicate / pessimize a user threads library.

For example, you can't really grow a C stack: you can't relocate it because there might be outstanding references to objects on the old stack, and you can't allocate more memory because functions aren't normally compiled in ways that detect overflow or permit the dynamic "chaining" of stacks. Instead, the library has to allocate a fixed amount of address space to the stack, and at least a page of that has to actually be mapped, and you can't put multiple threads on that page unless you're seriously giving each of them a max of less than a page of stack, which is not even slightly reasonable for a general purpose C thread. More realistically, you're looking at reserving a few hundred KB of address space per user thread, which is not something that scales to tens of thousands of threads (especially in the 32-bit era) even if most of it isn't actually mapped.

For another, C compilers don't normally insert random calls to the threading library on every function entry or back-edge, which means that code can just tie up a kernel thread forever if you don't do anything to stop it. But you can't necessarily just pre-empt another user thread from the library the way a kernel can, so you're stuck with things like sending yourself a periodic signal or running a separate manager thread to detect "greedy" threads and maybe spin up another kernel thread to keep things running. Without that, simple things like spin locks can easily deadlock the program by starving the threads that actually hold the spin lock; even with it, you can get really, really bad performance.

rjmccall fucked around with this message at 02:04 on May 14, 2016

Cory Parsnipson
Nov 15, 2015
Does anyone have tips/best practices/reading for converting a project of non-trivial size from using raw pointers to using smart pointers? I want to see if I can introduce smart pointers module by module or something into an existing project that only uses raw pointers, but that seems like I could shoot myself in the foot that way.

Xarn
Jun 26, 2015

Cory Parsnipson posted:

Does anyone have tips/best practices/reading for converting a project of non-trivial size from using raw pointers to using smart pointers? I want to see if I can introduce smart pointers module by module or something into an existing project that only uses raw pointers, but that seems like I could shoot myself in the foot that way.

When we tried it, we started using smart pointer everywhere in new code and slowly changed the old code as we did refactoring. It mostly worked, although there was some initial pain as noone actually understood the old ownership model, so suddenly there were double free etc.

Cory Parsnipson
Nov 15, 2015
Yeah that's what I'm afraid of. Eh I guess I'll just do it and see what happens. Thanks!

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
For most projects, the amount of code that manipulates ownership should be vastly smaller than the amount of code which just accesses data, and the latter shouldn't actually need to be changed.

Chuu
Sep 11, 2004

Grimey Drawer
Is there any trick that will let me detect, in code, when new members have been defined in an enum class?

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

Chuu posted:

Is there any trick that will let me detect, in code, when new members have been defined in an enum class?

Not sure how enum classes differ from regular enums, since I don't do any new C++,
but for a regular enum, I have a switch block with cases for all the enum values that I handle.

When compiling with -Werror=switch it becomes a compile error if a new value has been added to the enum that hasn't been handled.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Edison was a dick posted:

Not sure how enum classes differ from regular enums, since I don't do any new C++,
but for a regular enum, I have a switch block with cases for all the enum values that I handle.

When compiling with -Werror=switch it becomes a compile error if a new value has been added to the enum that hasn't been handled.
Enum classes are strongly typed enums (i.e. no implicit conversion to/from int) with scoped names. They're pretty neat but basically the same thing, and your advice applies. Always have your tools set up to notify you about incomplete switch case coverage.

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

Chuu posted:

Is there any trick that will let me detect, in code, when new members have been defined in an enum class?

At runtime (I.e. between modules) or compile time?

Chuu
Sep 11, 2004

Grimey Drawer

Hubis posted:

At runtime (I.e. between modules) or compile time?

Either is fine, compile time strongly preferred.

-Werror is something else I can't enable for really stupid reasons outside of my control.

(I'd settle for a CMake hack if this really isn't possible in code.)

Chuu fucked around with this message at 08:33 on May 22, 2016

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Chuu posted:

Either is fine, compile time strongly preferred.

-Werror is something else I can't enable for really stupid reasons outside of my control.

(I'd settle for a CMake hack if this really isn't possible in code.)

Can you not set up Werror locally? I'd probably do that and then blame the changes..

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

Chuu posted:

Either is fine, compile time strongly preferred.

-Werror is something else I can't enable for really stupid reasons outside of my control.

(I'd settle for a CMake hack if this really isn't possible in code.)

Well, you could add a "COUNT" value at the end of the enum, then do a static_assert to ensure the enum::COUNT equals whatever number you expect elsewhere in the code.

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Hubis posted:

Well, you could add a "COUNT" value at the end of the enum, then do a static_assert to ensure the enum::COUNT equals whatever number you expect elsewhere in the code.

Doesn't catch people dumping things into the enum past count, which seems like the likely place to dump new things into an enum.

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

leper khan posted:

Doesn't catch people dumping things into the enum past count, which seems like the likely place to dump new things into an enum.

Not if you structure/comment it reasonably/people are not complete loving idiots. I mean, it doesn't stop people from commenting out the static_assert with the commit message "fixed build error" either v:shobon:v

Klades
Sep 8, 2011

Hubis posted:

people are not complete loving idiots.

When you find a place where you don't have to worry about this one make sure to let the rest of us know.

Doc Block
Apr 15, 2003
Fun Shoe
Try naming it LAST_VALUE or something so at least people don't have an excuse for adding things after it?

Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

Klades posted:

When you find a place where you don't have to worry about this one make sure to let the rest of us know.

It helps that this is part of our coding standards / appears everywhere, so you have to be pretty intentionally oblivious to screw that particular thing up. Doesn't mean it can't happen, but at least when it does cause problems it's easy to identify so you can find the right person to smack.

Of course, there is no good reason C++ couldn't do something sane like adding introspection to enums so "count" was an automatic value (and hey support for cool things like reverse string name lookups!) but I guess they are too busy adding a 2d graphics API to the standard library or whatever.

Doc Block
Apr 15, 2003
Fun Shoe
Are they really? LMFAO

Dren
Jan 5, 2001

Pillbug

Hubis posted:

Of course, there is no good reason C++ couldn't do something sane like adding introspection to enums so "count" was an automatic value (and hey support for cool things like reverse string name lookups!)

this would be so so great

+1 if the string names are optionally user definable

b0lt
Apr 29, 2005

Hubis posted:

Of course, there is no good reason C++ couldn't do something sane like adding introspection to enums so "count" was an automatic value (and hey support for cool things like reverse string name lookups!) but I guess they are too busy adding a 2d graphics API to the standard library or whatever.

It would be hard to make this useful and maintain ABI compatibility when adding elements to enums.

Spatial
Nov 15, 2007

There doesn't need to be an ABI. Having the info available at compile time gets you 99% of the way there - it's the never-ending maintenance and boilerplate that has to go. Given the ability to iterate over the name-value pairs, every other feature you could possibly want is easy and more importantly, self-maintaining.

With features like this C++ could soon launch into the bright future of 1991!

Sex Bumbo
Aug 14, 2004
I don't think I've ever had anyone ever bungle a COUNT enum thing at the end of the enum definition. But yeah I don't get why it isn't just a language feature. If you're ever using an enum definition, you necessarily know exactly how many names exist because you can look at it, otherwise your code wouldn't compile. I guess it might be ambiguous if there's names mapping to the same value but that doesn't seem particularly hard to solve.

Same goes for string names -- you can do macro nonsense to auto generate a string lookup table alongside the enums, but why can't the language auto-generate it? Something linked in will have problems if you rearrange your enum names already.


Doc Block posted:

Are they really? LMFAO

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4073.pdf
it's not funny it's sad

Sex Bumbo fucked around with this message at 19:36 on May 23, 2016

Qwertycoatl
Dec 31, 2008


I like the bit where they made it by taking a library in C and renaming all the foo(bar) to bar->foo()

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Doc Block posted:

Are they really? LMFAO

It's basically just Herb Sutter's pet project that everyone else just rolls their eyes at, but being the head of the committee means your dumb pet projects get a lot more attention than they deserve.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
Static reflection proposals inevitably get bogged down in that it's easy to come up with something that works well for one specific case, but no one wants five dramatically different static reflection systems for each type of things you might want to reflect on, and coming up with a comprehensive propsal is a shitload of work that only cranks have done so far (there was an amazing proposal to basically embed Angular in C++).

SG 7 (the reflection one) finally actually met and decided on a road forward at the last meeting, so maybe it'll actually eventually happen.

csammis
Aug 26, 2003

Mental Institution

Plorkyeran posted:

SG 7 (the reflection one) finally actually met and decided on a road forward at the last meeting, so maybe it'll actually eventually happen.

This is second hand (I changed jobs so I'm no longer getting sent to the committee meetings) but a colleague told me that this was the proposal that they're going to use: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0194r0.pdf

It doesn't have anything helpful for Chuu's case at this stage but it looks to me like a good starting point at least. The authors wrote a follow-up recently.

Sex Bumbo
Aug 14, 2004
Maybe we should just be thankful we have sizeof.

That Turkey Story
Mar 30, 2003

Hubis posted:

Of course, there is no good reason C++ couldn't do something sane like adding introspection to enums so "count" was an automatic value (and hey support for cool things like reverse string name lookups!) but I guess they are too busy adding a 2d graphics API to the standard library or whatever.

A lot of people complain about what the committee does and doesn't do, but it's really the C++ community's responsibility to participate. That some people put work into bringing a graphics API to the standard library does not mean that the committee is focused on that. I don't know anyone who is participating in that effort. There is, however, an active Reflection group which will likely cover enum introspection, although none of that work is slated for C++17 and is still very early on. If you care enough, write a proposal and show up to a meeting to present it (or find someone online to champion it at a meeting). It costs nothing to do this, and a simple paper like that doesn't take much effort to put together. A lot of the meetings are in the US if that's where you're from. There is a meeting in Washington in the fall.

feedmegin
Jul 30, 2008

Qwertycoatl posted:

I like the bit where they made it by taking a library in C and renaming all the foo(bar) to bar->foo()

I like how it punts entirely on event handling (for now, they say, but we know how fast standards move). If I understand correctly, you can't even use this to redraw things when your window gets resized. :wtc:

nielsm
Jun 1, 2009



feedmegin posted:

I like how it punts entirely on event handling (for now, they say, but we know how fast standards move). If I understand correctly, you can't even use this to redraw things when your window gets resized. :wtc:

What window? Cairo has never really been concerned with any UI or interaction aspects of what you draw, it's just a way of drawing on surfaces obtained in mysterious ways. Similar to how OpenGL doesn't actually specify how you get a drawable surface, that's up to implementation-specific APIs.
I believe the intention is that whatever UI library you use would give you surface objects back, which you can then draw on using the standard drawing API, but if you want to react to UI-related changes (like window with surface resizing, mouse clicking somewhere etc.) that's something you have to handle with the UI library.

Besides, who says you're even drawing to a screen surface at all?

feedmegin
Jul 30, 2008

nielsm posted:

What window? Cairo has never really been concerned with any UI or interaction aspects of what you draw, it's just a way of drawing on surfaces obtained in mysterious ways. Similar to how OpenGL doesn't actually specify how you get a drawable surface, that's up to implementation-specific APIs.
I believe the intention is that whatever UI library you use would give you surface objects back, which you can then draw on using the standard drawing API, but if you want to react to UI-related changes (like window with surface resizing, mouse clicking somewhere etc.) that's something you have to handle with the UI library.

Besides, who says you're even drawing to a screen surface at all?

If you have to use platform-specific stuff to do literally anything useful at all, what's the point of standardising just part of the whole process? If you're using a UI library like Qt or whatever then you can just use Qt, after all.

nielsm
Jun 1, 2009



feedmegin posted:

If you have to use platform-specific stuff to do literally anything useful at all, what's the point of standardising just part of the whole process? If you're using a UI library like Qt or whatever then you can just use Qt, after all.

Not every program that draws things has to be interactive. One potential use case would be scientific applications that need to generate visualizations from datasets, and output that to graphics files.

But yes I agree, it is a rather odd thing to put into the standard library.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

You might not be interacting with UI meaningfully at all, just (or primarily) producing images.

nielsm
Jun 1, 2009



One thing I used cairo for in the past was a plugin for AviSynth that let you write Lua scripts to draw overlays on the video, as a sort of really over-complicated subtitle specification tool. As one example of using a 2D graphics library for things that are non-interactive.

feedmegin
Jul 30, 2008

Subjunctive posted:

You might not be interacting with UI meaningfully at all, just (or primarily) producing images.

Producing images into what, though? There's nothing in there that says 'make me a GIF', for example. I don't think I even saw something that said 'make me a fixed size window on the desktop of size x times y' (and what x times y do you pick with no way of knowing the desktop resolution). 'Just producing images' is a really, really niche thing for something that's intended to go into the standard library; there's a reason GUI libraries normally involve a whole lot more than that.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

feedmegin posted:

Producing images into what, though? There's nothing in there that says 'make me a GIF', for example.

GIF libraries (and PNG, and video) produce and consume pixel buffers, not drawing commands. (I would much rather draw complex images with cairo and feed them into Qt than try to draw them with Qt's facilities.)

Xerophyte
Mar 17, 2008

This space intentionally left blank

feedmegin posted:

Producing images into what, though? There's nothing in there that says 'make me a GIF', for example. I don't think I even saw something that said 'make me a fixed size window on the desktop of size x times y' (and what x times y do you pick with no way of knowing the desktop resolution). 'Just producing images' is a really, really niche thing for something that's intended to go into the standard library; there's a reason GUI libraries normally involve a whole lot more than that.

Regardless of how good an idea you think this is, "2D image" includes a lot less bagage than "window" or "JPG". It makes some sense that if there's 2d graphics in the standard library then it will be agnostic to both specific UI concepts and file formats since very few assumptions can be made about either.

Personally I've used the Haskell bindings of Cairo to implement a turtle graphics/logo interpreter. Sure, I also had separate libraries for taking my pixel buffer and outputting it to my application window or a file format on disk, but it's pretty useful to be able to generate the pixel buffer without any specific use in mind.

I'm not saying it's the most critical feature I can imagine but if Herb Sutter wants to make a reasonable 2d graphics library for the standard library then more power to him. It'll probably see more use than the irregular modified cylindrical Bessel functions.

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



If nothing else, a 2D graphics API in the standard will give a standardized interface for raster graphics buffers, which could be a useful intermediary between other, more specialized libraries.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply