mirror of
https://github.com/akuker/RASCSI.git
synced 2024-06-26 07:29:31 +00:00
Switched to file-based mutex
This commit is contained in:
parent
83a83e9e74
commit
1f178e4f60
|
@ -106,6 +106,10 @@ class BUS : public PinControl
|
|||
// Set SCSI output signal value
|
||||
static const int SEND_NO_DELAY = -1;
|
||||
// Passed into SendHandShake when we don't want to delay
|
||||
|
||||
// This is only applicable for the Virtual bus type
|
||||
virtual bool SharedMemValid() const {return true;}
|
||||
|
||||
private:
|
||||
static const array<phase_t, 8> phase_table;
|
||||
|
||||
|
|
|
@ -115,6 +115,12 @@ class GPIOBUS_Virtual final : public GPIOBUS
|
|||
// Get DAT signal
|
||||
void SetDAT(uint8_t dat) override;
|
||||
// Set DAT signal
|
||||
|
||||
bool SharedMemValid() const override
|
||||
{
|
||||
return signals->is_valid();
|
||||
}
|
||||
|
||||
private:
|
||||
// SCSI I/O signal control
|
||||
void MakeTable() override;
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#include "scsisim_core.h"
|
||||
#include "hal/data_sample_raspberry.h"
|
||||
#include "shared/log.h"
|
||||
#include "shared/piscsi_util.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
#include "hal/data_sample_raspberry.h"
|
||||
|
||||
#include "scsisim_defs.h"
|
||||
#include <iostream>
|
||||
|
@ -124,7 +124,7 @@ bool ScsiSim::ParseArgument(const vector<char*>& args)
|
|||
|
||||
int ScsiSim::run(const vector<char*>& args)
|
||||
{
|
||||
running = true;
|
||||
running = true;
|
||||
scsi_sim = this;
|
||||
|
||||
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
||||
|
@ -146,7 +146,7 @@ int ScsiSim::run(const vector<char*>& args)
|
|||
|
||||
// We just want to run the test client. After we're done, we can
|
||||
// return.
|
||||
if(test_mode){
|
||||
if (test_mode) {
|
||||
TestClient();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -162,24 +162,34 @@ int ScsiSim::run(const vector<char*>& args)
|
|||
signals = make_unique<SharedMemory>(SHARED_MEM_NAME, true);
|
||||
|
||||
uint32_t prev_value = signals->get();
|
||||
int dot_counter = 0;
|
||||
int dot_counter = 0;
|
||||
int char_counter = 0;
|
||||
while (running) {
|
||||
if (enable_debug) {
|
||||
uint32_t new_value = signals->get();
|
||||
|
||||
PrintDifferences(DataSample_Raspberry(new_value), DataSample_Raspberry(prev_value));
|
||||
|
||||
// Note, this won't necessarily print ever data change. It will
|
||||
// just give an indication of activity
|
||||
if (new_value != prev_value) {
|
||||
LOGTRACE("%s Value changed to %08X", __PRETTY_FUNCTION__, new_value);
|
||||
}
|
||||
PrintDifferences(DataSample_Raspberry(new_value), DataSample_Raspberry(prev_value));
|
||||
|
||||
prev_value = new_value;
|
||||
|
||||
if(++dot_counter > 1000){
|
||||
printf(".");
|
||||
dot_counter = 0;
|
||||
}
|
||||
|
||||
if (++dot_counter > 100) {
|
||||
if (char_counter == 0) {
|
||||
std::cout << "\r/" << flush;
|
||||
|
||||
} else if (char_counter == 1) {
|
||||
std::cout << "\r-" << flush;
|
||||
|
||||
} else if (char_counter == 2) {
|
||||
std::cout << "\r\\" << flush;
|
||||
|
||||
} else if (char_counter == 3) {
|
||||
std::cout << "\r|" << flush;
|
||||
}
|
||||
char_counter = (char_counter + 1) % 4;
|
||||
dot_counter = 0;
|
||||
}
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
// [ SCSI Bus Emulator ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#include "hal/gpiobus_factory.h"
|
||||
#include "hal/gpiobus_virtual.h"
|
||||
#include "scsisim_core.h"
|
||||
#include "shared/log.h"
|
||||
#include "shared/piscsi_util.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
#include "hal/gpiobus_factory.h"
|
||||
|
||||
#include "hal/data_sample.h"
|
||||
#include "scsisim_defs.h"
|
||||
|
@ -27,9 +28,6 @@ void ScsiSim::PrintDifferences(const DataSample& current, const DataSample& prev
|
|||
stringstream s;
|
||||
s << "Data changed: <";
|
||||
|
||||
// << setfill('0') << setw(2) << hex << GetBuffer()[0];
|
||||
// logger.Trace(s.str());
|
||||
|
||||
if (current.GetDAT() != previous.GetDAT()) {
|
||||
s << "DAT(" << setw(2) << hex << (int)current.GetDAT() << ") ";
|
||||
}
|
||||
|
@ -69,32 +67,78 @@ void ScsiSim::PrintDifferences(const DataSample& current, const DataSample& prev
|
|||
}
|
||||
}
|
||||
|
||||
void ScsiSim::TestClient(){
|
||||
|
||||
void ScsiSim::TestClient()
|
||||
{
|
||||
LOGINFO("TESTING!!!")
|
||||
int sleep_time = 10000;
|
||||
|
||||
unique_ptr<BUS> bus = GPIOBUS_Factory::Create(BUS::mode_e::INITIATOR);
|
||||
unique_ptr<BUS> bus = GPIOBUS_Factory::Create(BUS::mode_e::TARGET);
|
||||
|
||||
LOGINFO("bus->SetBSY"); bus->SetBSY(1); usleep(sleep_time); bus->SetBSY(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetSEL"); bus->SetSEL(1); usleep(sleep_time); bus->SetSEL(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetATN"); bus->SetATN(1); usleep(sleep_time); bus->SetATN(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetACK"); bus->SetACK(1); usleep(sleep_time); bus->SetACK(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetRST"); bus->SetRST(1); usleep(sleep_time); bus->SetRST(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetMSG"); bus->SetMSG(1); usleep(sleep_time); bus->SetMSG(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetCD"); bus->SetCD(1); usleep(sleep_time); bus->SetCD(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetIO"); bus->SetIO(1); usleep(sleep_time); bus->SetIO(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetREQ"); bus->SetREQ(1); usleep(sleep_time); bus->SetREQ(0); usleep(sleep_time);
|
||||
LOGINFO("bus->SetACT"); bus->SetACT(1); usleep(sleep_time); bus->SetACT(0); usleep(sleep_time);
|
||||
for(uint32_t i = 0; i <= 0xFF; i++){
|
||||
LOGINFO("bus->SetDAT(%02X)", i); bus->SetDAT((uint8_t)i); usleep(sleep_time); bus->SetDAT(0); usleep(sleep_time);
|
||||
if (!bus->SharedMemValid()) {
|
||||
LOGWARN("Unable to set up shared memory region");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGINFO("bus->SetBSY");
|
||||
bus->SetBSY(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetBSY(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetSEL");
|
||||
bus->SetSEL(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetSEL(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetATN");
|
||||
bus->SetATN(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetATN(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetACK");
|
||||
bus->SetACK(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetACK(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetRST");
|
||||
bus->SetRST(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetRST(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetMSG");
|
||||
bus->SetMSG(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetMSG(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetCD");
|
||||
bus->SetCD(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetCD(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetIO");
|
||||
bus->SetIO(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetIO(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetREQ");
|
||||
bus->SetREQ(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetREQ(0);
|
||||
usleep(sleep_time);
|
||||
LOGINFO("bus->SetACT");
|
||||
bus->SetACT(1);
|
||||
usleep(sleep_time);
|
||||
bus->SetACT(0);
|
||||
usleep(sleep_time);
|
||||
for (uint32_t i = 0; i <= 0xFF; i++) {
|
||||
LOGINFO("bus->SetDAT(%02X)", i);
|
||||
bus->SetDAT((uint8_t)i);
|
||||
usleep(sleep_time);
|
||||
bus->SetDAT(0);
|
||||
usleep(sleep_time);
|
||||
}
|
||||
// LOGINFO("bus->SetDAT(0x01)"); bus->SetDAT(1); usleep(sleep_time); bus->SetDAT(0); usleep(sleep_time);
|
||||
// LOGINFO("bus->SetDAT(0xFF)"); bus->SetDAT(1); usleep(sleep_time); bus->SetDAT(0); usleep(sleep_time);
|
||||
|
||||
if (bus != nullptr) {
|
||||
LOGTRACE("%s trying bus cleanup", __PRETTY_FUNCTION__)
|
||||
bus->Cleanup();
|
||||
}
|
||||
|
||||
}
|
|
@ -45,6 +45,22 @@ SharedMemory::SharedMemory(std::string region_name, bool is_primary)
|
|||
return;
|
||||
}
|
||||
LOGINFO("%s Shared memory region successfully memory mapped", __PRETTY_FUNCTION__)
|
||||
|
||||
if (m_primary) {
|
||||
oflag = O_CREAT;
|
||||
} else {
|
||||
oflag = 0;
|
||||
}
|
||||
|
||||
m_lock_name = m_name + "_lock";
|
||||
LOGINFO("%s Open file lock name: %s", __PRETTY_FUNCTION__, m_lock_name.c_str())
|
||||
m_file_lock = open(m_lock_name.c_str(), oflag);
|
||||
|
||||
if (m_file_lock == -1) {
|
||||
LOGWARN("%s Unable to open the file lock (%s). Is scsisim running? Are you running as root?",
|
||||
__PRETTY_FUNCTION__, m_lock_name.c_str())
|
||||
m_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: The normal logging functions can not be used here. The logger objects
|
||||
|
|
|
@ -15,30 +15,38 @@
|
|||
#include <semaphore.h>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <sys/file.h>
|
||||
#include <sys/mman.h>
|
||||
#include <thread>
|
||||
|
||||
#include "shared/log.h"
|
||||
|
||||
#pragma once
|
||||
class SharedMemory
|
||||
{
|
||||
public:
|
||||
SharedMemory(std::string, bool is_primary=false);
|
||||
SharedMemory(std::string, bool is_primary = false);
|
||||
~SharedMemory();
|
||||
|
||||
inline uint32_t get() const
|
||||
{
|
||||
std::shared_lock lock(m_shared_mem->mutex_);
|
||||
return m_shared_mem->value_;
|
||||
uint32_t value;
|
||||
flock(m_file_lock, LOCK_EX);
|
||||
value = m_shared_mem->value_;
|
||||
flock(m_file_lock, LOCK_UN);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void set(uint32_t new_val)
|
||||
{
|
||||
std::unique_lock lock(m_shared_mem->mutex_);
|
||||
flock(m_file_lock, LOCK_EX);
|
||||
m_shared_mem->value_ = new_val;
|
||||
flock(m_file_lock, LOCK_UN);
|
||||
}
|
||||
|
||||
inline void set_bit(int bit_num, int value)
|
||||
{
|
||||
std::unique_lock lock(m_shared_mem->mutex_);
|
||||
flock(m_file_lock, LOCK_EX);
|
||||
if (value) {
|
||||
// Set bit
|
||||
m_shared_mem->value_ |= (1 << bit_num);
|
||||
|
@ -46,22 +54,26 @@ class SharedMemory
|
|||
// Clear bit
|
||||
m_shared_mem->value_ &= ~(1 << bit_num);
|
||||
}
|
||||
flock(m_file_lock, LOCK_UN);
|
||||
}
|
||||
|
||||
inline bool is_valid(){
|
||||
inline bool is_valid()
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef struct lockable_data {
|
||||
mutable std::shared_mutex mutex_;
|
||||
uint32_t value_;
|
||||
} lockable_data_t;
|
||||
|
||||
lockable_data_t* m_shared_mem;
|
||||
|
||||
int m_file_lock;
|
||||
|
||||
bool m_valid;
|
||||
bool m_primary;
|
||||
int m_fd_shared_mem;
|
||||
std::string m_name;
|
||||
std::string m_lock_name;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user