mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-05-01 22:07:16 +00:00
Enable devices individually over param "enabled"
UNIBUS addr, intr vector, level setable
This commit is contained in:
@@ -1,27 +1,27 @@
|
||||
/* device.cpp - abstract base class for devices
|
||||
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
12-nov-2018 JH entered beta phase
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Abstract device, with or without UNIBUS registers.
|
||||
maybe mass storage controller, storage drive or other UNIBUS device
|
||||
@@ -32,7 +32,7 @@
|
||||
- has a worker()
|
||||
- has a logger
|
||||
- has parameters
|
||||
*/
|
||||
*/
|
||||
#define _DEVICE_CPP_
|
||||
|
||||
#include <string.h>
|
||||
@@ -68,17 +68,17 @@ static void device_worker_pthread_cleanup_handler(void *context) {
|
||||
|
||||
static void *device_worker_pthread_wrapper(void *context) {
|
||||
device_c *device = (device_c *) context;
|
||||
int oldstate ; // not used
|
||||
int oldstate; // not used
|
||||
#define this device // make INFO work
|
||||
// call real worker
|
||||
INFO("%s::worker() started", device->name.value.c_str());
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate) ;
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate) ; //ASYNCH not allowed!
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate); //ASYNCH not allowed!
|
||||
device->worker_terminate = false;
|
||||
device->worker_terminated = false;
|
||||
pthread_cleanup_push(device_worker_pthread_cleanup_handler, device) ;
|
||||
device->worker();
|
||||
pthread_cleanup_pop(1) ; // call cleanup_handler on regular exit
|
||||
pthread_cleanup_push(device_worker_pthread_cleanup_handler, device);
|
||||
device->worker();
|
||||
pthread_cleanup_pop(1); // call cleanup_handler on regular exit
|
||||
// not reached on pthread_cancel()
|
||||
#undef this
|
||||
return NULL;
|
||||
@@ -99,10 +99,13 @@ device_c::device_c() {
|
||||
// creation order of vector vs params?
|
||||
name.parameterized = this;
|
||||
type_name.parameterized = this;
|
||||
enabled.parameterized = this;
|
||||
verbosity.parameterized = this;
|
||||
verbosity.value = *log_level_ptr; // global default value from logger->logsource
|
||||
enabled.value = false; // must be activated by emulation logic/user interaction
|
||||
param_add(&name);
|
||||
param_add(&type_name);
|
||||
param_add(&enabled);
|
||||
param_add(&emulation_speed);
|
||||
param_add(&verbosity);
|
||||
emulation_speed.value = 1;
|
||||
@@ -125,7 +128,27 @@ device_c::~device_c() {
|
||||
mydevices.erase(p);
|
||||
}
|
||||
|
||||
bool device_c::on_param_changed(parameter_c *param) {
|
||||
if (param == &enabled) {
|
||||
if (enabled.new_value)
|
||||
worker_start();
|
||||
else
|
||||
worker_stop();
|
||||
}
|
||||
// all devices forward their "on_param_changed" to parent classes,
|
||||
// until a class rejects a value.
|
||||
// device_c is the grand pratnes and produces "OK" for unknown or passive parameters
|
||||
return true;
|
||||
}
|
||||
|
||||
// search device in global list mydevices[]
|
||||
device_c *device_c::find_by_name(char *name) {
|
||||
list<device_c *>::iterator it;
|
||||
for (it = device_c::mydevices.begin(); it != device_c::mydevices.end(); ++it)
|
||||
if (!strcasecmp((*it)->name.value.c_str(), name))
|
||||
return *it;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// set priority to max, keep policy, return current priority
|
||||
// do not change worker_sched_priority
|
||||
@@ -262,12 +285,13 @@ void device_c::worker_start(void) {
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
// pthread_attr_setstacksize(&attr, 1024*1024);
|
||||
assert(worker_terminated); // do not srtat device worker twiche in parallel!
|
||||
int status = pthread_create(&worker_pthread, &attr, &device_worker_pthread_wrapper,
|
||||
(void *) this);
|
||||
if (status != 0) {
|
||||
FATAL("Failed to create pthread with status = %d", status);
|
||||
}
|
||||
pthread_attr_destroy(&attr) ; // why?
|
||||
pthread_attr_destroy(&attr); // why?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +311,8 @@ void device_c::worker_stop(void) {
|
||||
// if thread is hanging in pthread_cond_wait(): send a cancellation request
|
||||
status = pthread_cancel(worker_pthread);
|
||||
if (status != 0)
|
||||
FATAL("Failed to send cancellation request to worker_pthread with status = %d", status);
|
||||
FATAL("Failed to send cancellation request to worker_pthread with status = %d",
|
||||
status);
|
||||
}
|
||||
|
||||
// !! If crosscompling: this causes a crash in the worker thread
|
||||
|
||||
Reference in New Issue
Block a user