Upgrade Tcl to 8.6.16
Use versioning to include tag, indication of timestamp and git hash.
Rename to include '7' in the labeling (as it is EL7 based)
Improve log output to keep information about versions used.
Update README.md a little.
Previously this was returning two values, a 'bool' and a data
structure that is created. Now it simply returns the data
structure which makes it easier to reason about who takes
ownership of the memory and when, also that no address-of can
be supplied that has any side-effect that interacts with how
the method works / the returned result.
-extern bool CIFParsePath(CIFPath **pathheadpp, int iscale);
+extern CIFPath *CIFParsePath(int iscale);
Previous related comments:
Easier to reason about, there can be no interaction from *pathheadpp
and the various functions called, which maybe the first concern to
the next reader as visibility of new data is limited to that of a
local variable of the function.
database corruption discovered recently that was uncovered by a
commit on Jan. 31 and is caused by DBMergeNMTiles0() using a
freed tile (reported in github issue #404).
commands, because the keypad numerical values no longer work
regardless of the setting of Num Lock. The keypad arrow keys
alone implement "move", while Shift + keypad arrow keys
implement "stretch".
keyword in LEF. FOREIGN may take an origin offset, but it is
optional. The routine to check that there were no offset values
in the statement incorrectly checked for a NULL token instead of
a value ";" which would indicate an end-of-statement.
This value appears to be initialised at only one spot in the codebase
(under very narrow conditions) but extresist will read it and make
branching decisions based on the uninitialised state.
This 'X' state propagation appears to eventually get processed in
ResWriteExtFile() near where final output formatting is occurring.
It is unclear (at this time) if it perturbs output values in a
problematic way, or if due to algorithmic reasons the data is
discarded before output anyway. I have at least one trace run (with
multiple triggers) of printf formatters handling uninitialised data
in ResWriteExtFile().
Original version would iterate exhaustively, even when it was not
necessary.
This version seeks to do the minimum amount of iteration work based
on the information available.
There are numerous concerns with the original code from a read through.
The #define TX_MAX_OPEN_FILES 20 is badly named, the txCommand.c uses
fd_set to hold active FD for each device, and makes no attempt to bounds
check the 'fd' or 'fd_set' of any TxAdd1InputDevice() is in range.
The real name of this variable should be TX_MAX_INPUT_DEVICES as it
related to the fixed compile time slots available for devices, each input
device must have at least one active FD and it can be in the range
that fd_set allows, which is 0..1023 on linux.
So based on this being the original intention, due to the way the code is
constructed and API calls made available, the file has been reworked
to allow all these considerations at the same time.
Now the design should be FD clean for FDs in the range 0..1023 instead of
being artificially clamped to the first 20 FDs being valid input devices.
Renaming of variable 'i' to 'fd' when it relates to an fd number, so all
uses of FD_XXXX() should use fd, this helps clarify the different domain
the number relates to.
When 'i' is used it relates to the index into the txInputDevRec array.
A large part of the concerns relate to trying to mix the two numbering
domains interchangeably, just using a different name really clears up
understanding to the reader.
Other items that look like errors TxDelete1InputDevice() will
shuffle-remove entries with no active FD, but it is iterating an array
it is also modifying, so it looks like it would have incorrectly skipped
the next item that should be inspected just after a shuffle-removal
occurred.
The various iterators that works from 0..TX_MAX_OPEN_FILES incorrectly
limited the visibility of the routines to the first 20 FDs instead of
the full FD_SETSIZE the TxAddInputDevice API call allows to be
registered.
Passing in TxAdd1InputDevice with an fd above 19 would have resulted in
everything looking successful until select() was used, then the kernel
would likely not sleep/wait because the input fd_set would look blank due
to being clipped by nfds=TX_MAX_OPEN_FILES (instead of that plus 1).
The use of TX_MAX_OPEN_FILES in select instead of TX_MAX_OPEN_FILES+1 for
the 'nfds' field would have meant a device with fd=19 would not work as
the design intended.
The define definition has been removed from the module public header,
I assume it was there for use by another module, but the incorrect
select() usage has been corrected over there in a previous commit.
So now the define can be maintained near the array it relates to.
While the code might looks less 'efficient' as it is now sweeping all
1024 FDs when input devices during add/remove (hopefully there maybe some
compiler auto-vectorization/tzcnt use there). The main event loop is
slightly more 'efficient' (especially for the single device with input
fd=0 case) as it will only check the 1 FD each input event loop iteration,
not check all 20 FDs for data readyness everytime.
This encapsulates the expectation the 'fd' is in the permitted range for
the standard sizes 'fd_set'.
This is so there is some form of detection with issues in this area, if
the RLIMIT_NOFILE limit is increased.
The old code would only work is the fileno(stream) returned an fd
in the range 0 <= 19. It would silently fail, if the fd was in
the range 20..1023 because FD_SET() would work and syscall select()
would be limited to only look at the first 20 fd's. Ignoring any
fd's higher even if set.
This would theoretically cause high CPU usage due to select()
never blocking because there are no active fd's in the fd_set
as far as the kernel interprets the request and the kernel would
immediately return.
But reading the code the 1st argument to select() seems self
limiting for no good reason. It should be fileno(stream)+1 as
documented in man select(2).
Added the assertion as well, because we are trying to allow magic
to use fd's beyond the standard environmental limits. So it
becomes an assertion condition if the fd is outside the range
0..1023 because the FD_SET() macro will not operate correctly /
undefined-behaviour.
I can't find any user of this func in the codebase right now.
If you look at sim/SimRsim.c and the use of select() there, it is
correctly using select() to wait on a single fd over there. This
commit changes this code to match this correct usage.