Use an object array for synchronising on internal chunk sections rather than the sections array itself.

- Synchronising on full sections synchronises on the global FULL instance (bad)
- Synchronising on empty sections synchronises on the local empty instance (bad)
- Leads to needless thread locking, and raises the possibility of cyclic locks considerably
Dieser Commit ist enthalten in:
dordsor21 2021-09-15 01:20:04 +01:00 committet von GitHub
Ursprung e989a4ebb0
Commit f10dbe7387
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
3 geänderte Dateien mit 27 neuen und 12 gelöschten Zeilen

Datei anzeigen

@ -40,7 +40,7 @@ public abstract class CharBlocks implements IBlocks {
@Override @Override
public char[] get(CharBlocks blocks, int layer, boolean aggressive) { public char[] get(CharBlocks blocks, int layer, boolean aggressive) {
synchronized (this) { synchronized (blocks.sectionLocks[layer]) {
char[] arr = blocks.blocks[layer]; char[] arr = blocks.blocks[layer];
if (arr == null) { if (arr == null) {
arr = blocks.blocks[layer] = blocks.update(layer, null, aggressive); arr = blocks.blocks[layer] = blocks.update(layer, null, aggressive);
@ -67,6 +67,7 @@ public abstract class CharBlocks implements IBlocks {
}; };
public char[][] blocks; public char[][] blocks;
public Section[] sections; public Section[] sections;
public Object[] sectionLocks;
protected int minSectionPosition; protected int minSectionPosition;
protected int maxSectionPosition; protected int maxSectionPosition;
protected int sectionCount; protected int sectionCount;
@ -80,8 +81,10 @@ public abstract class CharBlocks implements IBlocks {
this.sectionCount = maxSectionPosition - minSectionPosition + 1; this.sectionCount = maxSectionPosition - minSectionPosition + 1;
blocks = new char[sectionCount][]; blocks = new char[sectionCount][];
sections = new Section[sectionCount]; sections = new Section[sectionCount];
sectionLocks = new Object[sectionCount];
for (int i = 0; i < sectionCount; i++) { for (int i = 0; i < sectionCount; i++) {
sections[i] = empty; sections[i] = empty;
sectionLocks[i] = new Object();
} }
} }
@ -99,12 +102,14 @@ public abstract class CharBlocks implements IBlocks {
} }
@Override @Override
public synchronized boolean trim(boolean aggressive, int layer) { public boolean trim(boolean aggressive, int layer) {
boolean result = true; boolean result = true;
if (!sections[layer].isFull() && blocks[layer] != null) { synchronized (sectionLocks[layer]) {
blocks[layer] = null; if (!sections[layer].isFull() && blocks[layer] != null) {
} else { blocks[layer] = null;
result = false; } else {
result = false;
}
} }
return result; return result;
} }
@ -117,12 +122,14 @@ public abstract class CharBlocks implements IBlocks {
return null; return null;
} }
public synchronized void reset(int layer) { public void reset(int layer) {
layer -= minSectionPosition; layer -= minSectionPosition;
sections[layer] = empty; synchronized (sectionLocks[layer]) {
sections[layer] = empty;
}
} }
public synchronized char[] update(int layer, char[] data, boolean aggressive) { public char[] update(int layer, char[] data, boolean aggressive) {
if (data == null) { if (data == null) {
return new char[4096]; return new char[4096];
} }
@ -142,7 +149,7 @@ public abstract class CharBlocks implements IBlocks {
@Override @Override
public char[] load(int layer) { public char[] load(int layer) {
layer -= minSectionPosition; layer -= minSectionPosition;
synchronized (sections[layer]) { synchronized (sectionLocks[layer]) {
return sections[layer].get(this, layer); return sections[layer].get(this, layer);
} }
} }
@ -208,7 +215,7 @@ public abstract class CharBlocks implements IBlocks {
return sections[layer].get(this, layer, index); return sections[layer].get(this, layer, index);
} }
public synchronized final void set(int layer, int index, char value) throws public final void set(int layer, int index, char value) throws
ArrayIndexOutOfBoundsException { ArrayIndexOutOfBoundsException {
layer -= minSectionPosition; layer -= minSectionPosition;
sections[layer].set(this, layer, index, value); sections[layer].set(this, layer, index, value);
@ -231,7 +238,7 @@ public abstract class CharBlocks implements IBlocks {
return section[index]; return section[index];
} }
public final void set(CharBlocks blocks, int layer, int index, char value) { public final synchronized void set(CharBlocks blocks, int layer, int index, char value) {
get(blocks, layer)[index] = value; get(blocks, layer)[index] = value;
} }

Datei anzeigen

@ -331,13 +331,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
sectionCount += diff; sectionCount += diff;
char[][] tmpBlocks = new char[sectionCount][]; char[][] tmpBlocks = new char[sectionCount][];
Section[] tmpSections = new Section[sectionCount]; Section[] tmpSections = new Section[sectionCount];
Object[] tmpSectionLocks = new Object[sectionCount];
System.arraycopy(blocks, 0, tmpBlocks, diff, blocks.length); System.arraycopy(blocks, 0, tmpBlocks, diff, blocks.length);
System.arraycopy(sections, 0, tmpSections, diff, sections.length); System.arraycopy(sections, 0, tmpSections, diff, sections.length);
System.arraycopy(sectionLocks, 0, tmpSectionLocks, diff, sections.length);
for (int i = 0; i < diff; i++) { for (int i = 0; i < diff; i++) {
tmpSections[i] = empty; tmpSections[i] = empty;
tmpSectionLocks[i] = new Object();
} }
blocks = tmpBlocks; blocks = tmpBlocks;
sections = tmpSections; sections = tmpSections;
sectionLocks = tmpSectionLocks;
minSectionPosition = layer; minSectionPosition = layer;
if (biomes != null) { if (biomes != null) {
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64]; BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
@ -359,13 +363,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
sectionCount += diff; sectionCount += diff;
char[][] tmpBlocks = new char[sectionCount][]; char[][] tmpBlocks = new char[sectionCount][];
Section[] tmpSections = new Section[sectionCount]; Section[] tmpSections = new Section[sectionCount];
Object[] tmpSectionLocks = new Object[sectionCount];
System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length); System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
System.arraycopy(sections, 0, tmpSections, 0, sections.length); System.arraycopy(sections, 0, tmpSections, 0, sections.length);
System.arraycopy(sectionLocks, 0, tmpSectionLocks, 0, sections.length);
for (int i = sectionCount - diff; i < sectionCount; i++) { for (int i = sectionCount - diff; i < sectionCount; i++) {
tmpSections[i] = empty; tmpSections[i] = empty;
tmpSectionLocks[i] = new Object();
} }
blocks = tmpBlocks; blocks = tmpBlocks;
sections = tmpSections; sections = tmpSections;
sectionLocks = tmpSectionLocks;
maxSectionPosition = layer; maxSectionPosition = layer;
if (biomes != null) { if (biomes != null) {
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64]; BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];