Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Chapman <[email protected]>
  • Loading branch information
richardkchapman committed Oct 4, 2023
1 parent 0062f82 commit e74cd91
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 131 deletions.
22 changes: 19 additions & 3 deletions roxie/ccd/ccdfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2353,6 +2353,7 @@ class CFileIOArray : implements IFileIOArray, public CInterface
UnsignedArray subfiles;
StringArray filenames;
Int64Array bases;
mutable Int64Array sizes; // Lazy-evaluated and cached
int actualCrc = 0;
unsigned valid = 0;
bool multipleFormatsSeen = false;
Expand Down Expand Up @@ -2418,6 +2419,7 @@ class CFileIOArray : implements IFileIOArray, public CInterface
valid++;
files.append(f);
bases.append(base);
sizes.append(-1); // Calculated if/when needed
if (_actualCrc)
{
if (actualCrc && actualCrc != _actualCrc)
Expand Down Expand Up @@ -2468,14 +2470,28 @@ class CFileIOArray : implements IFileIOArray, public CInterface
totalSize = 0;
ForEachItemIn(idx, files)
{
IFileIO *file = files.item(idx);
if (file)
totalSize += file->size();
totalSize += partSize(idx);
}
}
return totalSize;
}

virtual unsigned __int64 partSize(unsigned idx) const override
{
CriticalBlock b(crit);
__int64 fsize = sizes.item(idx);
if (fsize == -1)
{
IFileIO *file = files.item(idx);
if (file)
fsize = file->size();
else
fsize = 0;
sizes.replace(fsize, idx);
}
return (unsigned __int64) fsize;
}

virtual StringBuffer &getId(StringBuffer &ret) const override
{
CriticalBlock b(crit);
Expand Down
2 changes: 1 addition & 1 deletion roxie/ccd/ccdkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ class BufferedDirectReader : public CDirectReaderBase
while (!_partNo && !thisPart && ++thisPartIdx < maxParts) // MORE
{
thisPart.setown(f->getFilePart(thisPartIdx, thisFileStartPos));
offset_t thisPartSize = thisPart->size();
offset_t thisPartSize = f->partSize(thisPartIdx);
if (thisPart && _startPos >= thisPartSize)
{
_startPos -= thisPartSize;
Expand Down
1 change: 1 addition & 0 deletions roxie/ccd/ccdstate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ interface IFileIOArray : extends IInterface
virtual unsigned numValid() const = 0;
virtual bool isValid(unsigned partNo) const = 0;
virtual unsigned __int64 size() const = 0;
virtual unsigned __int64 partSize(unsigned partNo) const = 0;
virtual StringBuffer &getId(StringBuffer &) const = 0;
virtual const char *queryLogicalFilename(unsigned partNo) const = 0;
virtual int queryActualFormatCrc() const = 0; // Actual format on disk
Expand Down
3 changes: 3 additions & 0 deletions system/jlib/jmutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,14 @@ void CriticalBlockInstrumentation::addStat(cycle_t wait, cycle_t hold, bool wasC
#ifdef HAS_BACKTRACE
void *lbtBuff[numStackEntries+3];
unsigned nFrames = backtrace(lbtBuff, numStackEntries+3);
NonReentrantSpinBlock b(lock);
if (nFrames == numStackEntries+3)
{
Stack *a = (Stack *) (lbtBuff+3);
stacks[*a]++;
}
#else
NonReentrantSpinBlock b(lock);
#endif
if (wasContended)
contended++;
Expand Down
256 changes: 129 additions & 127 deletions system/jlib/jmutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,133 +444,6 @@ template<typename T> class CriticalBlockOf
inline ~CriticalBlockOf() { crit.leave(); }
};

typedef CriticalBlockOf<UninstrumentedCriticalSection> UninstrumentedCriticalBlock;

class CriticalBlockInstrumentation
{
#ifdef HAS_BACKTRACE
static constexpr unsigned numStackEntries = 8;
class Stack
{
public:
void *stack[numStackEntries];
bool operator==(const Stack &other) const
{
return memcmp(stack, other.stack, sizeof(stack)) == 0;
}
};

struct StackHash
{
std::size_t operator()(const Stack& k) const;
};
#endif

public:
CriticalBlockInstrumentation(const char *file, const char *func, unsigned line);
~CriticalBlockInstrumentation();
void addStat(cycle_t wait, cycle_t hold, bool wasContended);
void describe(bool withStack) const;
int compare(const CriticalBlockInstrumentation *other) const;
private:
const char *file;
const char *func;
unsigned line;
cycle_t waitCycles;
cycle_t holdCycles;
unsigned uncontended;
unsigned contended;
#ifdef HAS_BACKTRACE
std::unordered_map<Stack, unsigned, StackHash> stacks;
#endif
};

class InstrumentedCriticalBlock
{
InstrumentedCriticalSection &crit;
public:
InstrumentedCriticalBlock(InstrumentedCriticalSection &c);
~InstrumentedCriticalBlock();
private:
CriticalBlockInstrumentation *inst;
cycle_t start = 0;
cycle_t in = 0;
};

/**
* Critical section delimiter, using scope to define lifetime of
* the lock on a critical section (parameter).
* Unblocks on construction, blocks on destruction.
*/
template<typename T> class CriticalUnblockOf
{
T &crit;
public:
inline CriticalUnblockOf(T &c) : crit(c) { crit.leave(); }
inline ~CriticalUnblockOf() { crit.enter(); }
};

typedef CriticalUnblockOf<UninstrumentedCriticalSection> UninstrumentedCriticalUnblock;
typedef CriticalUnblockOf<InstrumentedCriticalSection> InstrumentedCriticalUnblock;

template<typename T> class CLeavableCriticalBlockOf
{
T &crit;
bool locked = false;
public:
inline CLeavableCriticalBlockOf(T &_crit) : crit(_crit)
{
enter();
}
inline CLeavableCriticalBlockOf(T &_crit, bool lock) : crit(_crit)
{
if (lock)
enter();
}
inline ~CLeavableCriticalBlockOf()
{
if (locked)
crit.leave();
}
inline void enter()
{
if (locked)
return;
locked = true;
crit.enter();
}
inline void leave()
{
if (locked)
{
locked = false;
crit.leave();
}
}
};

typedef CLeavableCriticalBlockOf<UninstrumentedCriticalSection> UninstrumentedLeavableCriticalBlock;
typedef CLeavableCriticalBlockOf<InstrumentedCriticalSection> InstrumentedLeavableCriticalBlock;

#ifdef USE_INSTRUMENTED_CRITSECS
#define __glue(a,b) a ## b
#define glue(a,b) __glue(a,b)

extern thread_local CriticalBlockInstrumentation* __cbinst;

typedef InstrumentedCriticalSection CriticalSection;
typedef InstrumentedCriticalBlock ICriticalBlock;
#define CriticalBlock static CriticalBlockInstrumentation *glue(instrumenter,__LINE__) = new CriticalBlockInstrumentation(__FILE__, __func__, __LINE__); __cbinst = glue(instrumenter,__LINE__); ICriticalBlock
typedef InstrumentedCriticalUnblock CriticalUnblock;
typedef InstrumentedLeavableCriticalBlock CLeavableCriticalBlock;
#else
typedef UninstrumentedCriticalSection CriticalSection;
typedef UninstrumentedCriticalBlock ICriticalBlock;
typedef ICriticalBlock CriticalBlock;
typedef UninstrumentedCriticalUnblock CriticalUnblock;
typedef UninstrumentedLeavableCriticalBlock CLeavableCriticalBlock;
#endif

#ifdef SPINLOCK_USE_MUTEX // for testing

class SpinLock
Expand Down Expand Up @@ -720,6 +593,135 @@ class jlib_decl NonReentrantSpinLock

#endif

typedef CriticalBlockOf<UninstrumentedCriticalSection> UninstrumentedCriticalBlock;

class CriticalBlockInstrumentation
{
#ifdef HAS_BACKTRACE
static constexpr unsigned numStackEntries = 8;
class Stack
{
public:
void *stack[numStackEntries];
bool operator==(const Stack &other) const
{
return memcmp(stack, other.stack, sizeof(stack)) == 0;
}
};

struct StackHash
{
std::size_t operator()(const Stack& k) const;
};
#endif

public:
CriticalBlockInstrumentation(const char *file, const char *func, unsigned line);
~CriticalBlockInstrumentation();
void addStat(cycle_t wait, cycle_t hold, bool wasContended);
void describe(bool withStack) const;
int compare(const CriticalBlockInstrumentation *other) const;
private:
NonReentrantSpinLock lock;
const char *file;
const char *func;
unsigned line;
cycle_t waitCycles;
cycle_t holdCycles;
unsigned uncontended;
unsigned contended;
#ifdef HAS_BACKTRACE
std::unordered_map<Stack, unsigned, StackHash> stacks;
#endif
};

class InstrumentedCriticalBlock
{
InstrumentedCriticalSection &crit;
public:
InstrumentedCriticalBlock(InstrumentedCriticalSection &c);
~InstrumentedCriticalBlock();
private:
CriticalBlockInstrumentation *inst;
cycle_t start = 0;
cycle_t in = 0;
};

/**
* Critical section delimiter, using scope to define lifetime of
* the lock on a critical section (parameter).
* Unblocks on construction, blocks on destruction.
*/
template<typename T> class CriticalUnblockOf
{
T &crit;
public:
inline CriticalUnblockOf(T &c) : crit(c) { crit.leave(); }
inline ~CriticalUnblockOf() { crit.enter(); }
};

typedef CriticalUnblockOf<UninstrumentedCriticalSection> UninstrumentedCriticalUnblock;
typedef CriticalUnblockOf<InstrumentedCriticalSection> InstrumentedCriticalUnblock;

template<typename T> class CLeavableCriticalBlockOf
{
T &crit;
bool locked = false;
public:
inline CLeavableCriticalBlockOf(T &_crit) : crit(_crit)
{
enter();
}
inline CLeavableCriticalBlockOf(T &_crit, bool lock) : crit(_crit)
{
if (lock)
enter();
}
inline ~CLeavableCriticalBlockOf()
{
if (locked)
crit.leave();
}
inline void enter()
{
if (locked)
return;
locked = true;
crit.enter();
}
inline void leave()
{
if (locked)
{
locked = false;
crit.leave();
}
}
};

typedef CLeavableCriticalBlockOf<UninstrumentedCriticalSection> UninstrumentedLeavableCriticalBlock;
typedef CLeavableCriticalBlockOf<InstrumentedCriticalSection> InstrumentedLeavableCriticalBlock;

#ifdef USE_INSTRUMENTED_CRITSECS
#define __glue(a,b) a ## b
#define glue(a,b) __glue(a,b)

extern thread_local CriticalBlockInstrumentation* __cbinst;

typedef InstrumentedCriticalSection CriticalSection;
typedef InstrumentedCriticalBlock ICriticalBlock;
#define CriticalBlock static CriticalBlockInstrumentation *glue(instrumenter,__LINE__) = new CriticalBlockInstrumentation(__FILE__, __func__, __LINE__); __cbinst = glue(instrumenter,__LINE__); ICriticalBlock
typedef InstrumentedCriticalUnblock CriticalUnblock;
typedef InstrumentedLeavableCriticalBlock CLeavableCriticalBlock;
#else
typedef UninstrumentedCriticalSection CriticalSection;
typedef UninstrumentedCriticalBlock ICriticalBlock;
typedef ICriticalBlock CriticalBlock;
typedef UninstrumentedCriticalUnblock CriticalUnblock;
typedef UninstrumentedLeavableCriticalBlock CLeavableCriticalBlock;
#endif


class NonReentrantSpinBlock
{
NonReentrantSpinLock &lock;
Expand Down

0 comments on commit e74cd91

Please sign in to comment.