"Alf P. Steinbach" <
alf.p.s...@gmail.com> writes:
>On 2023-02-05 10:39 PM, Alf P. Steinbach wrote:
>> On 2023-02-05 9:49 PM, Chris M. Thomasson wrote:
>>
>>> Signalling a condition variable while the mutex is locked is not that
>>> efficient unless the condvar has wait morphing. God, I have not
>>> thought about wait morphing for a long time. Thanks for making me
>>> think of it!
>>
>> Thanks. I don't know yet how to handle that with the RAII-based access
>> scheme. Perhaps set a count of number of signals to issue then do that
>> in the Access destructor.
>
>Implementation of that idea, hopefully it makes sense and is technically
>correct:
Leaving aside the odd syntactic choices, what is the function
of the class and why would it be of use? How about providing
an example of use?
I don't recall 'not', 'and' and 'or' being C++ keywords.
What's the difference between "mutex" and "Mutex_lock" types?
Where is the mutex actually acquired? It is released in the
destructor - does the undefined "Mutex_lock" class acquire the
mutex in some misguided attempt to apply RAII to locking?
IME, a critical region generally protects more just queue accesses;
it may also protect other data or make a certain code sequence atomic
with respect to other threads. That's one of the many reasons that
I dislike the application of RAII to locking.
Whatever agent you used to post this wrapped many of the longer lines
which made it even less readable than your nonstandard syntax choices.
m_mutex.lock();
qe = m_queue.pop()
m_mutex_unlock();
seems to be much cleaner and far more readable (and thus more maintainable).
The idea that locking can be solved using RAII universally is unviable.
/**
* Execute I/O Control Blocks queued to this DLP instance.
*
* This is the main loop of the per-DLP instance thread.
*
* Loop until the d_exit flag is set to true.
* Set d_exited flag when the thread terminates to notify
* terminator that the thread terminated successfully.
*/
void
c_dlp::run(void)
{
int diag;
c_dlist pending;
char tname[64];
c_processor::set_this(d_processor);
c_system::set_this(mp->get_system());
c_memory::set_this(mp->get_system()->get_mem());
snprintf(tname, sizeof(tname), "%04lu %s DLP",
d_channel, get_hardware_name());
set_threadname(tname);
pending.init();
lock_thread();
while (!d_exit) {
while (pending.is_empty()) {
c_dlist_iterator di(&d_iocbs);
while (di.next()) {
c_iocb *iocb = (c_iocb *)di.curr();
iocb->remove();
pending.insert(iocb);
}
if (!pending.is_empty()) break;
diag = pthread_cond_wait(&d_wait, &t_threadlock);
if (diag != 0) {
d_logger->log("%04lu/00 Unexpected cond-wait result: %s\n",
d_channel, strerror(diag));
}
if (d_exit) break;
}
if (d_exit) break;
unlock_thread();
c_dlist_iterator worklist(&pending);
while (worklist.next()) {
c_iocb * iocb = (c_iocb *)worklist.curr();
iocb->remove();
switch (iocb->get_op()) {
case IOD_CANCEL:
cancel(iocb);
break;
case IOD_READ:
read(iocb);
break;
case IOD_WRITE:
write(iocb);
break;
case IOD_TEST:
if (iocb->get_op_var1() == IOD_TEST_IDENTIFY) {
set_rd(iocb, IOT_COMPLETE|IOT_EXT_RD_PRESENT,
0x0000, d_testid << 8);
} else {
test(iocb);
}
break;
case IOD_ECHO:
echo(iocb);
break;
}
}
lock_thread();
pending.init();
}
d_exited = true;
unlock_thread();