Exemple #1
0
            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;
                }
            }
Exemple #2
0
            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);
                        }
                    }
                }
            }