Question

Step 2: Implement adder, multiplier, and degrouper -------------------------------------------------- Write the code to implement these functions. They...

Step 2: Implement adder, multiplier, and degrouper
--------------------------------------------------

Write the code to implement these functions. They should only consider
the current expression, which is the first expression in the buffer, or,
equivilently, everything up until the first semicolon. Do not implement
synchronization and mutual exclusion yet.

Tip: See sentinel() for an example invocation of strcpy() that shifts
the characters in a string to the left.

Tip: If you are not certain which stdlib functions to use for
string/number manipulation, feel free to use the provided utility
functions (string2int, int2string, isNumeric).

Pseudocode for adder/multiplier:
a. Scan through current expression looking for a number.
b. Check each number to see if it is followed by a +/*, and then a
numeric character (indicating the start of another number).
c. If it is, add/multiply the two numbers, and replace the
addition/multiplication subexpression with the result, e.g., "34+22"
becomes "56".

Pseudocode for degrouper:
a. Scan through current expression looking for a '('.
b. Check if the next character is numeric (indicating the start of a
number).
c. If it is, check if the number is immediately followed by a ')'.
d. If so, we have something like "(32432)". Now remove the '(' and ')'
we've just located from the expression.

The above pseudocode is only a suggestion; your code may work
differently. For example, you could hunt for + or * in the expression,
then check that there are "naked" numbers to the left and right.

HERE IS THE C FILE:

/* calc.c - Multithreaded calculator */

#include "calc.h"

pthread_t adderThread;
pthread_t degrouperThread;
pthread_t multiplierThread;
pthread_t readerThread;
pthread_t sentinelThread;

char buffer[BUF_SIZE];
int num_ops;


/* Utiltity functions provided for your convenience */

/* int2string converts an integer into a string and writes it in the
passed char array s, which should be of reasonable size (e.g., 20
characters). */
char *int2string(int i, char *s)
{
sprintf(s, "%d", i);
return s;
}

/* string2int just calls atoi() */
int string2int(const char *s)
{
return atoi(s);
}

/* isNumeric just calls isdigit() */
int isNumeric(char c)
{
return isdigit(c);
}

/* End utility functions */


void printErrorAndExit(char *msg)
{
msg = msg ? msg : "An unspecified error occured!";
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}

int timeToFinish()
{
/* be careful: timeToFinish() also accesses buffer */
return buffer[0] == '.';
}

/* Looks for an addition symbol "+" surrounded by two numbers, e.g. "5+6"
and, if found, adds the two numbers and replaces the addition subexpression
with the result ("(5+6)*8" becomes "(11)*8")--remember, you don't have
to worry about associativity! */
void *adder(void *arg)
{
int bufferlen;
int value1, value2;
int startOffset, remainderOffset;
int i;

while (1) {
   startOffset = remainderOffset = -1;
   value1 = value2 = -1;

   if (timeToFinish()) {
   return NULL;
   }

   /* storing this prevents having to recalculate it in the loop */
   bufferlen = strlen(buffer);

   for (i = 0; i < bufferlen; i++) {
   // do we have value1 already? If not, is this a "naked" number?
   // if we do, is the next character after it a '+'?
   // if so, is the next one a "naked" number?

   // once we have value1, value2 and start and end offsets of the
   // expression in buffer, replace it with v1+v2

  
   }

   // something missing?
  
}
  
}

/* Looks for a multiplication symbol "*" surrounded by two numbers, e.g.
"5*6" and, if found, multiplies the two numbers and replaces the
mulitplication subexpression with the result ("1+(5*6)+8" becomes
"1+(30)+8"). */
void *multiplier(void *arg)
{
int bufferlen;
int value1, value2;
int startOffset, remainderOffset;
int i;

return NULL; /* remove this line */

while (1) {
   startOffset = remainderOffset = -1;
   value1 = value2 = -1;

   if (timeToFinish()) {
   return NULL;
   }

   /* storing this prevents having to recalculate it in the loop */
   bufferlen = strlen(buffer);

   for (i = 0; i < bufferlen; i++) {
   // same as adder, but v1*v2
   }

   // something missing?
}
}


/* Looks for a number immediately surrounded by parentheses [e.g.
"(56)"] in the buffer and, if found, removes the parentheses leaving
only the surrounded number. */
void *degrouper(void *arg)
{
int bufferlen;
int i;

  

while (1) {

   if (timeToFinish()) {
   return NULL;
   }

   /* storing this prevents having to recalculate it in the loop */
   bufferlen = strlen(buffer);

   for (i = 0; i < bufferlen; i++) {
   // check for '(' followed by a naked number followed by ')'
   // remove ')' by shifting the tail end of the expression
   // remove '(' by shifting the beginning of the expression
   if(buffer[i] == '(')
   {
       if(isNumeric(buffer[i+1]) && buffer[i+2] == ')' )
       {
           for (int j = i+2; j < bufferlen; j++)
               buffer[j] = buffer[j+1];
           for (int k = i; k < bufferlen; k++)
               buffer[k] = buffer[k+1];
       }
   }
   }

   // something missing?
}
}


/* sentinel waits for a number followed by a ; (e.g. "453;") to appear
at the beginning of the buffer, indicating that the current
expression has been fully reduced by the other threads and can now be
output. It then "dequeues" that expression (and trailing ;) so work can
proceed on the next (if available). */
void *sentinel(void *arg)
{
char numberBuffer[20];
int bufferlen;
int i;

  

while (1) {

   if (timeToFinish()) {
   return NULL;
   }

   /* storing this prevents having to recalculate it in the loop */
   bufferlen = strlen(buffer);

   for (i = 0; i < bufferlen; i++) {
   if (buffer[i] == ';') {
       if (i == 0) {
       printErrorAndExit("Sentinel found empty expression!");
       } else {
       /* null terminate the string */
       numberBuffer[i] = '\0';
       /* print out the number we've found */
       fprintf(stdout, "%s\n", numberBuffer);
       /* shift the remainder of the string to the left */
       strcpy(buffer, &buffer[i + 1]);
       break;
       }
   } else if (!isNumeric(buffer[i])) {
       break;
   } else {
       numberBuffer[i] = buffer[i];
   }
   }

   // something missing?
}
}

/* reader reads in lines of input from stdin and writes them to the
buffer */
void *reader(void *arg)
{
while (1) {
   char tBuffer[100];
   int currentlen;
   int newlen;
   int free;

   fgets(tBuffer, sizeof(tBuffer), stdin);

   /* Sychronization bugs in remainder of function need to be fixed */

   newlen = strlen(tBuffer);
   currentlen = strlen(buffer);

   /* if tBuffer comes back with a newline from fgets, remove it */
   if (tBuffer[newlen - 1] == '\n') {
   /* shift null terminator left */
   tBuffer[newlen - 1] = tBuffer[newlen];
   newlen--;
   }

   /* -1 for null terminator, -1 for ; separator */
   free = sizeof(buffer) - currentlen - 2;

   while (free < newlen) {
       // spinwaiting
   }

   /* we can add another expression now */
   strcat(buffer, tBuffer);
   strcat(buffer, ";");

   /* Stop when user enters '.' */
   if (tBuffer[0] == '.') {
   return NULL;
   }
}
}


/* Where it all begins */
int smp3_main(int argc, char **argv)
{
void *arg = 0;       /* dummy value */

/* let's create our threads */
if (pthread_create(&multiplierThread, NULL, multiplier, arg)
   || pthread_create(&adderThread, NULL, adder, arg)
   || pthread_create(°rouperThread, NULL, degrouper, arg)
   || pthread_create(&sentinelThread, NULL, sentinel, arg)
   || pthread_create(&readerThread, NULL, reader, arg)) {
   printErrorAndExit("Failed trying to create threads");
}

/* you need to join one of these threads... but which one? */
   pthread_join(readerThread, &arg);

pthread_detach(multiplierThread);
pthread_detach(adderThread);
pthread_detach(degrouperThread);
pthread_detach(sentinelThread);
pthread_detach(readerThread);

/* everything is finished, print out the number of operations performed */
fprintf(stdout, "Performed a total of %d operations\n", num_ops);
return EXIT_SUCCESS;
}

HERE IS H FILE:

/*************** YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE ***************/

#include
#include
#include
#include
#include
#include
#include
#include

#define LENGTH(a) ( sizeof(a) / sizeof(*(a)) )

#define BUF_SIZE 500

extern char buffer[BUF_SIZE];
extern int num_ops;

void *adder(void *arg);
void *multiplier(void *arg);
void *degrouper(void *arg);
void *sentinel(void *arg);
void *reader(void *arg);

int smp3_main(int argc, char **argv);

Implement adder function. Thank you

0 0
Add a comment Improve this question Transcribed image text
Answer #1

/* As requested, the adder function alone has been implemented */

/* Looks for an addition symbol "+" surrounded by two numbers, e.g. "5+6"
and, if found, adds the two numbers and replaces the addition subexpression
with the result ("(5+6)*8" becomes "(11)*8")--remember, you don't have
to worry about associativity! */
void *adder(void *arg)
{
int bufferlen;
int value1, value2;
int startOffset, remainderOffset;
int i, sum, operlength ;
char *operand;

while(1) {
startOffset = remainderOffset = -1;
value1 = value2 = -1;
sum = 0;

if (timeToFinish()) {
return NULL;
}

/* storing this prevents having to recalculate it in the loop */
bufferlen = strlen(buffer);
operand = (char *)malloc(bufflen * sizeof(char));

for (i = 0; i < bufferlen; i++)
{
// Look for a '+' in the expression.
if(buffer[i] == '+')
   {  
// Look for the beginning of the left operand
       for(startOffset = i; startOffset -1 >=0 && isNumeric(buffer[startOffset-1]); --startOffset);
       // If the left operand is not a naked number, proceed with finding the next '+'
       if( startOffset == i)
           continue;
      
       // Look for the beginning of the right operand
       for(remainderOffset = i; remainderOffset +1 < bufferlen && isNumeric(buffer[remainderOffset+1]); ++remainderOffset);
       // If the right operand is not a naked number, proceed with finding the next '+'
       if( remainderOffset == i)
           continue;
      
       // Now we have a naked number on both the left and right sides
       // Let us now convert the operands to numbers
      
       // Left operand
       strncpy(operand, &buffer[startOffset], i-startOffset);
       operand[i-startOffset] = '\0';
       string2int(value1, operand);
      
       // Right operand
       strncpy(operand, &buffer[remainderOffset], remainderOffset - i);
       operand[remainderOffset - i] = '\0';
       string2int(value2, operand);
      
       // add the two operands
       sum = value1 + value2;
      
       // convert the numeric sum to a string
       sprint(operand, "%d", sum);
      
       operlength = strlen(operand);
       // write the string sum back into the buffer
       strncpy( &buffer[startOffset], operand, operlength);
      
       // Shift the remaining characters to the left
       strcpy( &buffer[operlength], &buffer[remainderOffset+1]);
      
// Accordingly reset the buffer length      
       bufferlen = bufferlen - (remainderOffset - startOffset + 1) + operlength;
   }
}
free(operand);
}
}

Add a comment
Know the answer?
Add Answer to:
Step 2: Implement adder, multiplier, and degrouper -------------------------------------------------- Write the code to implement these functions. They...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Read the following code, threaded recursive calculation of Fibonacci number of n: #include <stdio.h> #include <stdlib.h>...

    Read the following code, threaded recursive calculation of Fibonacci number of n: #include <stdio.h> #include <stdlib.h> #include <pthread.h> void *fib(void *arg); int main(int argc, char **argv){     int n = atoi(argv[1]);     printf("%d\n", (int)fib(n)); } void *fib(void *arg){     int n;     pthread_t thread1;     pthread_t thread2;     void *a;     void *b;     int c;     n = (int)arg;     if (n <= 0) return 0;     if (n == 1) return 1;     pthread_create(&thread1, NULL, fib, n-1);    ...

  • /* myloggerd.c * Source file for thread-lab * Creates a server to log messages sent from...

    /* myloggerd.c * Source file for thread-lab * Creates a server to log messages sent from various connections * in real time. * * Student: */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <pthread.h> #include "message-lib.h" // forward declarations int usage( char name[] ); // a function to be executed by each thread void * recv_log_msgs( void * arg ); // globals int log_fd; // opened by main() but accessible...

  • I am supposed to write documentation and report for the code below but I am new...

    I am supposed to write documentation and report for the code below but I am new to operating system concepts I will appreciate if someone can help make a detailed comment on each line of code for better understanding. Thanks #include <pthread.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <ctype.h> #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) struct thread_info...

  • In c programming The Consumer Submits processing requests to the producer by supplying a file name, its location and a character. It also outputs the contents of the file provided by the producer...

    In c programming The Consumer Submits processing requests to the producer by supplying a file name, its location and a character. It also outputs the contents of the file provided by the producer to the standard output. The Producer Accepts multiple consumer requests and processes each request by creating the following four threads. The reader thread will read an input file, one line at a time. It will pass each line of input to the character thread through a queue...

  • Concurrent Key-Value Database Implement a non-persistent, concurrent key-value database using the Reader/Writers algorithm. - Use a...

    Concurrent Key-Value Database Implement a non-persistent, concurrent key-value database using the Reader/Writers algorithm. - Use a hashmap as the underlying data structure. Inspiration is ok, however the implementation must be yours. The hashmap must be able to grow to fit new elements, but it does not need to reduce its size. -- Linked lists? Positional arrays? All are fine. - Keys and values are strings (char *) - Operations are: get, put Provided files: - Implement the contract set in...

  • Read given code and write all possible outputs of the program. Assume there will be no...

    Read given code and write all possible outputs of the program. Assume there will be no thread creation or joining failures or mutex failures. If you believe there i only one possible output, you just need to write that output. Code: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <errno.h> sem_t s1; int c[2] = {0,1}; void *UpdateC1(void *arg) { int i; for(i=0;i<1000000;i++) { sem_wait(&s1); c[0]=(c[0]+1)%2; c[1]=(c[1]+1)%2; sem_post(&s1); } return NULL; } void *UpdateC2(void *arg) { int i; for(i=0;i<2000000;i++)...

  • Read given code RaceOrNot1.c and write all possible outputs of the program. Assume there will be...

    Read given code RaceOrNot1.c and write all possible outputs of the program. Assume there will be no thread creation or joining failures or mutex failures. If you believe there is only one possible output, you just need to write that output. #include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t count_mutex3 = PTHREAD_MUTEX_INITIALIZER; int c[2] = {1,0}; void *UpdateC1(void *arg) {    int i;    for(i=0;i<1000000;i++)    {        pthread_mutex_lock(&count_mutex);        c[0]=(c[0]+1)%2;        c[1]=(c[1]+1)%2;        pthread_mutex_unlock(&count_mutex);    }    return NULL; } void *UpdateC2(void *arg) {    int...

  • Read given code RaceOrNot1.c and write all possible outputs of the program. Assume there will be...

    Read given code RaceOrNot1.c and write all possible outputs of the program. Assume there will be no thread creation or joining failures or mutex failures. If you believe there is only one possible output, you just need to write that output. #include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t count_mutex3 = PTHREAD_MUTEX_INITIALIZER; int c[2] = {1,0}; void *UpdateC1(void *arg) {    int i;    for(i=0;i<1000000;i++)    {        pthread_mutex_lock(&count_mutex);        c[0]=(c[0]+1)%2;        c[1]=(c[1]+1)%2;   ...

  • 1. (50 pts) Write a C or C++ program A6p1.c(pp) that accepts one command line argument which is an integer...

    1. (50 pts) Write a C or C++ program A6p1.c(pp) that accepts one command line argument which is an integer n between 2 and 6 inclusive. Generate a string of 60 random upper case English characters and store them somewhere (e.g. in a char array). Use pthread to create n threads to convert the string into a complementary string ('A'<>'Z', 'B'<->'Y', 'C''X', etc). You should divide this conversion task among the n threads as evenly as possible, Print out the...

  • Read given code RaceOrNot3.c and write all possible outputs of the program. Assume there will be...

    Read given code RaceOrNot3.c and write all possible outputs of the program. Assume there will be no thread creation or joining failures or semaphore failures. If you believe there is only one possible output, you just need to write that output. #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <errno.h> sem_t s1; int c=0,x=0; void *UpdateC1(void *arg) {    int i;    for(i=0;i<2000000;i++)   {        sem_wait(&s1);        c++;   x++;        sem_post(&s1);    } } void *UpdateC2(void *arg) {    int i,x=0;    for(i=0;i<2999999;i++)   {        sem_wait(&s1);        c++;   x++;       ...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT