Skip to content

Commit

Permalink
Don't use Enum.HasFlag
Browse files Browse the repository at this point in the history
The Enum.HasFlag operation results in two boxing operations and is significantly slower than using integer boolean arithmetic. The boxing arises through converting the Enum type to a reference type, so that HasFlag can be called. The second boxing operation is converting the flag to test from an enum type to a reference type for the test.

This change would also slightly reduce CPU load.

Issue: DOTNET-165
  • Loading branch information
jcurl committed Jun 1, 2018
1 parent 93eb323 commit dbca712
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
12 changes: 6 additions & 6 deletions code/Native/UnixNativeSerial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ private unsafe void ReadWriteThread()
m_Name, m_Handle, rwevent, result);
}

if (result.HasFlag(SerialReadWriteEvent.ReadEvent)) {
if ((result & SerialReadWriteEvent.ReadEvent) != 0) {
int rresult;
fixed (byte* b = m_Buffer.Serial.ReadBuffer.Array) {
byte* bo = b + m_Buffer.Serial.ReadBuffer.End;
Expand All @@ -822,7 +822,7 @@ private unsafe void ReadWriteThread()
if (rresult > 0) OnDataReceived(this, new SerialDataReceivedEventArgs(SerialData.Chars));
}

if (result.HasFlag(SerialReadWriteEvent.WriteEvent)) {
if ((result & SerialReadWriteEvent.WriteEvent) != 0) {
int wresult;
fixed (byte * b = m_Buffer.Serial.WriteBuffer.Array) {
byte* bo = b + m_Buffer.Serial.WriteBuffer.Start;
Expand Down Expand Up @@ -910,10 +910,10 @@ private void PinChangeThread()

if (mevent != WaitForModemEvent.None) {
SerialPinChange pins = SerialPinChange.NoChange;
if (mevent.HasFlag(WaitForModemEvent.ClearToSend)) pins |= SerialPinChange.CtsChanged;
if (mevent.HasFlag(WaitForModemEvent.DataCarrierDetect)) pins |= SerialPinChange.CDChanged;
if (mevent.HasFlag(WaitForModemEvent.DataSetReady)) pins |= SerialPinChange.DsrChanged;
if (mevent.HasFlag(WaitForModemEvent.RingIndicator)) pins |= SerialPinChange.Ring;
if ((mevent & WaitForModemEvent.ClearToSend) != 0) pins |= SerialPinChange.CtsChanged;
if ((mevent & WaitForModemEvent.DataCarrierDetect) != 0) pins |= SerialPinChange.CDChanged;
if ((mevent & WaitForModemEvent.DataSetReady) != 0) pins |= SerialPinChange.DsrChanged;
if ((mevent & WaitForModemEvent.RingIndicator) != 0) pins |= SerialPinChange.Ring;
// TODO: Break not implemented

if (Log.SerialTrace(System.Diagnostics.TraceEventType.Verbose))
Expand Down
10 changes: 5 additions & 5 deletions code/Native/WinNativeSerial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ public bool DtrEnable
{
if (m_IsDisposed) throw new ObjectDisposedException("WinNativeSerial");
m_DtrEnable = value;
if (IsOpen && !m_Handshake.HasFlag(Handshake.Dtr)) SetDtrPortSettings(true);
if (IsOpen && (m_Handshake & Handshake.Dtr) == 0) SetDtrPortSettings(true);
}
}

Expand All @@ -602,7 +602,7 @@ public bool RtsEnable
{
if (m_IsDisposed) throw new ObjectDisposedException("WinNativeSerial");
m_RtsEnable = value;
if (IsOpen && !m_Handshake.HasFlag(Handshake.Rts)) SetRtsPortSettings(true);
if (IsOpen && (m_Handshake & Handshake.Rts) == 0) SetRtsPortSettings(true);
}
}

Expand Down Expand Up @@ -765,7 +765,7 @@ public void SetPortSettings()

SetRtsPortSettings(false);
SetDtrPortSettings(false);
if (m_Handshake.HasFlag(Handshake.XOn)) {
if ((m_Handshake & Handshake.XOn) != 0) {
m_CommState.InX = true;
m_CommState.OutX = true;
} else {
Expand All @@ -781,7 +781,7 @@ public void SetPortSettings()

private void SetRtsPortSettings(bool immediate)
{
if (m_Handshake.HasFlag(Handshake.Rts)) {
if ((m_Handshake & Handshake.Rts) != 0) {
m_CommState.OutCtsFlow = true;
m_CommState.RtsControl = RtsControl.Handshake;
} else {
Expand All @@ -797,7 +797,7 @@ private void SetRtsPortSettings(bool immediate)

private void SetDtrPortSettings(bool immediate)
{
if (m_Handshake.HasFlag(Handshake.Dtr)) {
if ((m_Handshake & Handshake.Dtr) != 0) {
m_CommState.OutDsrFlow = true;
m_CommState.DsrSensitivity = true;
m_CommState.DtrControl = DtrControl.Handshake;
Expand Down
36 changes: 20 additions & 16 deletions code/SerialPortStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1895,41 +1895,41 @@ private void HandleEvent(object state)
bool aboveThreshold = m_Buffer.Stream.BytesToRead >= m_RxThreshold;
if (aboveThreshold) {
OnDataReceived(this, new SerialDataReceivedEventArgs(serialDataFlags));
} else if (serialDataFlags.HasFlag(SerialData.Eof)) {
} else if ((serialDataFlags & SerialData.Eof) != 0) {
OnDataReceived(this, new SerialDataReceivedEventArgs(SerialData.Eof));
}

// Modem Pin States
if (serialPinChange.HasFlag(SerialPinChange.CtsChanged)) {
if ((serialPinChange & SerialPinChange.CtsChanged) != 0) {
OnPinChanged(this, new SerialPinChangedEventArgs(SerialPinChange.CtsChanged));
}
if (serialPinChange.HasFlag(SerialPinChange.Ring)) {
if ((serialPinChange & SerialPinChange.Ring) != 0) {
OnPinChanged(this, new SerialPinChangedEventArgs(SerialPinChange.Ring));
}
if (serialPinChange.HasFlag(SerialPinChange.CDChanged)) {
if ((serialPinChange & SerialPinChange.CDChanged) != 0) {
OnPinChanged(this, new SerialPinChangedEventArgs(SerialPinChange.CDChanged));
}
if (serialPinChange.HasFlag(SerialPinChange.DsrChanged)) {
if ((serialPinChange & SerialPinChange.DsrChanged) != 0) {
OnPinChanged(this, new SerialPinChangedEventArgs(SerialPinChange.DsrChanged));
}
if (serialPinChange.HasFlag(SerialPinChange.Break)) {
if ((serialPinChange & SerialPinChange.Break) != 0) {
OnPinChanged(this, new SerialPinChangedEventArgs(SerialPinChange.Break));
}

// Error States
if (serialErrorFlags.HasFlag(SerialError.TXFull)) {
if ((serialErrorFlags & SerialError.TXFull) != 0) {
OnCommError(this, new SerialErrorReceivedEventArgs(SerialError.TXFull));
}
if (serialErrorFlags.HasFlag(SerialError.Frame)) {
if ((serialErrorFlags & SerialError.Frame) != 0) {
OnCommError(this, new SerialErrorReceivedEventArgs(SerialError.Frame));
}
if (serialErrorFlags.HasFlag(SerialError.RXParity)) {
if ((serialErrorFlags & SerialError.RXParity) != 0) {
OnCommError(this, new SerialErrorReceivedEventArgs(SerialError.RXParity));
}
if (serialErrorFlags.HasFlag(SerialError.Overrun)) {
if ((serialErrorFlags & SerialError.Overrun) != 0) {
OnCommError(this, new SerialErrorReceivedEventArgs(SerialError.Overrun));
}
if (serialErrorFlags.HasFlag(SerialError.RXOver)) {
if ((serialErrorFlags & SerialError.RXOver) != 0) {
OnCommError(this, new SerialErrorReceivedEventArgs(SerialError.RXOver));
}
}
Expand Down Expand Up @@ -2021,36 +2021,40 @@ public override string ToString()

string dsrStatus;
try {
dsrStatus = Handshake.HasFlag(Handshake.Dtr) ? "hs" : (IsOpen ? (DsrHolding ? "on" : "off") : "-");
dsrStatus = ((Handshake & Handshake.Dtr) != 0) ?
"hs" : (IsOpen ? (DsrHolding ? "on" : "off") : "-");
} catch (IOException) {
dsrStatus = "err";
}

string ctsStatus;
try {
ctsStatus = Handshake.HasFlag(Handshake.Rts) ? "hs" : (IsOpen ? (CtsHolding ? "on" : "off") : "-");
ctsStatus = ((Handshake & Handshake.Rts) != 0) ?
"hs" : (IsOpen ? (CtsHolding ? "on" : "off") : "-");
} catch (IOException) {
ctsStatus = "err";
}

string dtrStatus;
try {
dtrStatus = Handshake.HasFlag(Handshake.Dtr) ? "hs" : (IsOpen ? (DtrEnable ? "on" : "off") : "-");
dtrStatus = ((Handshake & Handshake.Dtr) != 0) ?
"hs" : (IsOpen ? (DtrEnable ? "on" : "off") : "-");
} catch (IOException) {
dtrStatus = "err";
}

string rtsStatus;
try {
rtsStatus = Handshake.HasFlag(Handshake.Rts) ? "hs" : (IsOpen ? (RtsEnable ? "on" : "off") : "-");
rtsStatus = ((Handshake & Handshake.Rts) != 0) ?
"hs" : (IsOpen ? (RtsEnable ? "on" : "off") : "-");
} catch (IOException) {
rtsStatus = "err";
}

return string.Format("{0}:{1},{2},{3},{4},to={5},xon={6},idsr={7},icts={8},odtr={9},orts={10}",
PortName, BaudRate, DataBits, p, s,
TxContinueOnXOff ? "on" : "off",
Handshake.HasFlag(Handshake.XOn) ? "on" : "off",
((Handshake & Handshake.XOn) != 0) ? "on" : "off",
dsrStatus, ctsStatus, dtrStatus, rtsStatus);
}
}
Expand Down

0 comments on commit dbca712

Please sign in to comment.