Prev: Xlib question - efficient way to get pixel value?
Next: Printing Back tracing information during run time
From: Chris M. Thomasson on 29 Oct 2009 14:27 "Noob" <root(a)127.0.0.1> wrote in message news:hcbsu6$ocf$1(a)aioe.org... > Chris M. Thomasson wrote: > >> Man! This sucks!! Anyway, I believe you could meet all the requirements, >> however, it's not going to be pretty. Here is what I hacked together for >> you so far: >> >> http://cpt.pastebin.com/f540aaef5 > > Thanks Chris, I'll take a hard look at it. Here is updated code which handles the case in which a thread tries to unlock a mutex that is locked by another thread: http://cpt.pastebin.com/f3044e915 It also fixes a race-condition I overlooked. The unlocking needs to be done under the protection of the hash lock. The previous code did not do this, which would allow a thread A to destroy the mutex just before a thread B unlocked it. Sorry about that non-sense! Anyway, I cannot seem to find any more issues. > Please note that, although I was discussing this topic in light of a > POSIX OS, the proprietary OS I'm using (ST OS21) does not conform to > POSIX, AFAIK. I am not sure as I am not really familiar with at operating system.
From: Chris M. Thomasson on 29 Oct 2009 18:25 "Chris M. Thomasson" <no(a)spam.invalid> wrote in message news:hccn64$fi5$2(a)news.eternal-september.org... > > "Noob" <root(a)127.0.0.1> wrote in message news:hcbsu6$ocf$1(a)aioe.org... >> Chris M. Thomasson wrote: >> >>> Man! This sucks!! Anyway, I believe you could meet all the requirements, >>> however, it's not going to be pretty. Here is what I hacked together for >>> you so far: >>> >>> http://cpt.pastebin.com/f540aaef5 >> >> Thanks Chris, I'll take a hard look at it. > > Here is updated code which handles the case in which a thread tries to > unlock a mutex that is locked by another thread: > > > http://cpt.pastebin.com/f3044e915 > > > It also fixes a race-condition I overlooked. The unlocking needs to be > done under the protection of the hash lock. The previous code did not do > this, which would allow a thread A to destroy the mutex just before a > thread B unlocked it. > > Sorry about that non-sense! > > > Anyway, I cannot seem to find any more issues. I have implemented the algorithm in Relacy Race Detector: http://relacy.pastebin.com/f227e4245 Relacy likes it! So, this scheme works. BTW, what does the interface look like for the ST OS21 operating system? If it's compatible, then you have a complete solution which will conform to the libraries rules.
From: David Schwartz on 30 Oct 2009 05:40 On Oct 29, 5:42 am, Rainer Weikusat <rweiku...(a)mssgmbh.com> wrote: > A more probable conjecture would be that the library uses the > delete-operation to detect if a mutex has meanwhile been unlocked > without blocking on it and another conjecture based on that and a > short search of the as-always-inaccessible relevant documentation[*] > would be that (at least some versions of) Windows behaves in this way. I don't see how that could make sense. What if the mutex has meanwhile been unlocked but another thread is about to lock it? How do you guarantee that this other thread doesn't lock some other mutex? (Unless you add all the other crufty requirements, like that a mutex handle cannot be a pointer and that they cannot be re-used.) DS
From: Rainer Weikusat on 30 Oct 2009 05:54 David Schwartz <davids(a)webmaster.com> writes: > On Oct 29, 5:42�am, Rainer Weikusat <rweiku...(a)mssgmbh.com> wrote: > >> A more probable conjecture would be that the library uses the >> delete-operation to detect if a mutex has meanwhile been unlocked >> without blocking on it and another conjecture based on that and a >> short search of the as-always-inaccessible relevant documentation[*] >> would be that (at least some versions of) Windows behaves in this way. > > I don't see how that could make sense. What if the mutex has meanwhile > been unlocked but another thread is about to lock it? How do you > guarantee that this other thread doesn't lock some other mutex? Because there are is one thread with a mutex or maybe n threads with mutexes and one 'master thread' 'watching' them (or something similar with clearly separated 'kinds of threads'). That's a possible arrangement where the delete-semantics would make (some) sense. Other arrangements are conceivable but people usually write code to accomplish something definite and not because they are out of their senses (often both to a degree, actually -- once something has been implemented, it is all too clear how it should have been done instead :->, but 'it works' is a very practical quality).
From: Chris M. Thomasson on 30 Oct 2009 14:33
"David Schwartz" <davids(a)webmaster.com> wrote in message news:6b9a4262-aaab-4ea4-9fa0-56d98ae49f58(a)g22g2000prf.googlegroups.com... On Oct 28, 8:04 am, Noob <r...(a)127.0.0.1> wrote: > > >> If delete is called on a locked mutex, the function must return an > > >> error > > >> code to signal the error to the function's caller. > > > That is, IMO, fundamentally busted behavior, unless it only means > > > locked by the calling thread. > > Could you expand on /why/ you think it is busted behavior? > > (I need ammo to try to convince the library authors.) > Either they rely on this behavior or they don't. If they don't rely on > it, why do they make you implement it? If they do rely on it, what > happens when one thread destroys a mutex a split-second before another > thread acquires it? > The only way to make that sensible is to insist you detect an attempt > to lock a destroyed mutex. However, think about what this means. It > means you can never, ever reuse a mutex's identifier. It means a mutex > cannot be a pointer to a structure that is freed when that mutex > ceases to exist. Indeed. The hack I posted also requires that the memory which makes up a mutex cannot be freed. However, one can definetely use reference counting with strong thread saftey to handle this senerio: _________________________________________________________ struct foo { mutex m_lock; // [...]; }; static global_ptr<foo> g_foo; void threads() { for (;;) { local_ptr<foo> l_foo(g_foo); if (! l_foo) { l_foo = new foo; l_foo = g_foo.swap(l_foo); } l_foo->m_lock.lock(); l_foo->m_lock.unlock(); g_foo = NULL; } } _________________________________________________________ `foo' objects are allowed to be dynamically created and destroyed on the fly. Threads don't actually need to care about lifetime management because the reference count handles all of that for them. Although, I have to say that a library which has rules that basically demand using this type of reference counting is pretty darn crappy. |