Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Den 23-10-2012 06:50, d3fault skrev: OT'ish (relative to above): someone mentioned in reply to me that implementing QThread's run() method is needed for the pure computation use case. This is simply not true, please stop spreading misinformation. Now I'm getting annoyed. You're the one spreading misinformation here. I mentioned the pure computation as one of the cases where I prefer subclassing. But that of course doesn't mean you can't do it in other ways. I even mentioned that I think subclassing is an inferior way most of the times, but that didn't sink in with you. The point you just refuse to accept is that there are multiple ways to use QThread and each of them has their strengths and weaknesses. I've tried to help you understand some of the reasons you can have for choosing other ways, but you just can't accept any new information. Bo Thorsen. Come by my DevDays talk in Berlin - Designing for testability. Learn how to build and run your unit tests with the Qt application. Fionia Software - Qt experts for hire. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Exception during ASCII cast on windows
Hello again, there was an object constructed which called an external library which made poorly std::string currentPath=getenv(PWD) ... Of course under cygin, PWD is defined while it is not under windows termninal. Sorry for the noise. 2012/10/22 Frédéric Martinsons frederic.martins...@gmail.com Hello, I've an application which runs nicely on linux (Qt 4.7.3 gcc 4.1.2 32 bits) and I want it to run on windows XP 32 bits. So I've been built it inside eclipse (not my choice, it is part of a bigger C++ project), everything was fine until I want to execute it. It crashed poorly giving me the following exception: terminate called after throwing an instance of std::logic_error what() : basic_string::_S_construct NULL not valid. I've checked that all of my char* are not NULL before casting them into QString. Anyway running into debugger tells me it's the following line which seems to be the culprit: CommandLinkPOS2::CommandLinkPOS2(const QString serverName,unsigned short port) : CommandLink(QString(POS2_CMD),serverName,port) And especially in qtring.h at line : inline QT_ASCII_CAST_WARN_CONSTRUCTOR QString(const char *ch) : d(fromAscii_helper(ch) The parent constructor is called well but it seems the exception is launched after it (the POS2_CMD symbols is #define POS2_CMD POS2). The build on windows is done against Qt 4.7.3 with mingw 5.1.8 (gcc 4.5.2). The gcc version is newer than the one used on linux, but I'd not expected such problem. There is one more strange behaviour. The executable produced runs as expected under a cygwin environment but it launches an exception under cmd.exe or if I double click it. Have you any clue of what is going on here. Any hint would be greatly appreciate because I'm stuck. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Hi, On Monday 22 October 2012 22:44:05 Till Oliver Knoll wrote: Am 22.10.2012 um 16:07 schrieb Jan Kundrát j...@flaska.net: On 10/22/12 14:12, Till Oliver Knoll wrote: So the net effect is that the worker thread does one loop too much - but /eventually/ it will see that m_continue has been set to 'false' and will terminate. And that is exactly what we want and hence good enough (no need for protecting the member m_continue with a mutex!). Hi Till, you don't need a mutex, but you need a guarantee that the compiler will recognize that you use that variable for inter-thread synchronization. Off course I had only single CPU / multicore with synchronised caches in mind (*cough* *cough*). Volatile does not do that. Seriously, I thought volatile would at least force the CPU to always read it from (the CPU's own) memory instead of any cache/register? So the problem would only occur if you really had multiple CPUs with dedicated RAM per CPU, no? Right, on machines with only one CPU the problem doesn't exist. On machines with mulitple CPUs, the problem is always existant, as every CPU has a cache. Qt's QAtomicInt or C++11's std::atomic_bool or std::atomic_flag will work fine. So I understand you basically have to explicitly tell the CPU to fetch and sync the data from RAM by means of aquire and releasing memory, so it would also work on real multi-CPU systems (and dedicated RAM per CPU - but since you say the CPU might also cache the data regardless of volatile, I assume you also need to sync memory in the shared RAM case). However my actual question is: wouldn't that be also the case for /any/ data structure I share between threads? So besides making sure that only one thread modifies the data (by a mutex) I would *also* have to make sure that (possibly) cached instances (in the other CPUs) get invalidated? Correct, aquire and release semantics are always needed when sharing data structures between multiple threads. QMutex internally uses aquire and release semantics, so as soon as you use QMutex to protect your data structures, that takes care or memory barriers. Basically, calling QMutex::lock() will do an aquire, and QMutex::unlock() a release. This will affect all memory, not just the memory locations protected by the mutex (after all, the CPU has no way to know which variables you're using the mutex for). Or in other words: wouldn't there be a need for QAtomicString, QAtomicWhatever and any struct or pointer I could think of? No, no need to use the QAtomic classes when your data is already protected by a mutex. For the original use case here (boolean flag as the only shared variable), using QAtomic is of course faster than using a full-blown mutex. However I dare to put the following statement: As long as you only consider Intel Desktop-like CPUs with *shared RAM, even if you have multiple CPUs (not just cores), when you specify your shared data (shared between threads) as volatile, you are fine. I wouldn't bet on that. Most of the cases, you'll be lucky, but then, you might get the occasional situation in which you aren't lucky, and that will be quite hard to debug and to reproduce. Most of the time, some other place in your program will do a aquire/release memory barrier, and thus your variable will get updated, despite not having a memory barrier on its own. But then, that relies on others parts of the program, which is not a good practice. Is that wrong? Uh oh, and now I'm totally confused, because I never bothered to declare e.g. shared classes (or rather their member data) as volatile. I mean how is sharing a simple boolean (or integer) different from sharing say an instance of a QString? Isn't there then always the danger that one thread sees (partly) outdated data (coming from a stale cache) if you don't explicitly use memory aquire and -release? First of all: QString is not thread-safe according to the documentation. Using the same QString instance from two threads will lead to problems such as crashes. If you share data between threads, you need to protected them by a mutex or use aquire/release barriers manually. A mutex has implicit aquire/release semantics. When using aquire/release barriers properly, the data will be up- to-date on all CPUs. It doesn't matter if you are using simple types such as ints or complex types like structs, since the memory barriers update all memory. Using a mutex is the best first choice: It protects your data against concurrent access and makes sure the data updates is visible on all CPUs using memory barriers. If you know what you are doing, you can use the QAtomic classes instead. While these will take care of memory barriers, these will not protect you against concurrent access. But then again, for the simple case of a boolean flag to stop a thread, concurrent access is not a problem. Forget about volatile here, volatile should not be used for threading. Regards,
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
2012/10/23 Thomas McGuire thomas.mcgu...@kdab.com: ... If you share data between threads, you need to protected them by a mutex or use aquire/release barriers manually. A mutex has implicit aquire/release semantics. THAT'S exactly the point I was missing here! Thanks for the excellent clarification! I wasn't aware that QMutex would also make sure under the hood that memory / caches were synchronised, too, before granting access to the Critical Section! :) And yes, declaring a variable as volatile generates code such that the variable is not placed into a register, but into ordinary RAM instead (I guess - unfortunately I never took a compiler class, and my steps in Assembler were very few back in those days ;)) But off course the CPU will (might) still cache it into 1st or 2nd level cache. As Bo pointed out on ordinary desktops you are probably lucky, since the Intel desktop architecture (single CPU, multiple cores) apparently have coherent caches. But I do get the point now that you should - Use QAtomicInt instead of a volatile bool (for the simple Stop thread use case) or - Protect access with QMutex in order to make sure that memory is synchronised across cache (or even dedicated RAM) boundaries. ... Using a mutex is the best first choice: It protects your data against concurrent access and makes sure the data updates is visible on all CPUs using memory barriers. Yes, that is now understood :) I wasn't aware of the memory barrier aspect! Thanks again! Oliver ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
2012/10/23 Till Oliver Knoll till.oliver.kn...@gmail.com: 2012/10/23 Thomas McGuire thomas.mcgu...@kdab.com: ... But off course the CPU will (might) still cache it into 1st or 2nd level cache. Uh... oh.. never mind my terminology here (1st and 2nd level cache - might be wrong), but as always Wikipedia is a good starting point for understanding the problem of out-of-order execution and cache incoherency (when using multiple CPUs - but I guess depending on the architecture the cache problem could also occur on SINGLE CPU with multiple cores, each having its own NON-coherent cache): http://en.wikipedia.org/wiki/Memory_barrier Cheers, Oliver ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
2012/10/23 Harri Pasanen ha...@mpaja.com: On 10/23/2012 12:14 PM, Till Oliver Knoll wrote: As Bo pointed out on ordinary desktops you are probably lucky, since the Intel desktop architecture (single CPU, multiple cores) apparently have coherent caches. Just a note that things like out-of-order execution and threading behave subtly different when using multicore ARM chips compared to Intel. Yes! As a matter of fact, even though on Intel x86 desktop multicore architecture caches might be coherent, you would STILL have a problem with instruction re-ordering, as done by a single core. So declaring a boolean flag as volatile is definitively NOT the way to do it ;) I recommend reading especially the chapter Out-of-order execution versus compiler reordering optimizations here: http://en.wikipedia.org/wiki/Memory_barrier Quote: The C and C++ standards do not address multiple threads (or multiple processors),[citation needed] and as such, the usefulness of volatile depends on the compiler and hardware. Although volatile guarantees that the volatile reads and volatile writes will happen in the exact order specified in the source code, the compiler may generate code (or the CPU may re-order execution) such that a volatile read or write is reordered with regard to non-volatile reads or writes, thus limiting its usefulness as an inter-thread flag or mutex. [...]. Moreover, it is not guaranteed that volatile reads and writes will be seen in the same order by other processors or cores due to caching, cache coherence protocol and relaxed memory ordering, meaning volatile variables alone may not even work as inter-thread flags or mutexes. Some languages and compilers may provide sufficient facilities to implement functions which address both the compiler reordering and machine reordering issues. In Java version 1.5 (also known as version 5), the volatile keyword is now guaranteed to prevent certain hardware and compiler re-orderings, as part of the new Java Memory Model. C++11 standardizes special atomic types and operations with semantics similar to those of volatile in the Java Memory Model. I've learnt something important today :) Cheers, Oliver ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Till Oliver Knoll wrote: As Bo pointed out on ordinary desktops you are probably lucky, since the Intel desktop architecture (single CPU, multiple cores) apparently have coherent caches. I doubt there is any luck involved. Coherent memory architectures are the simplest and least error prone for programmers used to single processor architectures, hence their popularity on hardware that supports general purpose operating systems and general purpose applications. Graeme Gill. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
[Interest] New Wayland compositor made with QtCompositor
Hi, I would like to share with you my work on a Wayland compositor and desktop shell made with QtQuick and QtCompositor and is using a set of components for QML to draw panels and widgets. You can find some screenshots from the Google+ page: https://plus.google.com/u/0/b/106410682256187719404/106410682256187719404 https://plus.google.com/u/0/photos/106410682256187719404/albums/5746843650891290529 The compositor is called Green Island and it's part of Hawaii a desktop environment developed with Wayland in mind for (but not limited to) Maui, a Linux distribution for desktop computing. The idea behind Maui is to avoid traditional packages, the system provides a minimal image with kernel, systemd, connman and other core programs, the desktop environment and its dependencies and it's built from a set of git repositories from master or specific branches. Applications will be installed from bundles. Modules for the Maui distribution are here: https://github.com/mauios Modules for the Hawaii desktop are here: https://github.com/hawaii-desktop You can find the code for Green Island on Github: https://github.com/hawaii-desktop/greenisland Hawaii can be built and used in other Linux distributions too, this is why it has a dedicated Github page. At the moment my activity is focused on Hawaii, more precisely I'm implementing some of the ideas me and the designers had. The efforts undertaken recently will result in the release of the first development version soon. Green Island has a desktop shell but a different shell may be loaded through plugins for example one may write a dedicated UI for tablets, this is because I feel that a UI should be made for each device and form factor in order to take advantage of its peculiarities like screen size and input devices. More screenshots will be published during this week and Arch Linux packages for x86_64 are almost ready. If you want to try it you don't have to wait for packages, to build the desktop from sources there's this repository: https://github.com/hawaii-desktop/hawaii it fetches all git submodules and lets you build all the software in the right order provided that you have satisfied the dependencies (CMake 2.8.9+, Mesa, Qt 5, libxkbcommon, Wayland 0.95). Due to qtwayland requirements you need specific libxkbcommon and wayland versions until the port to the stable API is over: http://qt.gitorious.org/qt/qtwayland/blobs/master/libxkbcommon_sha1.txt http://qt.gitorious.org/qt/qtwayland/blobs/master/wayland_sha1.txt This project is still young and needs your contributions, if you believe that a lightweight desktop environment and yet powerful, with attention to details and usability is possible this is a project you most certainly would want to take a look at. Green Island could also become the reference Qt-based compositor with your help. -- Out of the box experience http://www.maui-project.org/ ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
2012/10/23 Graeme Gill grae...@argyllcms.com: Till Oliver Knoll wrote: As Bo pointed out on ordinary desktops you are probably lucky, since the Intel desktop architecture (single CPU, multiple cores) apparently have coherent caches. I doubt there is any luck involved. Coherent memory architectures are the simplest and least error prone for programmers used to single processor architectures, hence their popularity on hardware that supports general purpose operating systems and general purpose applications. Still: using an QAtomicInt instead of a volatile bool is the same effort (programming-wise), is about the same cost (performance-wise) and makes your application also run on the other X% of non-cache-coherent systems. And in case you also want to target embedded/mobile platforms, it is not /that/ unlikely anymore that your code might have to work on ARM etc. CPUs ;) I understand that in the terminate flag use case (assuming again cache-coherency) the worst which might happen is that the worker thread does one loop too much, in case the Core decides to re-order the instructions such that you just miss the fact that the continue flag has been set to false by the other Core. But eventually the worker thread *will* see that the flag has been set to false (we already agreed that when you have non-coherent caches then that approach will fail here, too). However when you rely on volatile for more delicate synchronisation issues (other than this terminate flag use case) you might have a hard time to debug - even on cache-coherent systems! So I'd say, as a rule of thumb, use QAtomicInt (instead of volatile bool) - or protect the data with mutexes (which will make sure that memory is consistent). Cheers, Oliver ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Comment from one of the files in that .zip file: When we call this-setLayout(m_Layout), 'this' becomes the parent of m_Layout and all child objects (everything we add to the layout becomes a child of m_Layout), and deletes it (and all children) for us when 'this' is destroyed Not exactly true. When you add a widget to a layout, it becomes a sibling object of that layout. If you add a layout to a layout, it becomes a child of that layout. On Sun, Oct 21, 2012 at 12:16 AM, d3fault d3faultdot...@gmail.com wrote: I created this for two reasons: 1) To be a good starting/reference point for Qt beginners. I'm trying to combat the misinformation on how to use QThreads that the outdated docs have embedded into so many brains. I hope this will jumping out somewhere on the qt-project.org/docs/ so that it can serve as a basic Intro to Qt (for relatively experienced programmers). 2) To get feedback and as a sanity check of sorts. HAY EXPERTS, AM I DOIN IT RITE?? Please feel free to contribute in any way possible, whether it's discussion on the proper use of Qt or if you're just improving grammar/understandability of the comments. I do feel it is relatively complete, however. I have attached it, but here's an external link as well: http://bayfiles.com/file/oC1L/kQcSQW/SimpleSingleFrontEndWithTwoBackEndsExample.zip d3fault ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Object-based paint/update in Qt/PyQt4
2012/10/23 Zsolt Ero zsolt@gmail.com: ... In the original example file: graphicsview/collidingmice there is a special function def paint(self, painter, option, widget): what does the painting. There is no function calling the paint function, thus I'd think it's a special name called by QGraphicsView, but I don't understand what is a painter and what should a paint function implement. Your question covers is quite broad and covers many (painting related) topics, so let me answer by giving you a general overview about how painting in Qt works, instead of answering every specific question you had. I further strongly assume that the Python API is pretty much a 1:1 mapping to the corresponding Qt API, so I will explain it with the later API. One concept is that every widget paints itself when asked to (Qt is traditionally a widget based API, so I'll start there): * You derive from the base class QWidget and * Implement the (protected) method paintEvent(QPaintEvent *): http://qt-project.org/doc/qt-4.8/qwidget.html#paintEvent Most widgets simply paint the entire surface they cover, but you can optimise the painting if you only (re-)draw the area which is specified in the argument QPaintEvent. For instance if your widget shows a pixmap, you can only draw parts of that pixmap (typically the part which was partly covered by another window, and has now been uncovered, or when scrolling a widget: the part which has just become visible etc.). But how do you paint? Enter QPainter (http://qt-project.org/doc/qt-4.8/QPainter.html): the painter class draws upon a surface which in most cases will be a QWidget (you need to specify that surface (a Paint Device in Qt's lingo) when creating a painter). It provides basic operations such drawing a line, circle, rectangle, image, text etc. It is considered a stateful API (like OpenGL), in the sense that when you set the brush colour, it will be used in successive paint operations - until you change the colour again. But when do you paint? Most of the time you don't care! Or rather: the Qt Event Queue cares for you! The Qt Event Queue will manage all the underlying window manager show, expose, resize, ... window events and forward them to the affected QWidgets - by sending a QPaintEvent (sic!) to them. The net effect is that your protected paintEvent method will be called. As a matter of fact you should never - ever - call that function directly in your own code! The Qt Event queue knows better! But what if I change the underlying data to be painted? Off course you want to update and control the paint process: you want to be able to say I changed the coordinates of my polygon, please repaint! - But instead of calling your own paintEvent() method (see above! Don't do that!) you tell the corresponding view (the QWidget painting your polygon) to update itself - by calling the slot update(): http://qt-project.org/doc/qt-4.8/qwidget.html#update Note that this is a slot, which is pretty convenient, as you could connect it to a model's signal changed (so each time the model changes, the view gets automatically notified to update itself). What does update do? It does /not/ immediately repaint the widget! Rather it tells the Qt Event Queue Hey! When you think it is convenient, please have that widget updated. And when the proper time comes the Qt Event queue does exactly that (it is even so clever so compress multiple update requests: the widget is only updated /once/, even if you tell it 10 times to update shortly before). So up to now you know: * Where and when to paint (QWidget::paintEvent) * How to paint (QPainter) Off course managing a scene of objects, moving them around, doing collision tests and much more is a common task for applications, so implementing all that with traditional QWidgets would mean reinventing the wheel over and over again. Managing A Scene Enter QGraphicsScene (http://qt-project.org/doc/qt-4.8/QGraphicsScene.html) and the corresponding -View (http://qt-project.org/doc/qt-4.8/qgraphicsview.html)! A Graphics Scene is a container for scene items (http://qt-project.org/doc/qt-4.8/qgraphicsitem.html) such as ellipses, polygons, text and images. The View already implements many convenience functions: e.g. adding an item will automatically re-trigger a repaint of the scene! Moving an items (if it is made movable) also works out of the box. Now I understand your final goal is to make a polygon editable. To be honest I don't quite know whether that is possible out of the box: I would start with either subclassing http://qt-project.org/doc/qt-4.8/qgraphicspolygonitem.html, or one hierarchy upwards: http://qt-project.org/doc/qt-4.8/qabstractgraphicsshapeitem.html if you want to control the painting of the polygon yourself. Note that painting and mouse handling is very similar to the QWidget paint system above: so if you decided to subclass from Graphics Shape Item and paint the polygon yourself (filled, dashed etc. depending on the
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
On terça-feira, 23 de outubro de 2012 12.14.37, Till Oliver Knoll wrote: - Use QAtomicInt instead of a volatile bool (for the simple Stop thread use case) or The problems with volatile bool: 1) volatile wasn't designed for threading. It was designed for memory-mapped I/O. Its purpose is to make sure that there are no more and no fewer reads from the variable and writes to it than what the code does. If I write: a = 1; a = 1; I want the compiler to store 1 twice. If this is MMIO, then I might need that value of 0x01 sent twice over my I/O device. For threading, however, that's irrelevant. Storing the same value twice, especially sequentially like that, makes no sense. I won't bother explaining why because you can see it with little thought. What's more, CPU architectures don't work like that either. Writes are cached and then sent to the main RAM and other CPUs later, in bursts. Writing twice to memory, especially sequentially, will almost certainly result in RAM being written to only once. And besides, there's no way to detect that a location in memory has been overwritten with the same value. For those reasons, the semantics of volatile don't match the needs of threading. 2) volatile isn't atomic. a) for all types All CPU architectures I know of have at least one size that they can read and write in a single operation. It's the machine word, which usually corresponds to the register size. Complex and modern CPUs are often able to read and write data types of different sizes in atomic operations, but there are many examples of CPUs that can't do it. The only way to store an 8-bit value is to load the entire word where that 8-bit value is located, merge it in and then store the full word. A read-modify-write sequence is definitely not an atomic store. The C++ bool type is 1 byte in size, so it suffers from this problem. So here we have a conclusion: you'd never use volatile bool, you'd use volatile sig_atomic_t (a type that is required by POSIX to have atomic loads and stores). b) for all operations Even if you follow the POSIX recommendations and use a sig_atomic_t for your variable, most other operations aren't atomic. On most architectures, incrementing and decrementing isn't atomic. And if you're trying to do thread synchronisation, you often need higher operations like fetch-and-add, compare- and-swap or simple swap. 3) volatile does not (usually) generate memory barriers There are two types of memory barriers: compiler and processor ones. Take the following code: value = 123456; spinlock = 0; Where spinlock is a volatile int. Two levels of things might go wrong there: first, since there's no compiler barrier, the compiler might generate code that stores the 0 to the spinlock (unlocking it) before it generates the code that saves the more complex value to the other variable. I'm not even talking hypotheticals or obscure architectures. This is what the ARMv7 compiler generated for me: movwr1, #57920 mov r0, #0 movtr1, 1 str r0, [r2, #0] str r1, [r3, #0] This example was intentional because I knew that ARM can't load a large value to a register in a single instruction. Loading 123456 requires two instructions (move and move top). So I expected the compiler to schedule the saving of 0 to before the saving of the more complex value and it did. And even when it does schedule things in the correct order, the memory barrier might be missing. Taking again the example of ARMv7, saving a zero to value and unlocking the mutex: mov r1, #0 str r1, [r2, #0] str r1, [r3, #0] The ARMv7 architecture, unlike x86, *does* allow the processor to write to main RAM in any order. That means another core could see the the spinlock being unlocked *before* the new value is stored, even if the compiler generated the proper instructions. It's missing the memory barrier instruction. The Qt 4 QAtomicInt API does not offer a load-acquire or a store-release operation. All reads and writes are non-atomic and may be problematic -- you can work around that by using a fetch-and-add of zero for load or a fetch-and- store for store. The Qt 5 API does offer the right functions and even requires you to think about it. The reason I said usually is because there is one architecture whose ABI requires acquire semantics for volatile loads and release semantics for volatile stores. That's IA-64, an architecture that was introduced after multithreading became mainstream and has a specific load acquire instruction anyway. The IA-64 manual explaining the memory ordering and barriers is one of the references I use to study the subject. 4) compilers have bugs In this case, there's little we can do but work around them. This problem was found by the kernel developers in GCC. They had a structure like: int field1; volatile int field2; On a 64-bit architecture, to modify field1,
Re: [Interest] New Wayland compositor made with QtCompositor
This is so glorious to see I can barely restrain myself from riddling this mail with expletives. When I finally extract my finger from taking a core sample, I will investigate the use of this on the Raspberry Pi, where Qt Wayland already hums merrily. Cheerio, Donald On Tue, Oct 23, 2012 at 4:12 AM, Pier Luigi pierluigi.fior...@gmail.com wrote: Hi, I would like to share with you my work on a Wayland compositor and desktop shell made with QtQuick and QtCompositor and is using a set of components for QML to draw panels and widgets. You can find some screenshots from the Google+ page: https://plus.google.com/u/0/b/106410682256187719404/106410682256187719404 https://plus.google.com/u/0/photos/106410682256187719404/albums/5746843650891290529 The compositor is called Green Island and it's part of Hawaii a desktop environment developed with Wayland in mind for (but not limited to) Maui, a Linux distribution for desktop computing. The idea behind Maui is to avoid traditional packages, the system provides a minimal image with kernel, systemd, connman and other core programs, the desktop environment and its dependencies and it's built from a set of git repositories from master or specific branches. Applications will be installed from bundles. Modules for the Maui distribution are here: https://github.com/mauios Modules for the Hawaii desktop are here: https://github.com/hawaii-desktop You can find the code for Green Island on Github: https://github.com/hawaii-desktop/greenisland Hawaii can be built and used in other Linux distributions too, this is why it has a dedicated Github page. At the moment my activity is focused on Hawaii, more precisely I'm implementing some of the ideas me and the designers had. The efforts undertaken recently will result in the release of the first development version soon. Green Island has a desktop shell but a different shell may be loaded through plugins for example one may write a dedicated UI for tablets, this is because I feel that a UI should be made for each device and form factor in order to take advantage of its peculiarities like screen size and input devices. More screenshots will be published during this week and Arch Linux packages for x86_64 are almost ready. If you want to try it you don't have to wait for packages, to build the desktop from sources there's this repository: https://github.com/hawaii-desktop/hawaii it fetches all git submodules and lets you build all the software in the right order provided that you have satisfied the dependencies (CMake 2.8.9+, Mesa, Qt 5, libxkbcommon, Wayland 0.95). Due to qtwayland requirements you need specific libxkbcommon and wayland versions until the port to the stable API is over: http://qt.gitorious.org/qt/qtwayland/blobs/master/libxkbcommon_sha1.txt http://qt.gitorious.org/qt/qtwayland/blobs/master/wayland_sha1.txt This project is still young and needs your contributions, if you believe that a lightweight desktop environment and yet powerful, with attention to details and usability is possible this is a project you most certainly would want to take a look at. Green Island could also become the reference Qt-based compositor with your help. -- Out of the box experience http://www.maui-project.org/ ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
I did some googling and found this http://lists.qt.nokia.com/pipermail/qt4-feedback/2009-October/000880.html - you are saying that it's ok to use volatile on x86_64 here since there is no actual synchronization here. Or am I missing something here and cases are different? Sorry for nitpicking, I am just trying to fully understand what's happening in this case On Tue, Oct 23, 2012 at 10:24 PM, Thiago Macieira thiago.macie...@intel.com wrote: On terça-feira, 23 de outubro de 2012 12.14.37, Till Oliver Knoll wrote: - Use QAtomicInt instead of a volatile bool (for the simple Stop thread use case) or The problems with volatile bool: 1) volatile wasn't designed for threading. It was designed for memory-mapped I/O. Its purpose is to make sure that there are no more and no fewer reads from the variable and writes to it than what the code does. If I write: a = 1; a = 1; I want the compiler to store 1 twice. If this is MMIO, then I might need that value of 0x01 sent twice over my I/O device. For threading, however, that's irrelevant. Storing the same value twice, especially sequentially like that, makes no sense. I won't bother explaining why because you can see it with little thought. What's more, CPU architectures don't work like that either. Writes are cached and then sent to the main RAM and other CPUs later, in bursts. Writing twice to memory, especially sequentially, will almost certainly result in RAM being written to only once. And besides, there's no way to detect that a location in memory has been overwritten with the same value. For those reasons, the semantics of volatile don't match the needs of threading. 2) volatile isn't atomic. a) for all types All CPU architectures I know of have at least one size that they can read and write in a single operation. It's the machine word, which usually corresponds to the register size. Complex and modern CPUs are often able to read and write data types of different sizes in atomic operations, but there are many examples of CPUs that can't do it. The only way to store an 8-bit value is to load the entire word where that 8-bit value is located, merge it in and then store the full word. A read-modify-write sequence is definitely not an atomic store. The C++ bool type is 1 byte in size, so it suffers from this problem. So here we have a conclusion: you'd never use volatile bool, you'd use volatile sig_atomic_t (a type that is required by POSIX to have atomic loads and stores). b) for all operations Even if you follow the POSIX recommendations and use a sig_atomic_t for your variable, most other operations aren't atomic. On most architectures, incrementing and decrementing isn't atomic. And if you're trying to do thread synchronisation, you often need higher operations like fetch-and-add, compare- and-swap or simple swap. 3) volatile does not (usually) generate memory barriers There are two types of memory barriers: compiler and processor ones. Take the following code: value = 123456; spinlock = 0; Where spinlock is a volatile int. Two levels of things might go wrong there: first, since there's no compiler barrier, the compiler might generate code that stores the 0 to the spinlock (unlocking it) before it generates the code that saves the more complex value to the other variable. I'm not even talking hypotheticals or obscure architectures. This is what the ARMv7 compiler generated for me: movwr1, #57920 mov r0, #0 movtr1, 1 str r0, [r2, #0] str r1, [r3, #0] This example was intentional because I knew that ARM can't load a large value to a register in a single instruction. Loading 123456 requires two instructions (move and move top). So I expected the compiler to schedule the saving of 0 to before the saving of the more complex value and it did. And even when it does schedule things in the correct order, the memory barrier might be missing. Taking again the example of ARMv7, saving a zero to value and unlocking the mutex: mov r1, #0 str r1, [r2, #0] str r1, [r3, #0] The ARMv7 architecture, unlike x86, *does* allow the processor to write to main RAM in any order. That means another core could see the the spinlock being unlocked *before* the new value is stored, even if the compiler generated the proper instructions. It's missing the memory barrier instruction. The Qt 4 QAtomicInt API does not offer a load-acquire or a store-release operation. All reads and writes are non-atomic and may be problematic -- you can work around that by using a fetch-and-add of zero for load or a fetch-and- store for store. The Qt 5 API does offer the right functions and even requires you to think about it. The reason I said usually is because there is one architecture whose ABI requires acquire semantics for volatile loads and
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two BackendsHi,
Hello Thomas (and Other Commenters)! (Let me apologize for remaining a little off topic, as my question -- can volatiles be used for one thread to signal another thread to stop -- is about c++ rather than Qt.) On Mon, Oct 22, 2012 at 9:18 AM, Thomas McGuire thomas.mcgu...@kdab.com wrote: Hi, On Monday 22 October 2012 14:16:33 Bo Thorsen wrote: Den 22-10-2012 12:10, Jan Kundrát skrev: On 10/22/12 07:21, d3fault wrote: According to my understanding, the reason for this is the C++ memory model (or lack thereof); while volatile might look like a great way to force an always load stuff from memory approach, it does not impose a particular ordering of the read/write operations, so the compiler/CPU/memory controller/... are actually allowed to reorder access to other memory regions (and they really do that). That's not what you want to do. Not correct. Neither the compiler nor the CPU can reorder around a volatile. volatile only forces the compiler to create an instruction to fetch the variable from memory again, to prevent caching in a register. The CPU doesn't even know about the volatile keyword anymore, it just sees a normal fetch instruction, and can therefore use the CPU cache. If I understand the original purpose of volatile, to confirm, reading a volatile should cause a true memory fetch, not just a fetch from cache. (As you mention below, if volatile is used for memory-mapped IO, that IO won't actually occur if the fetch is just a cache fetch.) Therefore, if your two threads are living on different CPUs, one CPU might not see the update on the other CPU, since the CPU caches are not updated. volatile does not help with that, you need proper memory barriers. Let's say that CPU A writes to the volatile and CPU B reads from it. Isn't it the case that A's write to the volatile must cause a true memory store and not just a write to cache? (Again, memory-mapped IO would not work if the store is just a write to cache.) Then when CPU B reads the volatile, mustn't it perform an actual memory fetch, picking up the result of A's memory store? The executed code has to write the true to the actual memory pointed to by b and read it back from that in the if statement just after it. Another thread could have changed it between the two statements. So no register or cache can be used to speed this up and the compiler won't optimize the check away. This does of course work. Otherwise, volatiles would be useless. It does not work in all cases, see above. volatile _is_ useless for threading, its orginal purpose was for memory-mapped IO. Let me state for the record that I do not use volatiles for thread synchronization. But the issue at hand is not whether a volatile can be used for full-featured thread synchronization, but whether it can be used by one thread to signal a second looping thread to quit. It seems to me that volatile must cause the signalling thread to perform an actual memory store and the thread to be signalled to perform an actual memory fetch. Yes, there is a potential race condition in that the looping thread may read the volatile after the signalling thread has written to it, but because the thread is looping, it will come around and read the volatile again, picking up the new value that signals it to quit. Is there any plausible reading of the standard by which this signalling mechanism could fail? Do you know of any mainstream platforms (hardware, os, and compiler) on which this signalling mechanism does fail? I can't conceive of any realistic scenario in which using volatiles for memory-mapped IO (both the input and the output) would work reliably, but nonetheless using volatiles for thread signalling would not be equally reliable. (The standard could perhaps say that the semantics of volatile are formally and explicitly implementation defined, but I would then argue that any reasonable implementation would have to define volatile as a useless no-op, or that the thread signalling mechanism will in fact work.) Regards, Thomas Thanks for any further insight. K. Frank ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Thank you Alan, I've fixed the comment to say sibling. On 10/22/12, Bo Thorsen b...@fioniasoftware.dk wrote: Now I'm getting annoyed. You're the one spreading misinformation here. I mentioned the pure computation as one of the cases where I prefer subclassing. But that of course doesn't mean you can't do it in other ways. You're right, I was mainly focusing on your pure computation argument in my response. Thought you were arguing that moveToThread couldn't do it. (emitting progress signals can take it off the list -- what?? meh don't bother responding, it's pointless) But anyways I've been following the [higher level] topics in this thread and now I'm thinking the example in the .zip needs a complete rewrite haha. Here, I'm about to contradict my earlier self: In order to have both the constructor and destructor run on the thread, would it be a good idea to do something like this? run() { UserObject obj; //ideally this would be a template passed in to some custom QThread implementation, but it's important to note that it is allocated on the stack emit readyForConnections(obj); //Would be dangerous to call methods etc on this object. Should only connect to it's signals/slots exec(); //destructor runs when exec() returns... ie when thread is ending/about-to-end. Since we're still in run(), the destructor runs on the thread :) } ...so you could set up an object on it's own thread (incl. constructor/destructor!) by doing: LoLCustomThreadImplWithATemplateTooMyObjectType threadForMyObject; connect(threadForMyObject, SIGNAL(readyForConnections(MyObjectType*)), this, SLOT(handleObjectReadyForConnections(MyObjectType*))); threadForMyObject.start(); void handleObjectReadyForConnections(MyObjectType *obj) { connect(btn, SIGNAL(clicked()), obj, SLOT(doSomethingPleaseAndThankYou())); connect(obj, SIGNAL(somethingHappenedDde()), this, SLOT(handleSomeoneStoleMyCarDude())); //etc } New Qt class or what? d3fault ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Quick fix: On 10/23/12, d3fault d3faultdot...@gmail.com wrote: emit readyForConnections(obj); //Would be dangerous to call methods etc on this object. Should only connect to it's signals/slots What I meant to say is that listeners to that signal should not call methods on the object. Calling methods on the object directly from within the run() method is OK, of course. ...but seeing as I'm proposing it's template-based, you wouldn't [need to] write any code in run() anyways... d3fault ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
On terça-feira, 23 de outubro de 2012 23.58.41, Sergey Borovkov wrote: I did some googling and found this http://lists.qt.nokia.com/pipermail/qt4-feedback/2009-October/000880.html - you are saying that it's ok to use volatile on x86_64 here since there is no actual synchronization here. Or am I missing something here and cases are different? Sorry for nitpicking, I am just trying to fully understand what's happening in this case All that I said in that email is still correct. Note that the use of volatile in that example was to ensure that the compiler was working at the point where I asked it to, not caching the result from some previous code before the snippets. The rest of the email has nothing to do with volatile. And, in fact, the volatile int should more correctly be QAtomicInt from Qt 5. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center signature.asc Description: This is a digitally signed message part. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two BackendsHi,
On terça-feira, 23 de outubro de 2012 16.14.11, K. Frank wrote: volatile only forces the compiler to create an instruction to fetch the variable from memory again, to prevent caching in a register. The CPU doesn't even know about the volatile keyword anymore, it just sees a normal fetch instruction, and can therefore use the CPU cache. If I understand the original purpose of volatile, to confirm, reading a volatile should cause a true memory fetch, not just a fetch from cache. (As you mention below, if volatile is used for memory-mapped IO, that IO won't actually occur if the fetch is just a cache fetch.) No, that's not what it means. A volatile load requires the compiler to *load* again, but it doesn't instruct the processor how to load it. The processor may serve the load from any cache level or from main memory. Unless the ABI says otherwise. The only ABI I know that says otherwise is IA-64's, that requires a volatile load to be done using the load acquire instruction. What you're missing is that MMIO requires the memory address to be uncacheable. That means the processor will bypass all cache levels and will just issue the right load in the memory bus. But all of that is outside the compiler's control. It simply loads from an address you gave it. Therefore, if your two threads are living on different CPUs, one CPU might not see the update on the other CPU, since the CPU caches are not updated. volatile does not help with that, you need proper memory barriers. Let's say that CPU A writes to the volatile and CPU B reads from it. Isn't it the case that A's write to the volatile must cause a true memory store and not just a write to cache? (Again, memory-mapped IO would not work if the store is just a write to cache.) Then when CPU B reads the volatile, mustn't it perform an actual memory fetch, picking up the result of A's memory store? That depends on the architecture. If the write to memory had release semantics and the read had acquire semantics, then the two CPUs must -- somehow -- figure out and synchronise. For example, on IA-64, the store-release causes CPU A to mark the address as modified in the L3 off-die cache and the load-acquire from CPU B requires it to go check the L3 cache. On x86, the store from CPU A causes it to go and invalidate all cachelines containing that address in the other CPUs' caches. So when CPU B tries to read, it will be forced to go to main memory or the L3 off-die cache. On those two architectures, a volatile qualifier is enough to ensure proper behaviour. On x86, because all loads and stores are fully ordered anyway and on IA-64, because the ABI requires volatile loads to acquire and volatile stores to release. But if you go beyond those two Intel architectures, the bets are off. On ARMv7, for example, the ABI does not require a volatile load or store to insert the dmb instruction. That means in your example, CPU B would not read from the main memory and it could fetch the value from one of its stale caches. The same goes for PowerPC/POWER, MIPS, Sparc, etc. Let me state for the record that I do not use volatiles for thread synchronization. But the issue at hand is not whether a volatile can be used for full-featured thread synchronization, but whether it can be used by one thread to signal a second looping thread to quit. It can. In that restricted scenario, even a non-atomic write would be sufficient. It seems to me that volatile must cause the signalling thread to perform an actual memory store and the thread to be signalled to perform an actual memory fetch. Yes, there is a potential race condition in that the looping thread may read the volatile after the signalling thread has written to it, but because the thread is looping, it will come around and read the volatile again, picking up the new value that signals it to quit. Correct. Is there any plausible reading of the standard by which this signalling mechanism could fail? Do you know of any mainstream platforms (hardware, os, and compiler) on which this signalling mechanism does fail? No, I can't think of any for this particular case. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center signature.asc Description: This is a digitally signed message part. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
On 23 October 2012 20:24, Thiago Macieira thiago.macie...@intel.com wrote: 1) volatile wasn't designed for threading. It was designed for memory-mapped I/O Going slightly off topic, I never managed to find reliable sources about which problem volatile was meant to solve when it was *first* introduced: MMIO, changing values from signal handlers (together with a sig_atomic_t), or saving the value of automatic variables across a setjmp/longjmp? Of course now it's a reliable solution to all three problems... (Yes, threads never entered the picture.) Cheers, -- Giuseppe D'Angelo ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two BackendsHi,
Hi Thiago! Thank you for your detailed explanation. I am still confused; it sounds like you are saying two different things. (Further comments below.) On Tue, Oct 23, 2012 at 6:11 PM, Thiago Macieira thiago.macie...@intel.com wrote: On terça-feira, 23 de outubro de 2012 16.14.11, K. Frank wrote: volatile only forces the compiler to create an instruction to fetch the variable from memory again, to prevent caching in a register. The CPU doesn't even know about the volatile keyword anymore, it just sees a normal fetch instruction, and can therefore use the CPU cache. If I understand the original purpose of volatile, to confirm, reading a volatile should cause a true memory fetch, not just a fetch from cache. (As you mention below, if volatile is used for memory-mapped IO, that IO won't actually occur if the fetch is just a cache fetch.) No, that's not what it means. A volatile load requires the compiler to *load* again, but it doesn't instruct the processor how to load it. The processor may serve the load from any cache level or from main memory. Okay, I'll buy that. At the language-semantics level, volatile prohibits the compiler form optimizing the load (or store) away. Unless the ABI says otherwise. The only ABI I know that says otherwise is IA-64's, that requires a volatile load to be done using the load acquire instruction. But the language standard does not prohibit the load (or store) from acting on a (potentially core-specific) cache. What you're missing is that MMIO requires the memory address to be uncacheable. That means the processor will bypass all cache levels and will just issue the right load in the memory bus. But all of that is outside the compiler's control. It simply loads from an address you gave it. If the hardware has magic (i.e., uncacheable) addresses, then a load to one of those addresses won't get cached. So memory-mapped IO, for example, works because of cooperation between the language's support of volatile (load cannot be optimized away) and the hardware (load is from memory, not the cache, if the address is uncacheable). This makes good sense. Therefore, if your two threads are living on different CPUs, one CPU might not see the update on the other CPU, since the CPU caches are not updated. volatile does not help with that, you need proper memory barriers. Let's say that CPU A writes to the volatile and CPU B reads from it. Isn't it the case that A's write to the volatile must cause a true memory store and not just a write to cache? (Again, memory-mapped IO would not work if the store is just a write to cache.) Then when CPU B reads the volatile, mustn't it perform an actual memory fetch, picking up the result of A's memory store? That depends on the architecture. If the write to memory had release semantics and the read had acquire semantics, then the two CPUs must -- somehow -- figure out and synchronise. For example, on IA-64, the store-release causes CPU A to mark the address as modified in the L3 off-die cache and the load-acquire from CPU B requires it to go check the L3 cache. On x86, the store from CPU A causes it to go and invalidate all cachelines containing that address in the other CPUs' caches. So when CPU B tries to read, it will be forced to go to main memory or the L3 off-die cache. On those two architectures, a volatile qualifier is enough to ensure proper behaviour. On x86, because all loads and stores are fully ordered anyway and on IA-64, because the ABI requires volatile loads to acquire and volatile stores to release. Okay. The scheme works on x86 because of how the hardware works, and on IA-64 because of its ABI guarantees. But if you go beyond those two Intel architectures, the bets are off. On ARMv7, for example, the ABI does not require a volatile load or store to insert the dmb instruction. That means in your example, CPU B would not read from the main memory and it could fetch the value from one of its stale caches. The same goes for PowerPC/POWER, MIPS, Sparc, etc. But need not work on other architectures, and ARMv7 and the others you mention are examples of this. I'll buy all that. Let me state for the record that I do not use volatiles for thread synchronization. But the issue at hand is not whether a volatile can be used for full-featured thread synchronization, but whether it can be used by one thread to signal a second looping thread to quit. It can. In that restricted scenario, even a non-atomic write would be sufficient. But now I'm confused. It would seem that from what you've said above, this thread signalling mechanism could easily fail on, for example, a multicore ARMv7 platform. CPU A writes to the volatile signalling variable, but it writes to its CPU-specific cache. The thread that's looping runs on CPU B, and repeatedly reads from the volatile signalling variable, but always reads it from its own CPU-specific cache. So it never
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
Actually, it's not as simple as I stated. Basically, adding a widget to a layout makes it the child of the widget that it is a layout for. So if you add a widget to a sub-layout, it actually won't be the sibling of that layout object, but an uncle or something. On Tue, Oct 23, 2012 at 1:28 PM, d3fault d3faultdot...@gmail.com wrote: Thank you Alan, I've fixed the comment to say sibling. But anyways I've been following the [higher level] topics in this thread and now I'm thinking the example in the .zip needs a complete rewrite haha. Regarding rewriting the example, I think the best way to rewrite it is to remove all usage of QThread entirely, and see if you can figure out how to program it using the higher-level QtConcurrent API. In my book [Intro to Design Patterns in Qt, 2nd edition], I show another multithreaded example written both ways and the QtConcurrent version performs much better. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two BackendsHi,
On terça-feira, 23 de outubro de 2012 19.14.48, K. Frank wrote: A volatile load requires the compiler to *load* again, but it doesn't instruct the processor how to load it. The processor may serve the load from any cache level or from main memory. Okay, I'll buy that. At the language-semantics level, volatile prohibits the compiler form optimizing the load (or store) away. Correct. A volatile load implies that the compiler must generate a load. It doesn't say what type of load that is. The IA-64 ABI says what type of load it is. The C11 and C++11 standards also specify an atomic_load() that can take an ATOMIC_ACQUIRE to produce an acquire. Unless the ABI says otherwise. The only ABI I know that says otherwise is IA-64's, that requires a volatile load to be done using the load acquire instruction. But the language standard does not prohibit the load (or store) from acting on a (potentially core-specific) cache. Correct. The processor is allowed to satisfy a generic load from anywhere that the architecture deems acceptable. On x86, the MOV load will load from any cache but the CPU will ensure that it behaves in fully-ordered mode. On ARM and on IA-64, the ld instructions may load from anywhere and do *not* have to obey any ordering. This is about ordering, not about where it loads from. Some architectures have special load or store instructions that specify what cache level they should hit. On x86, it's the MOVNTDQ instruction (NT = non- temporal = don't cache) which can only be used for stores. On IA-64, both ld and st can receive the .nta suffix for non-temporal locality and ld can also get an .nt1 for specifying non-temporal for level 1 only. Those instructions are not accessible via regular programming models. You either need to write assembly or use an intrinsic. What you're missing is that MMIO requires the memory address to be uncacheable. That means the processor will bypass all cache levels and will just issue the right load in the memory bus. But all of that is outside the compiler's control. It simply loads from an address you gave it. If the hardware has magic (i.e., uncacheable) addresses, then a load to one of those addresses won't get cached. Right. So memory-mapped IO, for example, works because of cooperation between the language's support of volatile (load cannot be optimized away) and the hardware (load is from memory, not the cache, if the address is uncacheable). Right. Let me state for the record that I do not use volatiles for thread synchronization. But the issue at hand is not whether a volatile can be used for full-featured thread synchronization, but whether it can be used by one thread to signal a second looping thread to quit. It can. In that restricted scenario, even a non-atomic write would be sufficient. But now I'm confused. It would seem that from what you've said above, this thread signalling mechanism could easily fail on, for example, a multicore ARMv7 platform. Not exactly. The explanation for that is below. CPU A writes to the volatile signalling variable, but it writes to its CPU-specific cache. The thread that's looping runs on CPU B, and repeatedly reads from the volatile signalling variable, but always reads it from its own CPU-specific cache. So it never gets the signal to quit, and potentially loops forever. Well, that's not exactly how processors work. CPU A will eventually get to write the data from its cache back to main RAM. And CPU B will eventually get to notice that and discard its cache. So the code running on CPU B will eventually get to see the new value. The question is only how long that might take. Also note that you should not implement a busy-wait loop like that, like a spinlock. At least on x86, if one CPU is constantly reading from the same address, it will prevent the others from writing to it. Since you're busy- looping, you're spending power. It seems to me that volatile must cause the signalling thread to perform an actual memory store and the thread to be signalled to perform an actual memory fetch. Yes, there is a potential race condition in that the looping thread may read the volatile after the signalling thread has written to it, but because the thread is looping, it will come around and read the volatile again, picking up the new value that signals it to quit. Correct. Again, I'm confused. Based on what you said above, why can't the looping thread keep reading the stale (but volatile) value from its cache, and, in fact, never pick up the new value? Because eventually the CPUs will figure it out. Is there any plausible reading of the standard by which this signalling mechanism could fail? Do you know of any mainstream platforms (hardware, os, and compiler) on which this signalling mechanism does fail? No, I can't think of any for this particular case. But couldn't it fail on the platforms you mentioned above, for
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
On 10/23/12, Alan Ezust alan.ez...@gmail.com wrote: Actually, it's not as simple as I stated. Basically, adding a widget to a layout makes it the child of the widget that it is a layout for. So if you add a widget to a sub-layout, it actually won't be the sibling of that layout object, but an uncle or something. Weird, so what you're saying is: QWidget 'this' parent _Layout _Layout1Widget1 _Layout1Widget2 __SubLayout1 // added via Layout.addLayout(), Layout now being his parent _SubLayout1Widget1 _SubLayout1Widget2 __SubLayout2 // ditto _SubLayout2Wiget1 ___SubSubLayout3 // added via SubLayout2.addLayout(), SubLayout2 now being his parent _SubSubLayout3Widget1 _SubSubLayout3Widget2 With everything that's a widget being a sibling and a direct child of 'this'? I guess that makes sense. I think I'm better off just removing the part of the comment that's wrong than trying to explain that (but the QWidget::setLayout docs should (and don't) explain it!). Regarding rewriting the example, I think the best way to rewrite it is to remove all usage of QThread entirely, and see if you can figure out how to program it using the higher-level QtConcurrent API. In my book [Intro to Design Patterns in Qt, 2nd edition], I show another multithreaded example written both ways and the QtConcurrent version performs much better. book I wish I could see what you're talking about :-P. My goal in making that example is/was to have a simple and easy to understand reference that implements a clean and re-usable design. Performance was not a huge concern, but I wouldn't say it isn't important. Why would QtConcurrent be more performant if they both use QThreads in the background? I'm under the impression that QtConcurrent is meant for.. err... problems... that scale horizontally. Yes my use of QCryptographicHash would scale horizontally, but not everything can. Is QtConcurrent still more performant in those cases where we can't scale horizontally? If so, I'll look more into rewriting it under QtConcurrent (if I could see the example in your book I could answer this myself). At a glance (I've read all the QtConcurrent docs previously, but have yet to actually use it... so I guess I should say at a re-glance), it looks like I could use that template-based readyForConnections() emitting design described in my previous email very easily within QtConcurrent::run(). However, then I saw this: Note that the function may not run immediately; the function will only be run when a thread is available ( http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run ). Within a large application with many backend objects/threads (doing different things, so they can't scale horizontally), it sounds sub-optimal to not be able to have them all running at the same time. You could override QThreadPool's max thread count, but idk that just seems hacky. Aren't thread pools meant for numerous shorter living units of execution? I recall reading somewhere something along the lines of if you are going to keep the thread alive for a long time, use QThread instead. The example, and the design I'm trying to perfect, is the long-standing single (or I guess double lol) backend thread. If I'm wrong and setting QThreadPool's max thread count to be = your backend object count on a per-project basis isn't a dirty hack (separation of concerns!)... and if QtConcurrent really performs that much better... I'll probably use it for the rewrite. Thanks :) d3fault ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
2012/10/24 d3fault d3faultdot...@gmail.com: Weird, so what you're saying is: QWidget 'this' parent _Layout _Layout1Widget1 _Layout1Widget2 __SubLayout1 // added via Layout.addLayout(), Layout now being his parent _SubLayout1Widget1 _SubLayout1Widget2 __SubLayout2 // ditto _SubLayout2Wiget1 ___SubSubLayout3 // added via SubLayout2.addLayout(), SubLayout2 now being his parent _SubSubLayout3Widget1 _SubSubLayout3Widget2 With everything that's a widget being a sibling and a direct child of 'this'? I guess that makes sense. I think I'm better off just removing the part of the comment that's wrong than trying to explain that (but the QWidget::setLayout docs should (and don't) explain it!). Look at http://qt-project.org/doc/qt-4.8/layout.html#tips-for-using-layouts Regarding rewriting the example, I think the best way to rewrite it is to remove all usage of QThread entirely, and see if you can figure out how to program it using the higher-level QtConcurrent API. In my book [Intro to Design Patterns in Qt, 2nd edition], I show another multithreaded example written both ways and the QtConcurrent version performs much better. book I wish I could see what you're talking about :-P. My goal in making that example is/was to have a simple and easy to understand reference that implements a clean and re-usable design. Performance was not a huge concern, but I wouldn't say it isn't important. Why would QtConcurrent be more performant if they both use QThreads in the background? I'm under the impression that QtConcurrent is meant for.. err... problems... that scale horizontally. Yes my use of QCryptographicHash would scale horizontally, but not everything can. Is QtConcurrent still more performant in those cases where we can't scale horizontally? If so, I'll look more into rewriting it under QtConcurrent (if I could see the example in your book I could answer this myself). At a glance (I've read all the QtConcurrent docs previously, but have yet to actually use it... so I guess I should say at a re-glance), it looks like I could use that template-based readyForConnections() emitting design described in my previous email very easily within QtConcurrent::run(). However, then I saw this: Note that the function may not run immediately; the function will only be run when a thread is available ( http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run ). Within a large application with many backend objects/threads (doing different things, so they can't scale horizontally), it sounds sub-optimal to not be able to have them all running at the same time. You could override QThreadPool's max thread count, but idk that just seems hacky. Aren't thread pools meant for numerous shorter living units of execution? I recall reading somewhere something along the lines of if you are going to keep the thread alive for a long time, use QThread instead. The example, and the design I'm trying to perfect, is the long-standing single (or I guess double lol) backend thread. If I'm wrong and setting QThreadPool's max thread count to be = your backend object count on a per-project basis isn't a dirty hack (separation of concerns!)... and if QtConcurrent really performs that much better... I'll probably use it for the rewrite. Thanks :) d3fault ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Heavily Commented Example: Simple Single Frontend with Two Backends
On Tue, Oct 23, 2012 at 6:51 PM, d3fault d3faultdot...@gmail.com wrote: Regarding rewriting the example, I think the best way to rewrite it is to remove all usage of QThread entirely, and see if you can figure out how to program it using the higher-level QtConcurrent API. In my book [Intro to Design Patterns in Qt, 2nd edition], I show another multithreaded example written both ways and the QtConcurrent version performs much better. book I wish I could see what you're talking about :-P. My goal in making that example is/was to have a simple and easy to understand reference that implements a clean and re-usable design. Performance was not a huge concern, but I wouldn't say it isn't important. http://www.ics.com/designpatterns is one place where you can see the book's contents and download the code examples. It requires you to register/login but it's free. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
[Interest] Getting a hostname given the IP Address
Hello all, I am writing an application for our company, and at one point I need to get the hostname of a computer on the network given the IP address. If I use QHostInfo::lookupHost() connected to a lookup slot, and provided with the IP address, it returns the same IP address. How can I rectify this? Thanking you in advance. Joshua. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Getting a hostname given the IP Address
On quarta-feira, 24 de outubro de 2012 05.38.03, Joseph W Joshua wrote: Hello all, I am writing an application for our company, and at one point I need to get the hostname of a computer on the network given the IP address. If I use QHostInfo::lookupHost() connected to a lookup slot, and provided with the IP address, it returns the same IP address. in the QHostInfo that you receive in your slot, the hostName() returns the IP address in string form? For every hostname you've tried? Try 8.8.8.8 for example. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center signature.asc Description: This is a digitally signed message part. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest