Hallo Darryl,

after some more reading (your links were really interesting) I hope you don't mi
nd
if I come around with one more question. Perhaps the following code fragments
can serve as an example:

#define USE_MTX
#define BSIZE  8192

volatile int error;
volatile char shared_buf[BSIZE]  /* buffer for data transport */
int *type_p /* describe type of data in buffer */
type_p = (int *) shared_buf;
pthread_mutex_t mtx;

pthread_create(..., transmit_thread, ...);
pthread_create(..., receive_thread, ...);
pthread_create(..., consumer_thread, ...);

transmit_thread {
    int error1;

    while (1) {
#ifdef USE_MTX
pthread_mutex_lock(&mtx);
error1 = error;
pthread_mutex_unlock(&mtx);
#else
error1 = error;
#endif
        if (error1 != 0) break;
        if (transmit() != 0) {  /* transmit yields any error */
#ifdef USE_MTX
pthread_mutex_lock(&mtx);
error = 5;
pthread_mutex_unlock(&mtx);
#else
error = 5;
#endif
        }
    }
}

receive_thread {
    int error1;

    while (1) {
#ifdef USE_MTX
pthread_mutex_lock(&mtx);
error1 = error;
pthread_mutex_unlock(&mtx);
#else
error1 = error;
#endif
        if (error1 != 0) break;
        if (receive_to_buf() != 0) {  /* receive yields any error */
#ifdef USE_MTX
pthread_mutex_lock(&mtx);
error = 5;
pthread_mutex_unlock(&mtx);
#else
error = 5;
#endif
       }
       else {
            *type_p = 10;
            wakeup_consumer_with_cv();
       }
   }
}


consumer_thread {
    int error1;
    waiting_on_cv();
#ifdef USE_MTX
pthread_mutex_lock(&mtx);
error1 = error;
pthread_mutex_unlock(&mtx);
#else
error1 = error;
#endif
    if (error1 == 0) {
        if (*type_p == 10) {
            process_the_buffer();
        }
    }
}


I hope, I didn't do any simple mistakes in writing.
The following is desired:
- transmit and receive threads share the same communication
  and shall work in parallel
- as soon as any error occurrs this would result in
  interrupting the threads in their transmit/receive functions
  The fact that this is due to an error shall be
  communicated by means of the variable error. A thread
  interrupted in transmit or receive shall never retry any
  transmit or receive
- if the receive thread has filled the buffer it wakes up
  the consumer waiting on a cv. The consumer shall then
  find the correct data in the buffer (as long as error is 0).

It is not worth discussing the purpose of the code. It is only
an example to make clear my issue. If I really need a mutex
or similar around any access to error (just to ensure flushing
of the store buffers after an update) this leads to an ugly
code instead of simply writing "while (error == 0)".  Error is
not calculated, it is simply assigned a value. Therefore I
guess one could simply use "error = 5" without a mutex
if only this got visible right away to all other threads.
On the other hand: If I use the mutex would I still need
the volatile keyword to ensure the compiler doesn't
optimize away the access?
And how can I be/make sure that data written to buffer
by receive_thread is completely visible to consumer_thread
after the latter is woken up with the cv?
Perhaps all these questions can be condensed to the question
if I need to define USE_MTX in the example to get a conforming
and portable code that runs on any CPU (at least with Solaris).

I hope very much that these issues are also of interest
to other programmers.
Thank you in advance for your patience and your assistance!
-- 
This message posted from opensolaris.org

Reply via email to