#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef enum
{
InstrNop,
InstrHalt,
InstrSetVarNum,
InstrJumpVarZero,
InstrJumpVarNonzero,
InstrJump,
InstrIncVar,
InstrDecVar,
InstrXorVarNum,
} tInstr;
int ExecuteInstruction(unsigned* Vars, const unsigned* Program, unsigned* Position)
{
switch (Program[*Position])
{
default:
case InstrHalt:
return 0;
case InstrNop:
(*Position)++;
break;
case InstrSetVarNum:
Vars[Program[*Position + 1]] = Program[*Position + 2];
(*Position) += 3;
break;
case InstrXorVarNum:
Vars[Program[*Position + 1]] ^= Program[*Position + 2];
(*Position) += 3;
break;
case InstrJumpVarZero:
if (Vars[Program[*Position + 1]] == 0)
(*Position) = Program[*Position + 2];
else
(*Position) += 3;
break;
case InstrJumpVarNonzero:
if (Vars[Program[*Position + 1]] != 0)
(*Position) = Program[*Position + 2];
else
(*Position) += 3;
break;
case InstrJump:
(*Position) = Program[*Position + 1];
break;
case InstrIncVar:
Vars[Program[*Position + 1]]++;
(*Position) += 2;
break;
case InstrDecVar:
Vars[Program[*Position + 1]]--;
(*Position) += 2;
break;
}
return 1;
}
typedef enum
{
VarGlobal,
VarCnt0,
VarCnt1,
VarFlag0,
VarFlag1,
VarTurn,
VarIdxMax
} tVarIdx;
unsigned Vars[VarIdxMax];
#define USE_PETERSON 01
#define SWAP_CHECKS 01
const unsigned Program0[] =
{
// cnt0 = 1000;
InstrSetVarNum, VarCnt0, 1000,
// 3:
#if USE_PETERSON
// flag[0] = 1;
InstrSetVarNum, VarFlag0, 1,
// turn = 1;
InstrSetVarNum, VarTurn, 1,
// 9:
// while (flag[1] == 1 && turn == 1) {}
#if SWAP_CHECKS
InstrJumpVarZero, VarTurn, 17,
InstrJumpVarZero, VarFlag1, 17,
#else
InstrJumpVarZero, VarFlag1, 17,
InstrJumpVarZero, VarTurn, 17,
#endif
InstrJump, 9,
// 17:
#endif
// Critical section starts
// global ^= 0x5555;
// global ^= 0x5555;
// global++;
InstrXorVarNum, VarGlobal, 0x5555,
InstrXorVarNum, VarGlobal, 0x5555,
InstrIncVar, VarGlobal,
// Critical section ends
#if USE_PETERSON
// flag[0] = 0;
InstrSetVarNum, VarFlag0, 0,
#endif
// cnt0--;
InstrDecVar, VarCnt0,
// if (cnt0 == 0) goto 3;
InstrJumpVarNonzero, VarCnt0, 3,
// end
InstrHalt
};
const unsigned Program1[] =
{
// cnt1 = 1000;
InstrSetVarNum, VarCnt1, 1000,
// 3:
#if USE_PETERSON
// flag[1] = 1;
InstrSetVarNum, VarFlag1, 1,
// turn = 0;
InstrSetVarNum, VarTurn, 0,
// 9:
// while (flag[0] == 1 && turn == 0) {}
#if SWAP_CHECKS
InstrJumpVarNonzero, VarTurn, 17,
InstrJumpVarZero, VarFlag0, 17,
#else
InstrJumpVarZero, VarFlag0, 17,
InstrJumpVarNonzero, VarTurn, 17,
#endif
InstrJump, 9,
// 17:
#endif
// Critical section starts
// global ^= 0xAAAA;
// global ^= 0xAAAA;
// global++;
InstrXorVarNum, VarGlobal, 0xAAAA,
InstrXorVarNum, VarGlobal, 0xAAAA,
InstrIncVar, VarGlobal,
// Critical section ends
#if USE_PETERSON
// flag[1] = 0;
InstrSetVarNum, VarFlag1, 0,
#endif
// cnt1--;
InstrDecVar, VarCnt1,
// if (cnt1 == 0) goto 3;
InstrJumpVarNonzero, VarCnt1, 3,
// end
InstrHalt
};
void Simulate(void)
{
unsigned pos0 = 0, pos1 = 0;
while (Program0[pos0] != InstrHalt ||
Program1[pos1] != InstrHalt)
{
int cnt;
while (cnt--)
if (!ExecuteInstruction(Vars, Program0, &pos0))
break;
while (cnt--)
if (!ExecuteInstruction(Vars, Program1, &pos1))
break;
}
}
int main(void)
{
Simulate();
printf("VarGlobal = %u\n", Vars
[VarGlobal
]); return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHRpbWUuaD4KCnR5cGVkZWYgZW51bQp7CiAgSW5zdHJOb3AsCiAgSW5zdHJIYWx0LAogIEluc3RyU2V0VmFyTnVtLAogIEluc3RySnVtcFZhclplcm8sCiAgSW5zdHJKdW1wVmFyTm9uemVybywKICBJbnN0ckp1bXAsCiAgSW5zdHJJbmNWYXIsCiAgSW5zdHJEZWNWYXIsCiAgSW5zdHJYb3JWYXJOdW0sCn0gdEluc3RyOwoKaW50IEV4ZWN1dGVJbnN0cnVjdGlvbih1bnNpZ25lZCogVmFycywgY29uc3QgdW5zaWduZWQqIFByb2dyYW0sIHVuc2lnbmVkKiBQb3NpdGlvbikKewogIHN3aXRjaCAoUHJvZ3JhbVsqUG9zaXRpb25dKQogIHsKICBkZWZhdWx0OgogIGNhc2UgSW5zdHJIYWx0OgogICAgcmV0dXJuIDA7CgogIGNhc2UgSW5zdHJOb3A6CiAgICAoKlBvc2l0aW9uKSsrOwogICAgYnJlYWs7CgogIGNhc2UgSW5zdHJTZXRWYXJOdW06CiAgICBWYXJzW1Byb2dyYW1bKlBvc2l0aW9uICsgMV1dID0gUHJvZ3JhbVsqUG9zaXRpb24gKyAyXTsKICAgICgqUG9zaXRpb24pICs9IDM7CiAgICBicmVhazsKCiAgY2FzZSBJbnN0clhvclZhck51bToKICAgIFZhcnNbUHJvZ3JhbVsqUG9zaXRpb24gKyAxXV0gXj0gUHJvZ3JhbVsqUG9zaXRpb24gKyAyXTsKICAgICgqUG9zaXRpb24pICs9IDM7CiAgICBicmVhazsKCiAgY2FzZSBJbnN0ckp1bXBWYXJaZXJvOgogICAgaWYgKFZhcnNbUHJvZ3JhbVsqUG9zaXRpb24gKyAxXV0gPT0gMCkKICAgICAgKCpQb3NpdGlvbikgPSBQcm9ncmFtWypQb3NpdGlvbiArIDJdOwogICAgZWxzZQogICAgICAoKlBvc2l0aW9uKSArPSAzOwogICAgYnJlYWs7CgogIGNhc2UgSW5zdHJKdW1wVmFyTm9uemVybzoKICAgIGlmIChWYXJzW1Byb2dyYW1bKlBvc2l0aW9uICsgMV1dICE9IDApCiAgICAgICgqUG9zaXRpb24pID0gUHJvZ3JhbVsqUG9zaXRpb24gKyAyXTsKICAgIGVsc2UKICAgICAgKCpQb3NpdGlvbikgKz0gMzsKICAgIGJyZWFrOwoKICBjYXNlIEluc3RySnVtcDoKICAgICgqUG9zaXRpb24pID0gUHJvZ3JhbVsqUG9zaXRpb24gKyAxXTsKICAgIGJyZWFrOwoKICBjYXNlIEluc3RySW5jVmFyOgogICAgVmFyc1tQcm9ncmFtWypQb3NpdGlvbiArIDFdXSsrOwogICAgKCpQb3NpdGlvbikgKz0gMjsKICAgIGJyZWFrOwoKICBjYXNlIEluc3RyRGVjVmFyOgogICAgVmFyc1tQcm9ncmFtWypQb3NpdGlvbiArIDFdXS0tOwogICAgKCpQb3NpdGlvbikgKz0gMjsKICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIDE7Cn0KCnR5cGVkZWYgZW51bQp7CiAgVmFyR2xvYmFsLAoKICBWYXJDbnQwLAogIFZhckNudDEsCgogIFZhckZsYWcwLAogIFZhckZsYWcxLAogIFZhclR1cm4sCgogIFZhcklkeE1heAp9IHRWYXJJZHg7Cgp1bnNpZ25lZCBWYXJzW1ZhcklkeE1heF07CgojZGVmaW5lIFVTRV9QRVRFUlNPTiAwMQojZGVmaW5lIFNXQVBfQ0hFQ0tTIDAxCgpjb25zdCB1bnNpZ25lZCBQcm9ncmFtMFtdID0KewogIC8vIGNudDAgPSAxMDAwOwogIEluc3RyU2V0VmFyTnVtLCBWYXJDbnQwLCAxMDAwLAoKLy8gMzoKI2lmIFVTRV9QRVRFUlNPTgogIC8vIGZsYWdbMF0gPSAxOwogIEluc3RyU2V0VmFyTnVtLCBWYXJGbGFnMCwgMSwKICAvLyB0dXJuID0gMTsKICBJbnN0clNldFZhck51bSwgVmFyVHVybiwgMSwKLy8gOToKICAvLyB3aGlsZSAoZmxhZ1sxXSA9PSAxICYmIHR1cm4gPT0gMSkge30KI2lmIFNXQVBfQ0hFQ0tTCiAgSW5zdHJKdW1wVmFyWmVybywgVmFyVHVybiwgMTcsCiAgSW5zdHJKdW1wVmFyWmVybywgVmFyRmxhZzEsIDE3LAojZWxzZQogIEluc3RySnVtcFZhclplcm8sIFZhckZsYWcxLCAxNywKICBJbnN0ckp1bXBWYXJaZXJvLCBWYXJUdXJuLCAxNywKI2VuZGlmCiAgSW5zdHJKdW1wLCA5LAovLyAxNzoKI2VuZGlmCgovLyBDcml0aWNhbCBzZWN0aW9uIHN0YXJ0cwogIC8vIGdsb2JhbCBePSAweDU1NTU7CiAgLy8gZ2xvYmFsIF49IDB4NTU1NTsKICAvLyBnbG9iYWwrKzsKICBJbnN0clhvclZhck51bSwgVmFyR2xvYmFsLCAweDU1NTUsCiAgSW5zdHJYb3JWYXJOdW0sIFZhckdsb2JhbCwgMHg1NTU1LAogIEluc3RySW5jVmFyLCBWYXJHbG9iYWwsCi8vIENyaXRpY2FsIHNlY3Rpb24gZW5kcwoKI2lmIFVTRV9QRVRFUlNPTgogIC8vIGZsYWdbMF0gPSAwOwogIEluc3RyU2V0VmFyTnVtLCBWYXJGbGFnMCwgMCwKI2VuZGlmCgogIC8vIGNudDAtLTsKICBJbnN0ckRlY1ZhciwgVmFyQ250MCwKICAvLyBpZiAoY250MCA9PSAwKSBnb3RvIDM7CiAgSW5zdHJKdW1wVmFyTm9uemVybywgVmFyQ250MCwgMywKCiAgLy8gZW5kCiAgSW5zdHJIYWx0Cn07Cgpjb25zdCB1bnNpZ25lZCBQcm9ncmFtMVtdID0KewogIC8vIGNudDEgPSAxMDAwOwogIEluc3RyU2V0VmFyTnVtLCBWYXJDbnQxLCAxMDAwLAoKLy8gMzoKI2lmIFVTRV9QRVRFUlNPTgogIC8vIGZsYWdbMV0gPSAxOwogIEluc3RyU2V0VmFyTnVtLCBWYXJGbGFnMSwgMSwKICAvLyB0dXJuID0gMDsKICBJbnN0clNldFZhck51bSwgVmFyVHVybiwgMCwKLy8gOToKICAvLyB3aGlsZSAoZmxhZ1swXSA9PSAxICYmIHR1cm4gPT0gMCkge30KI2lmIFNXQVBfQ0hFQ0tTCiAgSW5zdHJKdW1wVmFyTm9uemVybywgVmFyVHVybiwgMTcsCiAgSW5zdHJKdW1wVmFyWmVybywgVmFyRmxhZzAsIDE3LAojZWxzZQogIEluc3RySnVtcFZhclplcm8sIFZhckZsYWcwLCAxNywKICBJbnN0ckp1bXBWYXJOb256ZXJvLCBWYXJUdXJuLCAxNywKI2VuZGlmCiAgSW5zdHJKdW1wLCA5LAovLyAxNzoKI2VuZGlmCgovLyBDcml0aWNhbCBzZWN0aW9uIHN0YXJ0cwogIC8vIGdsb2JhbCBePSAweEFBQUE7CiAgLy8gZ2xvYmFsIF49IDB4QUFBQTsKICAvLyBnbG9iYWwrKzsKICBJbnN0clhvclZhck51bSwgVmFyR2xvYmFsLCAweEFBQUEsCiAgSW5zdHJYb3JWYXJOdW0sIFZhckdsb2JhbCwgMHhBQUFBLAogIEluc3RySW5jVmFyLCBWYXJHbG9iYWwsCi8vIENyaXRpY2FsIHNlY3Rpb24gZW5kcwoKI2lmIFVTRV9QRVRFUlNPTgogIC8vIGZsYWdbMV0gPSAwOwogIEluc3RyU2V0VmFyTnVtLCBWYXJGbGFnMSwgMCwKI2VuZGlmCgogIC8vIGNudDEtLTsKICBJbnN0ckRlY1ZhciwgVmFyQ250MSwKICAvLyBpZiAoY250MSA9PSAwKSBnb3RvIDM7CiAgSW5zdHJKdW1wVmFyTm9uemVybywgVmFyQ250MSwgMywKCiAgLy8gZW5kCiAgSW5zdHJIYWx0Cn07Cgp2b2lkIFNpbXVsYXRlKHZvaWQpCnsKICB1bnNpZ25lZCBwb3MwID0gMCwgcG9zMSA9IDA7CgogIHdoaWxlIChQcm9ncmFtMFtwb3MwXSAhPSBJbnN0ckhhbHQgfHwKICAgICAgICAgUHJvZ3JhbTFbcG9zMV0gIT0gSW5zdHJIYWx0KQogIHsKICAgIGludCBjbnQ7CgogICAgY250ID0gcmFuZCgpICUgNTA7CiAgICB3aGlsZSAoY250LS0pCiAgICAgIGlmICghRXhlY3V0ZUluc3RydWN0aW9uKFZhcnMsIFByb2dyYW0wLCAmcG9zMCkpCiAgICAgICAgYnJlYWs7CgogICAgY250ID0gcmFuZCgpICUgNTA7CiAgICB3aGlsZSAoY250LS0pCiAgICAgIGlmICghRXhlY3V0ZUluc3RydWN0aW9uKFZhcnMsIFByb2dyYW0xLCAmcG9zMSkpCiAgICAgICAgYnJlYWs7CiAgfQp9CgppbnQgbWFpbih2b2lkKQp7CiAgc3JhbmQodGltZShOVUxMKSk7CiAgU2ltdWxhdGUoKTsKICBwcmludGYoIlZhckdsb2JhbCA9ICV1XG4iLCBWYXJzW1Zhckdsb2JhbF0pOwogIHJldHVybiAwOwp9Cg==