fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. typedef enum
  6. {
  7. InstrNop,
  8. InstrHalt,
  9. InstrSetVarNum,
  10. InstrJumpVarZero,
  11. InstrJumpVarNonzero,
  12. InstrJump,
  13. InstrIncVar,
  14. InstrDecVar,
  15. InstrXorVarNum,
  16. } tInstr;
  17.  
  18. int ExecuteInstruction(unsigned* Vars, const unsigned* Program, unsigned* Position)
  19. {
  20. switch (Program[*Position])
  21. {
  22. default:
  23. case InstrHalt:
  24. return 0;
  25.  
  26. case InstrNop:
  27. (*Position)++;
  28. break;
  29.  
  30. case InstrSetVarNum:
  31. Vars[Program[*Position + 1]] = Program[*Position + 2];
  32. (*Position) += 3;
  33. break;
  34.  
  35. case InstrXorVarNum:
  36. Vars[Program[*Position + 1]] ^= Program[*Position + 2];
  37. (*Position) += 3;
  38. break;
  39.  
  40. case InstrJumpVarZero:
  41. if (Vars[Program[*Position + 1]] == 0)
  42. (*Position) = Program[*Position + 2];
  43. else
  44. (*Position) += 3;
  45. break;
  46.  
  47. case InstrJumpVarNonzero:
  48. if (Vars[Program[*Position + 1]] != 0)
  49. (*Position) = Program[*Position + 2];
  50. else
  51. (*Position) += 3;
  52. break;
  53.  
  54. case InstrJump:
  55. (*Position) = Program[*Position + 1];
  56. break;
  57.  
  58. case InstrIncVar:
  59. Vars[Program[*Position + 1]]++;
  60. (*Position) += 2;
  61. break;
  62.  
  63. case InstrDecVar:
  64. Vars[Program[*Position + 1]]--;
  65. (*Position) += 2;
  66. break;
  67. }
  68.  
  69. return 1;
  70. }
  71.  
  72. typedef enum
  73. {
  74. VarGlobal,
  75.  
  76. VarCnt0,
  77. VarCnt1,
  78.  
  79. VarFlag0,
  80. VarFlag1,
  81. VarTurn,
  82.  
  83. VarIdxMax
  84. } tVarIdx;
  85.  
  86. unsigned Vars[VarIdxMax];
  87.  
  88. #define USE_PETERSON 01
  89. #define SWAP_CHECKS 0
  90.  
  91. const unsigned Program0[] =
  92. {
  93. // cnt0 = 1000;
  94. InstrSetVarNum, VarCnt0, 1000,
  95.  
  96. // 3:
  97. #if USE_PETERSON
  98. // flag[0] = 1;
  99. InstrSetVarNum, VarFlag0, 1,
  100. // turn = 1;
  101. InstrSetVarNum, VarTurn, 1,
  102. // 9:
  103. // while (flag[1] == 1 && turn == 1) {}
  104. #if SWAP_CHECKS
  105. InstrJumpVarZero, VarTurn, 17,
  106. InstrJumpVarZero, VarFlag1, 17,
  107. #else
  108. InstrJumpVarZero, VarFlag1, 17,
  109. InstrJumpVarZero, VarTurn, 17,
  110. #endif
  111. InstrJump, 9,
  112. // 17:
  113. #endif
  114.  
  115. // Critical section starts
  116. // global ^= 0x5555;
  117. // global ^= 0x5555;
  118. // global++;
  119. InstrXorVarNum, VarGlobal, 0x5555,
  120. InstrXorVarNum, VarGlobal, 0x5555,
  121. InstrIncVar, VarGlobal,
  122. // Critical section ends
  123.  
  124. #if USE_PETERSON
  125. // flag[0] = 0;
  126. InstrSetVarNum, VarFlag0, 0,
  127. #endif
  128.  
  129. // cnt0--;
  130. InstrDecVar, VarCnt0,
  131. // if (cnt0 == 0) goto 3;
  132. InstrJumpVarNonzero, VarCnt0, 3,
  133.  
  134. // end
  135. InstrHalt
  136. };
  137.  
  138. const unsigned Program1[] =
  139. {
  140. // cnt1 = 1000;
  141. InstrSetVarNum, VarCnt1, 1000,
  142.  
  143. // 3:
  144. #if USE_PETERSON
  145. // flag[1] = 1;
  146. InstrSetVarNum, VarFlag1, 1,
  147. // turn = 0;
  148. InstrSetVarNum, VarTurn, 0,
  149. // 9:
  150. // while (flag[0] == 1 && turn == 0) {}
  151. #if SWAP_CHECKS
  152. InstrJumpVarNonzero, VarTurn, 17,
  153. InstrJumpVarZero, VarFlag0, 17,
  154. #else
  155. InstrJumpVarZero, VarFlag0, 17,
  156. InstrJumpVarNonzero, VarTurn, 17,
  157. #endif
  158. InstrJump, 9,
  159. // 17:
  160. #endif
  161.  
  162. // Critical section starts
  163. // global ^= 0xAAAA;
  164. // global ^= 0xAAAA;
  165. // global++;
  166. InstrXorVarNum, VarGlobal, 0xAAAA,
  167. InstrXorVarNum, VarGlobal, 0xAAAA,
  168. InstrIncVar, VarGlobal,
  169. // Critical section ends
  170.  
  171. #if USE_PETERSON
  172. // flag[1] = 0;
  173. InstrSetVarNum, VarFlag1, 0,
  174. #endif
  175.  
  176. // cnt1--;
  177. InstrDecVar, VarCnt1,
  178. // if (cnt1 == 0) goto 3;
  179. InstrJumpVarNonzero, VarCnt1, 3,
  180.  
  181. // end
  182. InstrHalt
  183. };
  184.  
  185. void Simulate(void)
  186. {
  187. unsigned pos0 = 0, pos1 = 0;
  188.  
  189. while (Program0[pos0] != InstrHalt ||
  190. Program1[pos1] != InstrHalt)
  191. {
  192. int cnt;
  193.  
  194. cnt = rand() % 50;
  195. while (cnt--)
  196. if (!ExecuteInstruction(Vars, Program0, &pos0))
  197. break;
  198.  
  199. cnt = rand() % 50;
  200. while (cnt--)
  201. if (!ExecuteInstruction(Vars, Program1, &pos1))
  202. break;
  203. }
  204. }
  205.  
  206. int main(void)
  207. {
  208. srand(time(NULL));
  209. Simulate();
  210. printf("VarGlobal = %u\n", Vars[VarGlobal]);
  211. return 0;
  212. }
  213.  
Success #stdin #stdout 0s 1788KB
stdin
Standard input is empty
stdout
VarGlobal = 2000