public void Set(long soffset, byte[] src, int srcoffset, int length) { for (; ;) { int slaveindex = (int)(soffset / parent.blocksize); long slaveoffset = soffset % parent.blocksize; long spill = (slaveoffset + (long)length) - parent.blocksize; int slavelength = length; if (spill > 0) { if (spill > int.MaxValue) { throw new Exception("SlaveMemory: spill overflow"); } slavelength -= (int)spill; } unsafe { ComBuf cb = combufs[slaveindex]; byte * com = (byte *)cb.pview; Int64ToBytes(slaveoffset, com, 1); Int32ToBytes(slavelength, com, 1 + 8); pmemcpy(com + 1 + 8 + 4, src, srcoffset, slavelength); com[0] = 2; // Write cb.xsignal(); #if SPINWAIT_RETURN for (; ;) // Spin lock for completion. { System.Threading.Thread.SpinWait(8); if (255 == com[0]) { break; } } #else cb.waitreturnsignal(); #endif } if (spill <= 0) { break; } soffset += slavelength; srcoffset += slavelength; length -= slavelength; } }
public void Set(List <Batch> bat) { unsafe { _batspill.Clear(); for (int curslaveindex = 0; curslaveindex < parent.slaves.Count; curslaveindex++) { ComBuf cb = combufs[curslaveindex]; byte * com = (byte *)cb.pview; byte * comnext = com; byte * comend = com + 1 + 8 + 4 + parent.maxpacketsize; for (int ib = 0; ib < bat.Count; ib++) { int slaveindex = (int)(bat[ib].soffset / parent.blocksize); if (slaveindex == curslaveindex) { long slaveoffset = bat[ib].soffset % parent.blocksize; long spill = (slaveoffset + (long)bat[ib].length) - parent.blocksize; int slavelength = bat[ib].length; if (spill > 0) { #if DEBUG parent._batchspilled = true; #endif if (spill > int.MaxValue) { throw new Exception("SlaveMemory: spill overflow"); } _batspill.Add(bat[ib]); continue; // This one spills; skip it for now. } // ... batch it up... if (comnext + 1 + 8 + 4 + slavelength + 1 > comend) { throw new SlaveMemoryException("Communication buffer overflow: batched too much memory"); } comnext[0] = 4; // Batch write Int64ToBytes(slaveoffset, comnext, 1); Int32ToBytes(slavelength, comnext, 1 + 8); pmemcpy(comnext + 1 + 8 + 4, bat[ib].dest, bat[ib].destoffset, slavelength); comnext += 1 + 8 + 4 + slavelength; } } if (comnext != com) { comnext[0] = 255; // End of batch. cb.xsignal(); #if SPINWAIT_RETURN for (; ;) // Spin lock for result. { System.Threading.Thread.SpinWait(8); if (255 == com[0]) { break; } } #else cb.waitreturnsignal(); #endif } } if (0 != _batspill.Count) { for (int i = 0; i < _batspill.Count; i++) { Set(_batspill[i].soffset, _batspill[i].dest, _batspill[i].destoffset, _batspill[i].length); } } } }