Advertisement
LA77

Untitled

Feb 25th, 2025
445
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.29 KB | None | 0 0
  1. #include <stdbool.h>
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <sys/mman.h>
  5. #include <unistd.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/wait.h>
  10. #include <semaphore.h>
  11.  
  12. #define MAX_CHILDREN 1024
  13.  
  14. struct LOGS
  15. {
  16.     char op[256];
  17.     int suc;
  18.     int number_transaction, value, destination_1, destination_2, new_balance, new_balance2, failure1, failure2;
  19. };
  20.  
  21. void init(struct LOGS *log)
  22. {
  23.     memset(log->op, 0, 255);
  24.     log->number_transaction = 0;
  25.     log->value = 0;
  26.     log->destination_1 = 0;
  27.     log->destination_2 = 0;
  28.     log->suc = 0;
  29.     log->new_balance = 0;
  30.     log->new_balance2 = 0;
  31.     log->failure1 = 0;
  32.     log->failure2 = 0;
  33. }
  34.  
  35. int is_digit(char c)
  36. {
  37.     return (c >= '0' && c <= '9');
  38. }
  39.  
  40. int process_transaction(char *operation, int *accounts, struct LOGS *logs, sem_t *account_semaphore, int id)
  41. {
  42.     sem_wait(account_semaphore);
  43.     int idx = 0, save_i;
  44.     char *cpy = (char*) malloc(128 * sizeof(char));
  45.     pid_t child_pids[MAX_CHILDREN];
  46.     memset(child_pids, 0, MAX_CHILDREN * sizeof(pid_t));
  47.  
  48.     for(int j = 0; j < strlen(operation); ++j)
  49.     {
  50.         if(operation[j] == '(')
  51.         {
  52.             save_i = j;
  53.             cpy[idx] = '\0';
  54.             break;
  55.         }
  56.         cpy[idx++] = operation[j];
  57.     }
  58.  
  59.     if(!strcmp(cpy, "Withdraw"))
  60.     {
  61.         int sum = 0, dest = 0;
  62.        
  63.         save_i++;
  64.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  65.         {
  66.             sum = sum * 10 + (operation[save_i] - '0');
  67.             save_i++;
  68.         }
  69.         save_i += 2;
  70.  
  71.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  72.         {
  73.             dest = dest * 10 + (operation[save_i] - '0');
  74.             save_i++;
  75.         }
  76.  
  77.         if(accounts[dest] - sum < 0)
  78.         {
  79.             logs[id].failure1 = accounts[dest];
  80.             logs[id].suc = 0;
  81.             strcpy(logs[id].op, cpy);
  82.             logs[id].number_transaction = id;
  83.             logs[id].value = sum;
  84.             logs[id].destination_1 = dest;
  85.  
  86.             free(cpy);
  87.             sem_post(account_semaphore);
  88.             return 1;
  89.         }
  90.         else
  91.         {
  92.             accounts[dest] -= sum;
  93.             logs[id].suc = 1;
  94.             strcpy(logs[id].op, cpy);
  95.             logs[id].number_transaction = id;
  96.             logs[id].value = sum;
  97.             logs[id].destination_1 = dest;
  98.             logs[id].new_balance = accounts[dest];
  99.  
  100.             free(cpy);
  101.             sem_post(account_semaphore);
  102.             return 0;
  103.         }
  104.     }
  105.     if(!strcmp(cpy, "Deposit"))
  106.     {
  107.         int sum = 0, dest = 0;
  108.         save_i++;
  109.  
  110.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  111.         {
  112.             sum = sum * 10 + operation[save_i] - '0';
  113.             save_i++;
  114.         }
  115.         save_i += 2;
  116.  
  117.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  118.         {
  119.             dest = dest * 10 + operation[save_i] - '0';
  120.             save_i++;
  121.         }
  122.  
  123.         accounts[dest] += sum;
  124.         logs[id].suc = 1;
  125.         strcpy(logs[id].op, cpy);
  126.         logs[id].number_transaction = id;
  127.         logs[id].value = sum;
  128.         logs[id].destination_1 = dest;
  129.         logs[id].new_balance = accounts[dest];
  130.  
  131.         free(cpy);
  132.         sem_post(account_semaphore);
  133.         return 0;
  134.     }
  135.     if(!strcmp(cpy, "Transfer"))
  136.     {
  137.         int sum = 0, dest1 = 0, dest2 = 0;
  138.  
  139.  
  140.         save_i++;
  141.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  142.         {
  143.             sum = sum * 10 + operation[save_i] - '0';
  144.             save_i++;
  145.         }
  146.         save_i += 2;
  147.  
  148.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  149.         {
  150.             dest1 = dest1 * 10 + operation[save_i] - '0';
  151.             save_i++;
  152.         }
  153.         save_i += 2;
  154.  
  155.         while(operation[save_i] != '\0' && is_digit(operation[save_i]))
  156.         {
  157.             dest2 = dest2 * 10 + operation[save_i] - '0';
  158.             save_i++;
  159.         }
  160.  
  161.         if(accounts[dest1] - sum < 0)
  162.         {
  163.             logs[id].failure1 = accounts[dest1];
  164.             logs[id].failure2 = accounts[dest2];
  165.             logs[id].suc = 0;
  166.             strcpy(logs[id].op, cpy);
  167.             logs[id].number_transaction = id;
  168.             logs[id].value = sum;
  169.             logs[id].destination_1 = dest1;
  170.             logs[id].destination_2 = dest2;
  171.             logs[id].new_balance = accounts[dest1];
  172.             logs[id].new_balance2 = accounts[dest2];
  173.  
  174.             free(cpy);
  175.             sem_post(account_semaphore);
  176.             return 1;
  177.         }
  178.         else
  179.         {
  180.             accounts[dest1] -= sum;
  181.             accounts[dest2] += sum;
  182.  
  183.             logs[id].suc = 1;
  184.             strcpy(logs[id].op, cpy);
  185.             logs[id].number_transaction = id;
  186.             logs[id].value = sum;
  187.             logs[id].destination_1 = dest1;
  188.             logs[id].destination_2 = dest2;
  189.             logs[id].new_balance = accounts[dest1];
  190.             logs[id].new_balance2 = accounts[dest2];
  191.  
  192.             free(cpy);
  193.             sem_post(account_semaphore);
  194.             return 0;
  195.         }
  196.     }
  197.  
  198.     sem_post(account_semaphore);
  199.     free(cpy);
  200.     return 0;
  201. }
  202.  
  203. int main()
  204. {
  205.     setbuf(stdout, NULL);
  206.  
  207.     int n, count = 0;
  208.     pid_t child_pids[MAX_CHILDREN];
  209.     memset(child_pids, 0, MAX_CHILDREN);
  210.  
  211.     int fd_accounts = shm_open("/bank_account", O_CREAT | O_RDWR, 0666);
  212.     int fd_retry = shm_open("/bank_retry", O_CREAT | O_RDWR, 0666);
  213.     int fd_stats = shm_open("/bank_stats", O_CREAT | O_RDWR, 0666);
  214.     int ld = shm_open("/logs", O_CREAT | O_RDWR, 0666);
  215.     ftruncate(fd_accounts, 1024);
  216.     ftruncate(fd_retry, 1024);
  217.     ftruncate(fd_stats, 1024);
  218.     ftruncate(ld, sizeof(struct LOGS) * 1024);
  219.    
  220.     scanf("%d", &n);
  221.     if(n <= 0)
  222.     {
  223.         printf("Invalid number of accounts.\n");
  224.         exit(0);
  225.     }
  226.     printf("\n");
  227.  
  228.     int *accounts = mmap(0, sizeof(int) * (n + 1), PROT_READ | PROT_WRITE, MAP_SHARED, fd_accounts, 0);
  229.     int *before_retry = mmap(0, sizeof(int) * (n + 1), PROT_READ | PROT_WRITE, MAP_SHARED, fd_retry, 0);
  230.     int *stats = mmap(0, sizeof(int) * (n + 1), PROT_READ | PROT_WRITE, MAP_SHARED, fd_stats, 0);
  231.     struct LOGS *logs = mmap(0, sizeof(struct LOGS) * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, ld, 0);
  232.    
  233.     for(int i = 0; i < 1000; ++i)
  234.     {
  235.         init(&logs[i]);
  236.     }
  237.  
  238.     sem_t *account_semaphore = sem_open("/account_semaphore", O_CREAT, 0666, 1);
  239.  
  240.     printf("Initial account balances:\n");
  241.     for(int i = 0; i < n; ++i)
  242.     {
  243.         int x;
  244.         scanf("%d", &x);
  245.         accounts[i] = x;
  246.         printf("Account %d: %d\n", i, accounts[i]);
  247.     }
  248.    
  249.     while (getchar() != '\n');
  250.     int i = 0;
  251.  
  252.     char operations[MAX_CHILDREN][256];
  253.     memset(operations, 0, sizeof(operations));
  254.  
  255.     int total_tx = 0;
  256.     while(true)
  257.     {
  258.         if(!fgets(operations[total_tx], 256, stdin)) break;
  259.         if(strlen(operations[total_tx]) <= 1) break;
  260.         total_tx++;
  261.     }
  262.  
  263.     for(int i = 0; i < total_tx; i++)
  264.     {
  265.         pid_t pid = fork();
  266.         if(pid == 0)
  267.         {
  268.             int result = process_transaction(operations[i], accounts, logs, account_semaphore, i);
  269.             exit(result);
  270.         }
  271.         else
  272.         {
  273.             child_pids[i] = pid;
  274.         }
  275.     }
  276.  
  277.     for (int j = 0; j < total_tx; j++)
  278.     {
  279.         int status;
  280.         waitpid(child_pids[j], &status, 0);
  281.  
  282.         if (WEXITSTATUS(status) == 1)
  283.         {
  284.             printf("Transaction %d failed, retrying...\n", j);
  285.            
  286.             pid_t retry_pid = fork();
  287.             if(retry_pid == 0)
  288.             {
  289.                 int result = process_transaction(operations[j], accounts, logs, account_semaphore, j);
  290.                 exit(result);
  291.             }
  292.             else
  293.             {
  294.                 waitpid(retry_pid, &status, 0);
  295.             }
  296.         }
  297.     }
  298.  
  299.     int m = total_tx;
  300.     printf("\nFinal account balances:\n");
  301.  
  302.     for(int i = 0; i < n; ++i)
  303.     {
  304.         printf("Account %d: %d\n", i, accounts[i]);
  305.     }
  306.    
  307.     printf("\nTransaction Log (in order):\n");
  308.  
  309.     for(int i = 0; i < m; ++i)
  310.     {
  311.         if(strcmp(logs[i].op, "Withdraw") == 0)
  312.         {
  313.             if(logs[i].suc == 1)
  314.             {
  315.                 printf("Transaction %d: Withdraw %d from Account %d (Success) New balance: %d\n",
  316.                        logs[i].number_transaction, logs[i].value, logs[i].destination_1, logs[i].new_balance);
  317.             }
  318.             else
  319.             {
  320.                 printf("Transaction %d: Withdraw %d from Account %d (Failed) Current balance: %d\n",
  321.                        logs[i].number_transaction, logs[i].value, logs[i].destination_1, logs[i].failure1);
  322.             }
  323.         }
  324.         if(strcmp(logs[i].op, "Deposit") == 0)
  325.         {
  326.             printf("Transaction %d: Deposit %d to Account %d (Success) New balance: %d\n",
  327.                    logs[i].number_transaction, logs[i].value, logs[i].destination_1, logs[i].new_balance);
  328.         }
  329.         if(strcmp(logs[i].op, "Transfer") == 0)
  330.         {
  331.             if(logs[i].suc == 1)
  332.             {
  333.                 printf("Transaction %d: Transfer %d from Account %d to Account %d (Success) New balances: Account %d: %d, Account %d: %d\n",
  334.                        logs[i].number_transaction, logs[i].value, logs[i].destination_1, logs[i].destination_2,
  335.                        logs[i].destination_1, logs[i].new_balance, logs[i].destination_2, logs[i].new_balance2);
  336.             }
  337.             else
  338.             {
  339.                 printf("Transaction %d: Transfer %d from Account %d to Account %d (Failed) Current balances: Account %d: %d, Account %d: %d\n",
  340.                        logs[i].number_transaction, logs[i].value, logs[i].destination_1, logs[i].destination_2,
  341.                        logs[i].destination_1, logs[i].failure1, logs[i].destination_2, logs[i].failure2);
  342.             }
  343.         }
  344.     }
  345.  
  346.     munmap(accounts, sizeof(int) * (n + 1));
  347.     munmap(logs, sizeof(struct LOGS) * 1024);
  348.     sem_close(account_semaphore);
  349.     shm_unlink("/logs");
  350.     shm_unlink("/bank_account");
  351.     sem_unlink("/account_semaphore");
  352.     close(fd_accounts);
  353.     close(fd_retry);
  354.     close(fd_stats);
  355.     close(ld);
  356.     exit(0);
  357.     return 0;
  358. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement