diff --git a/.codio b/.codio new file mode 100644 index 0000000..7232506 --- /dev/null +++ b/.codio @@ -0,0 +1,19 @@ +{ + // This file is used to configure the three buttons along Codio's top menu. + + // Run button configuration + "commands": { + "Compile & Run": "gcc {{filename}} -o {{filename_no_ext}} && ./{{filename_no_ext}}", + "Compile": "gcc {{filename}} -o {{filename_no_ext}}", + "Run": "./{{filename_no_ext}}" + }, + // Preview button configuration + "preview": { + "Project Index (static)": "https://{{domain}}/{{index}}", + "Current File (static)": "https://{{domain}}/{{filepath}}", + "Box URL": "http://{{domain3000}}/", + "Box URL SSL": "https://{{domain3000}}/" + }, + // Debugger target button configuration + "debugger": [{"type":"GDB","command":"/tmp/program67e2dee2135748e7c1ba01f45b46ceda ","before":"gcc -std=c11 -g -lm {{filepath}} -o /tmp/program67e2dee2135748e7c1ba01f45b46ceda","single":true,"lang":"c","additionalCompilerFlags":"","sourcePath":"{{filepath}}","args":"","uuid":"4713985f-ec53-ca5c-71b4-b8615ec23995","name":"Debug Current File"}] +} \ No newline at end of file diff --git a/AssemblyGuessingGame/main.asm b/AssemblyGuessingGame/main.asm new file mode 100644 index 0000000..e5765de --- /dev/null +++ b/AssemblyGuessingGame/main.asm @@ -0,0 +1,533 @@ +;From GuessingGame.asm I used: +;array with answers +;function to end the program +;function for the player to input the answer +;comparison between player input and the answer +;printing messages function, which is adapted into other print functions ;throughout the code + +;Additional features: +;swap system +;answer confidence system + +;If the player guesses correctly: if he is sure, he gets 2 points, if not, ;he gets 1 +;If the player guesses incorrectly: if he is sure, he looses 1 point, ;unless he already has 0, if he is not sure, he looses 0 points + +section .data +welcome db "Welcome to higher or lower game, collect 10 points to win the game, score 5 right answers in a row to win a prize", 10 ;Welcome message + ;for game +welcomeLen equ $-welcome ;Size of the message + +samemsg db 10,"Correct, ";Message that the guess is correct +samelen equ $-samemsg ;Size of the message + +notsamemsg db 10,"Incorrect, ";Message that the guess is incorrect +notsamelen equ $-notsamemsg ;Size of the message + +inputMsg db "User: " ;Message after which player puts their input +inputMsglen equ $-inputMsg ;Size of the message + +streakMsg1 db "Your streak is " ;first segment of message about the streak +streakMsg1len equ $-streakMsg1 ;Size of the message + +streakMsg2 db " out of 5", 10 ;third segment of message about the streak, + ;the second segment being the streak itself +streakMsg2len equ $-streakMsg2 ;Size of the message + +prizeMsg db "Congratulations! You win a prize", 10 ;Message that tells the + ;player that they won a prize +prizeMsglen equ $-prizeMsg ;Size of the message + +exitMsg db " .Press 'e' to exit the game",10; Message that informs the + ;player about the ability to close the game +exitMsglen equ $-exitMsg ;Size of the message + +swapQuestion db "Press 's' to swap question. Swaps left: " ;Message that + ;informs the player about the ability to swap + ;questions, as well as the first part of swaps + ;left message +swapQuestionlen equ $-swapQuestion ;Size of the message + +noSwap db "You have no swaps left", 10 ;message that informs player that + ;they have no swaps left +noSwaplen equ $-noSwap ;Size of the message + +sureMsg db "Are you sure? Y/N",10 ;message asking the user if they are sure + ;of their answer +sureMsglen equ $-sureMsg ;Size of the message + +invalidMsg db "invalid Input, no win points granted",10 ;message informing + ;player that they put invalid input on YES/NO segment +invalidMsglen equ $-invalidMsg ;Size of the message + +winMsg db "Congratulations, you have 10 points, you win!!",10 ;message + ;informing the player that he won the game +winMsglen equ $-winMsg ;Size of the message + +yesInput dq "Y" ;input required from player to say he is sure of the answer +noInput dq "N" ;input required from player to say he is not sure of the + ;answer +;Same as endl in C++ +cr db 10 +exitInput dq "e" ;input required from player to exit the game +swapInput dq "s" ;input required from player to swap the question + +;the array we are using to store the answers +global listAnswers +listAnswers: + dq 'H' ; the answer letters are stores in 8 bytes to aid the comparison + dq 'L' + dq 'H' + dq 'L' + dq 'L' +letter: + dq 0 ; where we store each of the answers one at a time + +Question1 db "Is mount Everest higher or lower than 7000m?(H/L)" +Question1len equ $-Question1 +Question2 db "Is the age of Don Cheadle Higher or Lower than 60?(H/L)" +Question2len equ $-Question2 +Question3 db "Distance from Paris to Berlin is Higher or Lower than 1000km" +Question3len equ $-Question3 +Question4 db "Is the population of Brazil Higher or Lower than 250 milion?" +Question4len equ $-Question4 +Question5 db "Is average reading speed Higher or Lower than 300 words per minute?(H/L)" +Question5len equ $-Question5 + +;array storing quiz questions +questionList: + dq Question1 + dq Question2 + dq Question3 + dq Question4 + dq Question5 +;array storing quiz questions length +questionLenList: + dq Question1len + dq Question2len + dq Question3len + dq Question4len + dq Question5len + +Response1 db "Mount Everest height is 8849 m" +Response1len equ $-Response1 +Response2 db "Don Cheadle is 57 years old" +Response2len equ $-Response2 +Response3 db "Distance from Paris to Berlin is 1054 km" +Response3len equ $-Response3 +Response4 db "The population of Brazil is 212,6 million" +Response4len equ $-Response4 +Response5 db "Average reading speed is 250 words per minute" +Response5len equ $-Response5 + +;array storing quiz answers +responseList: + dq Response1 + dq Response2 + dq Response3 + dq Response4 + dq Response5 +;array for storing quiz answers length +responseLenList: + dq Response1len + dq Response2len + dq Response3len + dq Response4len + dq Response5len + +segment .bss +pointNum: resb 8 ;store number of points +swapNum: resb 8 ;store number of swaps left +winPoints: resb 8;store second punctation system needed to win the game +guess resb 1 ; store the users guess + + +section .text + global _start ;must be declared for linker (ld) +_start: +call displayWelcome +call newLine +mov esi, 0 ;move 0 to esi register +mov [pointNum], esi ;set 0 as the number of points +mov [winPoints], esi ;set 0 as the number of win points +mov esi, 3 ;move 3 to esi register +mov [swapNum], esi ;set 3 as number of guesses left +call loopQuestions + +;Main function that calls other functions +top: + mov rbx, [rcx] ; put the current letter being guessed in rbx + mov [letter],rbx ; move rbx into a variable letter that stores the + ;current guess + push rax ; push rax on stack + push rcx ; push rax on stack + call displayQuestion ; display the question + call displayExitMsg ;display exit message + call displaySwapMsg ;display swap message + call newLine + call reading ; call reading to get the users guess + call displayCorrectAnswer ; print the letter they should have guessed + call newLine + call displayStreak ;display user streak + call newLine ; new line like endl in C++ + pop rcx ; get back from stack + pop rax ; get back from stack + add rcx,8 ;move pointer to next element as 8 bits for each move on by 8 + add r8,8 ; add on 8 bytes as using dq data type + add r9,8 ; add on 8 bytes as using dq data type + add r10,8 ; add on 8 bytes as using dq data type + add r11,8 ; add on 8 bytes as using dq data type + dec rax ;decrement counter so going down + jnz top ;if counter not 0, then loop again + call loopQuestions ;go to the beggining of question array + jmp top + +;function for displaying the correct answer for the current question +displayCorrectAnswer: + mov edx, [r11] ;message length content of register r9 + mov ecx, [r10];message to write content of register r8 + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + ret + + ;function to read the user guess and do comparison with the answer +reading: + mov ecx,inputMsg ; input message + mov edx, inputMsglen ; length of input message + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + mov eax, 3 ; read from keyboard + mov ebx, 2; + mov ecx, guess ; move guess into ecx + mov edx, 1 ; As single letter using 1 byte + int 80h ; call interrupt + mov rax, [guess] ;mov players guess to rax register + cmp rax, [exitInput] ;compare rax and value of exitInput + je done ;if they are same jump to function to end the program + cmp rax, [swapInput] ;else, compare rax to value of swapInput + je swap ;if they are same, jump to swap function + cmp rax, [letter] ;else, compare correct answer with what in rax + je same ; if guess was correct jump to same function + call Notsame ; if the guess is incorrect then go to Notsame function + ret + +; function to show message that answer was not correct answer +Notsame: + ;call all the functions checking if player is sure of their answer first + call clearInput + call displaySure + call sureRead + call nSameSure + call clearInput + mov edx, notsamelen ; length of same message + mov ecx,notsamemsg ; Not same message + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + mov esi, 0 ;move 0 to esi register + mov [pointNum], esi ;set 0 as the number of points, since not getting the + ;answer right looses the point streak + ret + +; function to show message answer was correct +same: + ;call all the functions checking if player is sure of their answer first + call clearInput ;call function to clear input + call displaySure ;call function to display question if player is sure + call sureRead ;call function for player to input if they are sure + call sameSure ;call function to check effect on points from player + ;sureness + call clearInput ;call function to clear input + call winCheck ;call function to check if player won + mov edx, samelen ; length of same message + mov ecx,samemsg ;same message + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + mov dx, [pointNum] ;move value of pointNum to dx register + inc dx ;decrease value of integer inside dx register + mov [pointNum], dx ;set contents of dx register as a value of pointNum + ret + +;function for checking whether player has any swaps left and if yes, ;swapping the question +swap: + call clearInput ;call function to clear input + mov rax, 0 ;move 0 into rax register + cmp rax, [swapNum] ;compare value in swapNum variable to value of rax + ;register + je zeroSwap ;if swapNum is equal to zero, jump to zeroSwap function + mov dx, [swapNum] ;else, move value of swapNum to dx register + dec dx ;decrease value of integer inside dx register + mov [swapNum], dx ;set contents of dx register as a value of swapNum + call newLine ; new line like endl in C++ + pop rcx ; get back from stack + pop rax ; get back from stack + add rcx,8 ;move pointer to next element as 8 bits for each move on by 8 + add r8,8 ; add on 8 bytes as using dq data type + add r9,8 ; add on 8 bytes as using dq data type + add r10,8 ;add on 8 bytes as using dq data type + add r11,8 ;add on 8 bytes as using dq data type + dec rax ;decrement counter so going down + jnz top ;if counter not 0, then loop again + call loopQuestions ;go to the beginning of question array + jmp top + +;function for printing a message informing the player that they have zero ;swaps left +zeroSwap: + mov edx, noSwaplen ;message length + mov ecx, noSwap ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + jmp reading + +; Function to create a New line like endl in C++ +newLine: + mov eax,4 ; Put 4 in eax register into which is system + ;call for write (sys_write) + mov ebx,1 ; Put 1 in ebx register which is the standard + ; output to the screen + mov ecx, cr ; Put the newline value into ecx register + mov edx, 1 ; Put the length of the newline value into edx + ; register + int 80h ; Call the kernel with interrupt to check the + ; registers and perform the action of moving to + ; the next line like endl in c++ + ret ; return to previous position in code + +;Function to display welcome to game message +displayWelcome: + mov edx,welcomeLen ;message length + mov ecx, welcome ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + ret + +;Function to display question for quiz +displayQuestion: + mov edx, [r9] ;message length from content of register r9 + mov ecx, [r8];message to write from content of register r8 + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + ret + +; Function to display the correct answer sentence +displayExitMsg: + mov edx,exitMsglen ;message length + mov ecx, exitMsg ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + ret +;Function for displaying swaps left message, and the number of swaps left +displaySwapMsg: + mov edx,swapQuestionlen ;message length + mov ecx, swapQuestion ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + call printSwapNum ;call function to print number of swaps left + ret +;Function for displaying players streak +displayStreak: + mov edx, streakMsg1len ; length of same message + mov ecx,streakMsg1 ; same message + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + call printStreak ;call function to print current streak + mov edx, streakMsg2len ; length of same message + mov ecx,streakMsg2 ; same message + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + call prize ;call function to display prize + ret +;function for converting integer streak to ascii and displaying it on the ;screen +printStreak: + mov esi, [pointNum] ;move value of pointNum variable to esi register + add esi, 48 ;add 48 to esi register to convert number in there into ascii + ;character + mov [pointNum], esi ;set value inside esi register as value of pointNum + ;variable + mov eax, 4 ;system call number (sys_write) + mov ebx, 1 ;file descriptor (stdout) + mov ecx , pointNum ;move number of points to ecx register + mov edx, 8 ;set length of pointNum to 8 bytes + int 80h ;call kernel + mov esi, [pointNum] ;move value of pointNum variable to esi register + sub esi, 48 ;subtract 48 from esi register to convert ascii character + ;back to integer + mov [pointNum], esi ;set value inside esi register as value of pointNum + ;variable + ret + +;function for converting integer swap number to ascii and displaying it on ;the screen +printSwapNum: + mov esi, [swapNum] ;move value of swapNum variable to esi register + add esi, 48 ;add 48 to esi register to convert number in there into ascii + ;character + mov [swapNum], esi ;set value inside esi register as value of swapNum + ;variable + mov eax, 4 ;system call number (sys_write) + mov ebx, 1 ;file descriptor (stdout) + mov ecx , swapNum ;move number of swaps left to ecx register + mov edx, 8 ;set length of swapNum to 8 byte + int 80h ;call kernel + mov esi, [swapNum] ;move value of swapNum variable to esi register + sub esi, 48 ;subtract 48 from esi register to conver ascii character back + ;to integer + mov [swapNum], esi ;set value inside esi register as value of swapNum + ;variable + ret + +;function for checking if player got 5 questions right in a row +prize: + mov rax, 5 ;mov 5 into rax register + cmp rax, [pointNum] ;compare value in rax register to pointNum + je displayPrize ;if they are equal, jump to displayPrizefunction + ret ;else, return + +;function for displaying prize message to the player, and restarting ;punctation system from 0 +displayPrize: + mov edx,prizeMsglen ;move length of prize message to edx register + mov ecx,prizeMsg ; move prize message to ecx register + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + mov esi,0 ;move 0 to esi register + mov [pointNum],esi ;restart the punctation system by moving value of esi + ;register to pointNum + ret + +;function for displaying message to player if they are sure of their answer +displaySure: + mov edx,sureMsglen ;message length + mov ecx, sureMsg ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + ret + +;function for getting input from the user if they are sure of their answer +sureRead: + mov ecx,inputMsg ; input message + mov edx, inputMsglen ; length of input message + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h ;call kernel + mov eax, 3 ; read from keyboard + mov ebx, 2; + mov ecx, guess ; move guess into ecx + mov edx, 1 ; As single letter using 1 byte + int 80h ; call interrupt + ret + +;function to process input if player was sure of their answer, when their ;answer was right +sameSure: + mov rax, [guess] ;move players guess to rax registery + cmp rax, [yesInput] ;compare value of rax with value of yesInput variable + je sameYes ;if they are the same, go to sameYes function + cmp rax, [noInput] ;else, compare value of rax with value of noInput + ;variable + jne invalidInput ;if they are not the same, go to invalidInput function + mov dx, [winPoints] ;else, move value of winPoints to dx register + inc dx ;decrease value of integer inside dx register + mov [winPoints], dx ;set contents of dx register as a value of winPoints + ret + +;function that is called when player has answered right, and were confident ;in their answer, increases their winPoints by 2 +sameYes: + mov esi, [winPoints] ;move value of winPoints to esi register + add esi, 2 ;add 2 to esi registery + mov [winPoints], esi ;set contents of esi register as a value of + ;winPoints + ret + +;function to process input if player was sure of their answer, when their ;answer was wrong +nSameSure: + mov rax, [guess] ;mov value of guess to rax register + cmp rax, [yesInput] ;compare value of yesInput variable to rax + je nSameYes1 ;if they are the same, jump to nSameYes1 function + cmp rax, [noInput] ;else, compare value of noInput variable to rax + jne invalidInput ;if they are not the same, call invalidInput function + ret ;else, if the player was not sure in their answer and it was wrong, + ;there is no change in points, which means we can just return + +;funtion that is called when the player has answered wrong and was ;confident, first checks if current number of win points is 0 and if no, ;calls function to decrease points +nSameYes1: + mov rax, 0 ;move 0 to rax registery + cmp rax, [winPoints] ;compare number of win points to rax registery + jne nSameYes2 ;if not equal, jump to nSameYes2 function + ret ;else return + +;funtion to decrease current number of win points by 1 +nSameYes2: + mov dx, [winPoints] ;else, move value of winPoints to dx register + dec dx ;decrease value of integer inside dx register + mov [winPoints], dx ;set contents of dx register as a value of winPoints + ret + +;function for displaying to user that their input was invalid +invalidInput: + mov edx,invalidMsglen ;move length of prize message to edx register + mov ecx,invalidMsg ; move prize message to ecx register + mov ebx,1 ;file descriptor (stdout) + mov eax,4 ;system call number (sys_write) + int 80h + ret + +;function to check if the player has enough points to win the game +winCheck: + mov rax, 10 ;move 10 to rax registery + cmp rax, [winPoints] ;compare current number of win points to rax + ;registry + jle winGame ;if rax registery is lesser or equal to current number of win + ;points, jump to winGame function + ret ;else return + +;function for printing message about winning the game, and then calling done function to quit program +winGame: + mov edx,winMsglen ;message length + mov ecx, winMsg ;message to write + mov ebx, 1 ;file descriptor (stdout) + mov eax, 4 ;system call number (sys_write) + int 0x80 ;call kernel + call done + +;function for going to the beginning of question array, called when program stars, +;and when it reaches the end of question array +loopQuestions: + mov rax,5 ;number of answers + mov rcx,0 ;RBX will store the letter + mov rcx, listAnswers ;RCX will point to the current element array to + ;be guessed + mov r8, questionList ;move into r9 register the beginning of array with + ;questions + mov r9, questionLenList ;move into r9 register the beginning of array + ;with question lengths + mov r10, responseList ;move into r10 register the beginning of array + ;with answers + mov r11, responseLenList ;move into r11 register the beginning of array + ;with answer lengths + ret + +;function to deal with previous enter key +clearInput: + mov eax, 3 ; read previous enter key press + mov ebx, 2 + mov ecx, guess ; Deal with previous enter key press so it does not mess + ;up loop + mov edx, 1 ; As single letter using 1 byte + int 80h ;call kernel + ret + +;Function to end the program +done: + call clearInput + mov rax,0 ;move 0 to rax register + mov eax, 1 ;system call number (sys_exit) + int 0x80 ;call kernel diff --git a/AssemblyGuessingGame/main.o b/AssemblyGuessingGame/main.o new file mode 100644 index 0000000..1447955 Binary files /dev/null and b/AssemblyGuessingGame/main.o differ diff --git a/MultiprogrammingInC/clinic.db b/MultiprogrammingInC/clinic.db new file mode 100644 index 0000000..4bddcd3 Binary files /dev/null and b/MultiprogrammingInC/clinic.db differ diff --git a/MultiprogrammingInC/main b/MultiprogrammingInC/main new file mode 100644 index 0000000..43ed35e Binary files /dev/null and b/MultiprogrammingInC/main differ diff --git a/MultiprogrammingInC/main.c b/MultiprogrammingInC/main.c new file mode 100644 index 0000000..fa95a06 --- /dev/null +++ b/MultiprogrammingInC/main.c @@ -0,0 +1,221 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ops_sems.h" +#include +#include +//aditional features: +//number of doctors administering the vaccine can be modified +//additionaly to ID, name and age are required from patients, and their personal data is placed in a database instead of text file + +int callback(void *count, int argc, char **argv, char **azColName) { + //callback function for getting number of rows in a database, code based on https://stackoverflow.com/questions/21692245/retrieve-sql-table-row-count-with-c + int *c = count; //initialise pointer to count variable + *c = atoi(argv[0]); //convert string number of rows to int and place it in c pointer + return 0; +} + +bool inputCheck(char name[50],int age){ + //function that checks if name and age inputs are valid + bool validInput = true; //initialise validInput boolean and set it to true + for(int i = 0; name[i]; i++){ //for each character in name string + if(isdigit(name[i]) && !isspace(name[i])){ //if it is a digit and + //not a whitespace + validInput = false;} } //set validInput boolean to false + if(age < 1 || age > 130){validInput = false;} //if age is smaller than 1 + //or bigger than 130, set + //validInput variable to false + return validInput; + +} +int main(int argc, char argv[]){ + char* err; //initialise a pointer to error message + int count; //initialise count integer + sqlite3* db; //initialise sqlite3 database + sqlite3_stmt* stmt; //initialise pointer to sqlite3 statement + sqlite3_open("clinic.db",&db); //open clinic database + int rc = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS patients(ID INT,name varchar(14),age INT)",NULL,NULL,&err); //create patients table in clinic + //database if it does not exist, and + //place ID, name and age columns there + if(rc != SQLITE_OK) { //if there were errors in the sqlite operation + fprintf(stderr, "SQL error: %s\n", err); //print to stderr the + //error message + sqlite3_free(err); //free the query with the error + } + rc = sqlite3_exec(db, "select count(*) from patients", callback, &count, &err); //make sqlite query to count all the rows in patients table + if(rc != SQLITE_OK) { //if there were errors in the sqlite operation + fprintf(stderr, "SQL error: %s\n", err); //print to stderr the + //error message + sqlite3_free(err); //free the query with the error + } + int maxPatients = 120; //initialise maxPatients inside database int and + //set it to 120 + if(count >= maxPatients){printf("the database is full, no more vaccines can be administered \n");return 0;} //if the patient table in the clinic + //database is full, inform the user and + //end the program + int bufferlength = 1024; //set length of buffer to 1024 bytes + //FILE *f = fopen("patients.txt", "w+");//if we wanted to use txt file instead of database, it opens patients.txt in write mode, and creates the txt file if it does not exist + int id=ops_semget("main.c",1); //initialise int and setit to ops_semget + //function with current file and 1 as + //passed arguments + int status = 0; //initialise status int and set it to 0 + int shmid; //initialise shmid integer + char temp; //initialise character for temporary input + int doctorNum; //initialise number of doctors int + typedef struct{int id;char name[50];int age;}patient; //define patient + //structure with int id, name 50 + //characters string, and age int. + char nameStr[50]; //initialise nameStr 50 character string, where patients + //name input will be stored + int ageInt; //initialise ageInt int, where patients age input + //will be stored + int patientID = count + 1; //initialise patinentID int and set it to + //current number of rows inside database + 1 + int clinicSize = 10; //initialise size of clinic int and set it to 10 + patient (*data)[clinicSize]; //initialise pointer to shared data array + //where max clinic size number of patient + //structures can be stored + printf("Set number of doctors administering the vaccine -> "); + scanf("%d",&doctorNum); //input that sets doctorNum integer + if(doctorNum > clinicSize) doctorNum = clinicSize; //if there are more + //doctors than places in the + //clinic, set number of doctors to + //clinicSize + int pid=fork(); //fork the current process + shmid=shmget(ftok("main.c",2),bufferlength, 0644|IPC_CREAT); //set shmid of the + //current process + if(pid){ //if current process id is greater than 0 + //P1 + int patientNum = 0; //initialise patient number and set it to 0 + int written = 0; //initialise number of times written to shared memory + //int and set it to 0 + data = shmat(shmid, NULL, 0); //create shared memory + ops_wait(id); //process calls wait, so that it can go into its + //critical section if none other processes are in their + //critical section + while(written < clinicSize){ //fully fill the clinic with patients + printf("Patient %i add your name -> ",patientID); + scanf("%c",&temp); //temporary input stament to clear input buffer + scanf("%[^\n]",nameStr); //input with allowed whitespaces that + //sets nameStr string + printf("Patient %i add your age -> ",patientID); + scanf("%i",&ageInt); //input that sets ageInt integer + if(inputCheck(nameStr,ageInt) == false){printf("Please input real personal data\n");continue;} //if the inputCheck with name and age passed as + //arguments returns false, repeat the loop + //without increasing written and patientID + (*data)[written].id = patientID; //go to written integer index of + //shared data array, and set id in + //patient structure to patinentID + strcpy((*data)[written].name, nameStr); //go to written integer + //index of shared data array, and set + //name in patient structure to nameStr + (*data)[written].age = ageInt; //go to written integer index of + //shared data array, and set age in + //patient structure to ageInt + written++; //increase written integer by 1 + patientID++; //increase patientID integer by 1 + } + //this is part of process 1 that will be executed after initial clinic + //fill, until the end of the program + ops_signal(id); //process sends a signal that it had finished its + //critical section + while(patientID <= maxPatients){ //repeat until the patient table + //in the database is filled + ops_wait(id); //process calls wait, so that it can go into its + //critical section if none other processes are in + //their critical section + for(int i = 0;i= clinicSize) //if written is bigger or equal + //than clinic size + written = 0; //go to the beggining of shared memory + printf("Patient %i add your name -> ",patientID); + scanf("%c",&temp); //temporary input stament to clear input + //buffer + scanf("%[^\n]",nameStr); //input with allowed whitespaces + //that sets nameStr string + printf("Patient %i add your age ->",patientID); + scanf("%i",&ageInt); //input that sets ageInt integer + if(inputCheck(nameStr,ageInt) == false){printf("Please input real personal data\n");continue;} //if the inputCheck with name and age + //passed as arguments returns false, repeat the + //loop without increasing written and patientID + (*data)[written].id = patientID; //go to written integer index + //of shared data array, and set id in + //patient structure to patinentID + strcpy((*data)[written].name, nameStr); //go to written + //integer index of shared data + //array, and set age in patient + //structure to ageInt + (*data)[written].age = ageInt; //go to written integer index + //of shared data array, and set age in + //patient structure to ageInt + written++; //increase written integer by 1 + patientID++;}} //increase patientID integer by 1 + ops_signal(id); //process sends a signal that it had finished + //its critical section + } + wait(&status); //wait for the child process to end + } + else{ //if current process id is 0 + //P2 + int read = 0; //initialise number of times read from shared memory int + //and set it to 0 + data = shmat(shmid, (void *)0, 0); //create shared memory + sleep(1); //ensure that P2 will be executed after P1 + while(patientID <= maxPatients){ //repeat until the patient table in + //the database is filled + ops_wait(id); //process calls wait, so that it can go into its + //critical section if none other processes are in their + //critical section + for(int i = 0;i= clinicSize) //if read is bigger or equal than + //clinic size + read = 0; //go to the beggining of shared memory + char* query = sqlite3_mprintf("insert into patients values (%i,'%q',%i)",(*data)[read].id,(*data)[read].name,(*data)[read].age);//create + //sqlite query for inserting rows into database, + //and set inserted values to current vaccinated + //patients id, name and age + int rc = sqlite3_exec(db,query,NULL,NULL,&err); //execure + //sqlite query + if(rc != SQLITE_OK) { //if there were errors in the sqlite + //operation + fprintf(stderr, "SQL error: %s\n", err); //print to stderr + //the error message + sqlite3_free(err); //free the query with the error + } + //fprintf(f, "Patient name: %s, Patient ID: %i\n, Patient age: %i",(*data)[read].name,(*data)[read].id),(*data)[read].age; //line of code used if we wanted to use txt files insteas of database + printf("Patient %i leaving the clinic...\n",(*data)[read].id); //print string to console with current + //patients id inserted into it + read++; //increase read integer by 1 + patientID++; //increase patientID by 1 + }} + sleep(2); //patient leaving the clinic + ops_signal(id); //process sends a signal that it had finished its + //critical section + } + //fclose(f); //if the user wants to use txt file instead of database, close the txt file + sqlite3_close(db); //close the database + } +return 0; +} + diff --git a/MultiprogrammingInC/ops_sems.h b/MultiprogrammingInC/ops_sems.h new file mode 100644 index 0000000..14ce2ad --- /dev/null +++ b/MultiprogrammingInC/ops_sems.h @@ -0,0 +1,99 @@ +/* ops_sems.h */ +/* Simple functions to ease the use of semaphores */ +/* James Shuttleworth, 2012 */ +/*--------------------------------------------------------------------------------*/ +/* This program is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ + +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ + +/* You should have received a copy of the GNU General Public License */ +/* along with this program. If not, see . */ + +#include +#include +#include +#include + +void rsleep(){ + //Random sleep function. Comes in handy demoing stuff. + int stime=2+(rand()/(float)(RAND_MAX))*4; + printf("Sleeping for %d secs\n",stime); + sleep(stime); +} + + +int ops_semget(char* path, int val){ + //Very simple semaphore "getting", + //always uses 1 as the project ID + //takes path to file and initial value of semaphore + + int id; /* Number by which the semaphore + is known within a program */ + + + union semun { + int val; + struct semid_ds *buf; + ushort * array; + } argument; + + argument.val = val; + + /* Create the semaphore with external key from + ftok if it doesn't already + exist. Give permissions to the world. */ + + id = semget(ftok(path,1), 1, 0666 | IPC_CREAT); + + /* Always check system returns. */ + + if(id < 0) + { + fprintf(stderr, "Unable to obtain semaphore.\n"); + exit(0); + } + + /* Set the value of the number 0 semaphore in semaphore array # id + to the value "val". */ + + if( semctl(id, 0, SETVAL, argument) < 0) + fprintf( stderr, "Cannot set semaphore value.\n"); + else + fprintf(stderr, "Semaphore %d initialized with path '%s'.\n", + ftok(path,1),path); + return id; +} + +void ops_semop(int id,int val){ + + + struct sembuf operations[1]; + int retval; /* Return value from semop() */ + + //simple wait on semaphore + operations[0].sem_num = 0; + /* Which operation? Subtract 1 from semaphore value to wait, add to + signal */ + operations[0].sem_op = val; + operations[0].sem_flg = 0; + + retval = semop(id, operations, 1); + +} + + +void ops_wait(int id){ + ops_semop(id,-1); +} + +void ops_signal(int id){ + ops_semop(id,1); +} + +