× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Back in the day, I wrote operating systems, and thread safety was an
issue (although I don't think we called it that at the time).

Here's a VERY simplistic example of what might happen.  Let's say you
had a language that compiled an IF statement this way:

IF BYTE1 = BYTE2 THEN GOTO EQUAL
-----

001: CALL JUMPEQUAL(@BYTE1, @BYTE2, @EQUAL)

101: JUMPEQUAL:
102:  MOV *PARM1, A  // Get value pointed to by Parm 1 into register A
103:  MOV *PARM2, B  // Get value pointed to by Parm 2 into register B
104:  CMP A, B       // Compare them 
105:  JMPEQ *PARM3   // Jump to address in Parm 3 if equal

Pretty simple stuff.  Load the memory values into registers, compare
them, and jump to the instruction if equal.  The problem with threads is
that one thread can interrupt the execution of another thread at any
time and run the same code (this is called reentrancy).  So, in this
case, let's say the first thread is executing and byte1 and byte2 are
equal.  It should jump to EQUAL, right?

But if a second thread comes through and interrupts thread one between
instructions 103 and 104 and puts DIFFERENT values into registers A and
B, they might no longer be equal.  And unless the interrupting thread
restores the state of all the registers, the results are unpredicted
when you return control to thread one.

And this saving and restoring of state is essentially the difference
between a task (or job) and a thread.  Saving and restoring state can be
a very costly operation, and threads are designed to be lightweight,
thus they don't do the state save/restore.  And so unless you have a way
of preventing one thread from interrupting another at a crucial point in
the code, you can have this sort of problem.

In the olden days, we would actually disable interrupts during sections
of code that were vulnerable.  That's okay when you own the CPU, but
these days it's a bit more complicated, and you need to "synchronize"
the method, which cause it to lock something (this something is called a
semaphore or mutex) while the vulnerable code is executed.  That way,
two threads can't walk over each other.

Non-thread-safe code is code that cannot handle reentrancy.  These days,
it's not so much about registers as in my Assembly Language 101 example
above; I'm pretty sure that level of state swapping is handled by the
CPU (although ask me about LPAR and L2 cache some day).  Instead, it's
the use of temporary work variables that causes problems (in Java, for
example, instance variables in servlets are not threadsafe).  It takes a
lot of work to make code truly reentrant, and it is especially difficult
to back engineer reentrancy into code originally written without it,
which is probably a big reason why RPG is not threadsafe without
activation groups.

Joe


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.