Ejemplo n.º 1
0
void *starsToCaret(void *s){
	printf("Thread_3: starsToCaret \n");
	thread_Producer_Consumer_init *p = s;
	bool isStarLast = false;
	char processingTank;
	
	while (1) {
		withdrawalCirBuf(&processingTank, p->buffer_C);
		if (isStarLast) { //Last input is sta
			if (processingTank == '*') {
				processingTank = '^';
			}
			else {
				depositCirBuf(p->buffer_P, '*');
			}
			isStarLast = false;
		}
		else if(processingTank == '*') {
				isStarLast = true;
				continue;
		}
		depositCirBuf(p->buffer_P, processingTank);
		if (processingTank == EOF) {
			break;
		}	
	}
	printf("Thread 3: starsToCaret Existing\n");
	st_thread_exit(NULL);	
}
Ejemplo n.º 2
0
void *print80CharLines(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char toPrint[LINE_TO_PRINT_SIZE + 1] = ""; // +1 for null-termination
  int index = 0;
  int toBreak = 0;

while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0)){
        toBreak = 1;
      }
    }

    if (toBreak == 0){
      down(init->bin_sem);
      //deadlock on consume unless extra produce in asterisk
      theCharacter = consume(init->from);
      printf("consumed: [%c]\n", theCharacter);
      toPrint[index] = theCharacter;
      index++;
      if (index == LINE_TO_PRINT_SIZE){
        toPrint[80] = '\0'; // terminates string
        printf("%s\n", toPrint);
        toPrint[0] = '\0'; // resets string
      }
      up(init->bin_sem);
    }
  }

  // done, exit thread
  printf("EXIT PRINT\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 3
0
//second processor function: takes in a character and checks if it's an asterisk. If not, it just passes the character 
//If so, pulls in another character and check if it's another
//asterisk. If so, it will pass along a carat symbol, if not it just passes both characters. Ends at EOF after passing
//
//Modifier
void *secondproc_thread_func(void *s){
	ThreadInit *i = s;
	/*
 	use a buffer system to check for double-asteriks
	*/
	int c = 0; //if c is not an asterisk, just produce it
	int char_buff = 0;
	int carat = '^'; //convenience
	while(1) {
		//assert there must be at least one full buff if full buffers down passes
		//so read has run at least once and called full buffers up
		c = consumeChar(i);

		if (c == '*'){//if c is a asterisk, get another character to check
			char_buff = consumeChar(i);
			if (char_buff == '*'){
				//we can assert that we know the buffer isn't full
				//by similar logic as the above. This is the only thread that
				//writes to it and if empty buffers passes, output thread function has run
				
				produceChar (i, carat); //if both are asterisks, produce carat
			}
			else{
				produceChar (i, c);		//if only one is asterisk, produce both
				produceChar (i, char_buff);
			}
		}
		else
			produceChar (i, c); //if not asterisks, produce c
		
		if (c == EOF || char_buff == EOF)
			break;
	}
	st_thread_exit(NULL);
}
Ejemplo n.º 4
0
/*
 * Asynchronous DNS host name resolution. This program creates one
 * ST thread for each host name (specified as command line arguments).
 * All threads do host name resolution concurrently.
 */
int main(int argc, char *argv[])
{
  int i;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s <hostname1> [<hostname2>] ...\n", argv[0]);
    exit(1);
  }

  if (st_init() < 0) {
    perror("st_init");
    exit(1);
  }

  for (i = 1; i < argc; i++) {
    /* Create a separate thread for each host name */
    if (st_thread_create(do_resolve, argv[i], 0, 0) == NULL) {
      perror("st_thread_create");
      exit(1);
    }
  }

  st_thread_exit(NULL);

  /* NOTREACHED */
  return 1;
}
Ejemplo n.º 5
0
//The output thread: Takes in characters and jams them in an array to wait. Once the thread reaches 80 characters, it outputs the array.
//Exciting.
//Ends at EOF; doesn't output it because it's a weird lookin character.
//
//Observer, kinda
void *output_thread_func (void *s){
	IOThreadInit *i = s;
	//80 char array to be output
	char output[81];
	int c = 0;
	//printf("%c",'\n');
	while(1) {
		//code saving functions dont take IOThreadInit :/
		//has to be written explicitly
		down(i->fullbuffs);
		down(i->mutex);
		c = cbConsume(i->buffer);
		up(i->mutex);
		up(i->emptybuffs);
		output[strlen(output)] = c;
		if (strlen(output) == output_size){
			printf("%s", output);
			printf("%c", '\n');
			memset(output, '\0', strlen(output) * sizeof(char));
		}
		if (c == EOF)
			break;
	}
	st_thread_exit(NULL);
}
Ejemplo n.º 6
0
CAMLprim value caml_thread_exit(value unit)   /* ML */
{
  struct longjmp_buffer * exit_buf = NULL;

  if (curr_thread == NULL) invalid_argument("Thread.exit: not initialized");

  /* In native code, we cannot call pthread_exit here because on some
     systems this raises a C++ exception, and ocamlopt-generated stack
     frames cannot be unwound.  Instead, we longjmp to the thread
     creation point (in caml_thread_start) or to the point in
     caml_main where caml_termination_hook will be called.
     Note that threads created in C then registered do not have
     a creation point (exit_buf == NULL).
 */
#ifdef NATIVE_CODE
  exit_buf = curr_thread->exit_buf;
#endif
  caml_thread_stop();
  if (exit_buf != NULL) {
    /* Native-code and (main thread or thread created by Caml) */
    siglongjmp(exit_buf->buf, 1);
  } else {
    /* Bytecode, or thread created from C */
    st_thread_exit();
  }
  return Val_unit;  /* not reached */
}
Ejemplo n.º 7
0
void *outputProcessing(void *s){
	printf("Thread_4: outputProcessing \n");
	thread_Producer_Consumer_init *p = s;
	char processingTank[2 * OUTPUT_SIZE];
	int tankLevel = 0;
	while (1) {
		for (tankLevel = 0; tankLevel < OUTPUT_SIZE; tankLevel++) {
			withdrawalCirBuf(&processingTank[tankLevel], p->buffer_C);
			if (processingTank[tankLevel]==EOF) {
				tankLevel++;
				break;
			}
		}
		processingTank[tankLevel]='\0';
		if (processingTank[tankLevel-1]==EOF) {
			break;
		}
		if (tankLevel>=OUTPUT_SIZE) {
			printf("Output: \n%s\n%s\n%s\n",ruler, processingTank, ruler);
			tankLevel = 0;
			continue;
		}
		printf("ERROR:===IMPOSSIBLE TO BE HERE\n");
	}
	printf("Thread 4: outputProcessing Existing\n");
	st_thread_exit(NULL);
}
Ejemplo n.º 8
0
void _st_thread_main(void)
{
	st_thread_t *thread = _ST_CURRENT_THREAD();

	/* Run thread main */
	thread->retval = (*thread->start)(thread->arg);

	/* All done, time to go away */
	st_thread_exit(thread->retval);
}
void* SrsThread::thread_fun(void* arg)
{
    SrsThread* obj = (SrsThread*)arg;
    srs_assert(obj);
    
    obj->thread_cycle();

    st_thread_exit(NULL);
    
    return NULL;
}
Ejemplo n.º 10
0
int main (int argc, const char * argv[]) {
	thread_Producer_Consumer_init inputProcessing_init;
	thread_Producer_Consumer_init carriageToSpace_init;
	thread_Producer_Consumer_init starsToCaret_init;
	thread_Producer_Consumer_init outputProcessing_init;
	if (st_init()<0) {
		perror("st_init");
		exit(1);
	}
	
	circularBuffer buf1, buf2, buf3;
	newBuffer(&buf1, BUFFER_SIZE); //for buffer inputProcessing & carriageToSpace
	newBuffer(&buf2, BUFFER_SIZE); //for buffer carriageToSpace & starsToCaret
	newBuffer(&buf3, BUFFER_SIZE); //for buffer starsToCaret & outputProcessing
		
	inputProcessing_init.buffer_C = NULL;
	inputProcessing_init.buffer_P = &buf1;
	
	carriageToSpace_init.buffer_C = &buf1;
	carriageToSpace_init.buffer_P = &buf2;	
	
	starsToCaret_init.buffer_C = &buf2;
	starsToCaret_init.buffer_P = &buf3;
	
	outputProcessing_init.buffer_C = &buf3;
	outputProcessing_init.buffer_P = NULL;
	
	if (st_thread_create(inputProcessing, &inputProcessing_init, 0, 0)==NULL) {
		perror("st_thread_create \n");
		exit(1);
	}
	
	if (st_thread_create(carriageToSpace, &carriageToSpace_init, 0, 0)==NULL) {
		perror("st_thread_create \n");
		exit(1);
	}
	
	if (st_thread_create(starsToCaret, &starsToCaret_init, 0, 0)==NULL) {
		perror("st_thread_create \n");
		exit(1);
	}
	
	if (st_thread_create(outputProcessing, &outputProcessing_init, 0, 0)==NULL) {
		perror("st_thread_create \n");
		exit(1);
	}
	printf("Hello World~~~~~~\n");
	
	fflush(stdout);
	st_thread_exit(NULL);
	
    return 0;	
}
Ejemplo n.º 11
0
// creates two threads using ST, one of which increments a shared counter,
// and one of which decrements it. The counter's value is printed to stdout
// after each operation. After a certain number of operations the program
// terminates.
int main (int argc, char const *argv[]) {
	// initialize the ST library runtime
	st_init();
	
	// store an arbitrary integer
	int value = 0;
	
	// create a binary semaphore initialized to 1
	semaphore bin_sem;
	createSem(&bin_sem, 1);
	
	// which output stream to use
	FILE *output = DEFAULT_OUT;
	
	// create our init data struct
	ThreadInit thread_init = {
		output,
		&bin_sem,
		&value
	};

  //JSR
  int semValue = 1;
  int i;
  for (i = 0; i < 5; i++){
    semValue++;
    up(thread_init.bin_sem);
    printf("semValue= %d\n", semValue);
  }

  /*
	// create the increment thread
	if (st_thread_create(increment_thread_func, &thread_init, 0, 0) == NULL) {
		perror("st_thread_create for increment thread failure");
		exit(1);
	}
	
	// create the decrement thread
	if (st_thread_create(decrement_thread_func, &thread_init, 0, 0) == NULL) {
		perror("st_thread_create for decrement thread failure");
		exit(1);
	}
  */

	// main thread exits
	st_thread_exit(NULL);
	return 0;
}
Ejemplo n.º 12
0
//thread to change asterisks to carats
void *asterisksToCarat(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char nextCharacter;
  char carat = '^'; //used for produce() if it needs a carat
  int toBreak = 0;

  while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
    down(init->from_bin_sem);
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0))
        toBreak = 1;
    }

    if (toBreak == 0){ 
      up(init->from_bin_sem);
      theCharacter = consume(init->from);
      if (theCharacter == '*'){
        nextCharacter = consume(init->from);
        if (nextCharacter == '*'){ // if two successive asterisks
          down(init->to_bin_sem);
          produce(init->to, &carat);
        }
        else { // if they're not both asterisks
          down(init->to_bin_sem);
          produce(init->to, &theCharacter);
          produce(init->to, &nextCharacter); 
        }
      }
      else { //the character was not an asterisk
        down(init->to_bin_sem);
        produce(init->to, &theCharacter);
      }
      up(init->to_bin_sem);
    }
    up(init->from_bin_sem);// releases from if toBreak == 1
  }

  // lets next buffer know when to stop consuming
  down(init->to_bin_sem);
  *(init->to->doneInserting) = 1;
  up(init->to_bin_sem);

  // done, exit thread
  st_thread_exit(NULL);
}
Ejemplo n.º 13
0
// thread to change newlines to spaces
void *newlineToSpace(void *t){
  printf("in newline\n");
  ThreadInit *init = t;
  char theCharacter;
  char space = ' '; //used for produce() in the case it needs a space
  int toBreak = 0; //toBreak is boolean initialized to FALSE
  int printed = 0;

  //printf("input's numElements: %d\n", *(init->from->numElements));

  while(toBreak == 0) {
    printf("in newline  while\n");
    //if "from" is done inserting, and there are no elements, break
    if( *(init->from->doneInserting) == 1){
      printf("in first if\n");
      if( (*init->from->numElements == 0)){
        printf("input's numElements = 0\n");
        toBreak = 1;
      }
    }
    printf("after nested if's\n");

    down(init->bin_sem);
    printf("in bin_sem and before consume\n");
    if (toBreak != 1){
      theCharacter = consume(init->from);
    }
    printf("after consume\n");
    if (theCharacter == '\n'){
      produce(init->to, &space);
    }
    else{
      produce(init->to, &theCharacter);
    }
    up(init->bin_sem);
    printf("out of bin_sem\n");
    printf("exit else if\n");
  }
  printf("exit while\n");

  // lets next buffer know when to stop consuming
  *(init->to->doneInserting) = 1;

  //done, exit thread
  printf("EXIT NL\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 14
0
void *carriageToSpace(void *s){
	printf("Thread_2: carriageToSpace \n");
	thread_Producer_Consumer_init *p = s;
	char processingTank;
	while (1) {
		withdrawalCirBuf(&processingTank, p->buffer_C);
		if (processingTank =='\n') {
			processingTank = ' ';
		}
		depositCirBuf(p->buffer_P, processingTank);
		if (processingTank==EOF) {
			break;
		}
	}
	printf("Thread 2: carriageToSpace Existing\n");
	st_thread_exit(NULL);
}
Ejemplo n.º 15
0
void _st_thread_main(void)
{
  _st_thread_t *thread = _ST_CURRENT_THREAD();

  /*
   * Cap the stack by zeroing out the saved return address register
   * value. This allows some debugging/profiling tools to know when
   * to stop unwinding the stack. It's a no-op on most platforms.
   */
  MD_CAP_STACK(&thread);

  /* Run thread main */
  thread->retval = (*thread->start)(thread->arg);

  /* All done, time to go away */
  st_thread_exit(thread->retval);
}
Ejemplo n.º 16
0
void *print80CharLines(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char toPrint[LINE_TO_PRINT_SIZE + 1] = ""; // +1 for null-termination
  int index = 0;
  int toBreak = 0;

while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
//    printf("from done inserting?[%d]\n", *(init->from->doneInserting));
//    printf("from numElements?[%d]\n", *(init->from->numElements));
    down(init->from_bin_sem);
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0)){
        toBreak = 1;
      }
    }

    if (toBreak == 0){
      //extra consume called after asterisk is called
      up(init->from_bin_sem);

      //deadlock here

      printf("about to call consume\n");
      //don't want to call consume if asterisks is done and
      //nothing is there...
      theCharacter = consume(init->from);
      printf("consumed: [%c]\n", theCharacter);
      toPrint[index] = theCharacter;
//      printf("char[%c], index[%d]\n", theCharacter, index);
      index++;
      if (index == LINE_TO_PRINT_SIZE){
        toPrint[80] = '\0'; // terminates string
        printf("%s\n", toPrint);
        toPrint[0] = '\0'; // resets string
        index = 0;
      }
    }
  }

  // done, exit thread
  printf("EXIT PRINT\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 17
0
void *asterisksToCarat(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char nextCharacter;
  char carat = '^'; //used for produce() if it needs a carat
  char null = '\0';
  int toBreak = 0;

  while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0))
        toBreak = 1;
    }

    if (toBreak == 0){ 
      down(init->bin_sem);
      theCharacter = consume(init->from);
      if (theCharacter == '*'){
        nextCharacter = consume(init->from);
        if (nextCharacter == '*'){
          produce(init->to, &carat);
        }
        else {
          produce(init->to, &theCharacter);
          produce(init->to, &nextCharacter); 
        }
      }
      else{ 
        printf("producing: [%c]\n", theCharacter);
        produce(init->to, &theCharacter);
      }
      up(init->bin_sem);
    }
  }

  // lets next buffer know when to stop consuming
  down(init->bin_sem);
  *(init->to->doneInserting) = 1;
  up(init->bin_sem);

  // done, exit thread
  printf("EXIT ASTERISK\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 18
0
// thread to get input from stdin
void *getInput(void *t){
  ThreadInit *init = t;

  int theCharacter;
  int count = 0;
  while(theCharacter != EOF){
    down(init->bin_sem);
    theCharacter = getchar();
    produce(init->to, &theCharacter);
    count++;
    up(init->bin_sem);
  }

  // lets next buffer know when to stop consuming
  *(init->to->doneInserting) = 1;

  // done, exit thread
  printf("EXIT INPUT\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 19
0
// function called by the increment thread
// increments the counter, prints the current value, and then
// sleeps for some time.
void *increment_thread_func(void *s) {
	ThreadInit *init = s; // cast the void pointer to keep compiler happy
	
	int num_inc;

	for (num_inc = 0; num_inc < DEFAULT_NUM_ITERS; num_inc++) {
		// decrement the semaphore
		down(init->bin_sem);
	 	// dereference the value pointer, then increment it
		(*(init->value_ptr))++;
		// print the current value
		fprintf(init->output_stream, "%d\n", (*(init->value_ptr)));
		fflush(init->output_stream);
		// increment the semaphore
		up(init->bin_sem);
		// wait some time
		st_usleep(INC_SLEEP_TIME);
	}
	// all done - thread exits
	st_thread_exit(NULL);
}
Ejemplo n.º 20
0
void *pong(void *s)
{
    thread_init *p = s;  /* p has the proper type instead of void */
    char sync_char[1];
    bool forever = true;

    while (forever)
    {
        BB_get(sync_char);

        if (quit)
            break;

        assert(sync_char[0] == 'S');

        printf("%s\n", p->my_call);
    }
    printf("Pong exiting\n");
    fflush(stdout);
    st_thread_exit(NULL);
}
Ejemplo n.º 21
0
void *print80CharLines(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char toPrint[LINE_TO_PRINT_SIZE + 1] = ""; // +1 for null-termination
  int index = 0;
  int toBreak = 0;

while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
    down(init->from_bin_sem);
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0)){
        toBreak = 1;
      }
    }

    if (toBreak == 0){
      up(init->from_bin_sem);
      //only call consume if there are elements to be consumed
      if(*(init->from->numElements) != 0){ 
        theCharacter = consume(init->from);
        //puts character in the buffer to print
        if(theCharacter != EOF){
          toPrint[index] = theCharacter;
          index++;
        }
        if (index == LINE_TO_PRINT_SIZE){
          toPrint[80] = '\0'; // terminates string
          printf("%s\n", toPrint);
          toPrint[0] = '\0'; // resets string
          index = 0;
        }
      }
    }
  }

  // done, exit thread
  st_thread_exit(NULL);
}
Ejemplo n.º 22
0
//the first of the two processing functions: takes in a character in ascii and processes whether the character is a newline
//and if it is, it will pass along a space otherwise it passes the character. Ends on EOF after passing it along
//
//Modifier
void *firstproc_thread_func (void *s){
	ThreadInit *i = s;
	int c = 0;
	int space = 32;
	while(1) {
		//assert there must be at least one full buff if full buffers down passes
		//so read has run at least once and called full buffers up
		c = consumeChar(i);
		//do our processing, pass the space if we meet a newline
		if (c == '\n')
			produceChar(i, space);
		
		//we can assert that we know the buffer isn't full
		//by similar logic as the above. This is the only thread that
		//writes to it and if empty buffers passes, second process thread function has run
		else
			produceChar(i ,c);
		if (c == EOF)
			break;
	}
	st_thread_exit(NULL);
}
Ejemplo n.º 23
0
// thread to change newlines to spaces
void *newlineToSpace(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char space = ' '; // used for produce() in the case it needs a space
  int toBreak = 0; // toBreak is boolean initialized to FALSE

  while(toBreak == 0) {
    //if "from" is done inserting, and there are no elements, break
    down(init->from_bin_sem);
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0)){
        toBreak = 1;
      }
    }

    if (toBreak == 0){ // do only if toBreak is FALSE
      theCharacter = consume(init->from);
      down(init->to_bin_sem);
      if (theCharacter == '\n'){
        produce(init->to, &space);
      }
      else{
        produce(init->to, &theCharacter);
      }
//      printf("elements after nl produce: [%d]\n", *init->to->numElements);
      up(init->to_bin_sem);
    }
    up(init->from_bin_sem);
  }

  // lets next buffer know when to stop consuming
  down(init->to_bin_sem);
  *(init->to->doneInserting) = 1;
  up(init->to_bin_sem);

  //done, exit thread
  printf("EXIT NL\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 24
0
void *ping(void *s)
{
    thread_init *p = s;  /* p has the proper type instead of void */
    int i;
    int sleep_time;
    char sync[1] = {'S'};
    unsigned int rand_seed = p->my_seed;

    for (i = 0; i < p->count; i++)
    {
        sleep_time = 1 + (rand_r(&rand_seed) % p->max_sleep);
        printf("%s (Delay %d seconds before & after Pong thread)\n", p->my_call, sleep_time);
        st_sleep(sleep_time);
        BB_put(sync);
        st_sleep(sleep_time);   /* give pong a chance to run */
    }
    quit = true;
    printf("Ping exiting\n");
    BB_put(sync);
    fflush(stdout);
    st_thread_exit(NULL);
}
Ejemplo n.º 25
0
void *inputProcessing(void *s){
	thread_Producer_Consumer_init *p = s;
	char inputReceiver = 0;
	printf("%s\n%s\n%s\n",ruler,"Welcome to Duo's HW4 ([email protected]) ",ruler);	
	printf("Thread_1: inputProcessing \n");
	printf("Please Enter: \n");
	
	while (1) {
		if (fscanf(stdin, "%1c", &inputReceiver)==EOF) {
			inputReceiver = EOF;
		}
		depositCirBuf(p->buffer_P, inputReceiver); //Semaphore and mutex included
		if (inputReceiver==EOF) {
			break;
		}
		if (inputReceiver=='\n') {
			st_sleep(WAIT_TIME);
			printf("Please Continue to Enter: \n");
		}
	}
	printf("Thread 1: inputProcessing Existing\n");
	st_thread_exit(NULL);	
}
Ejemplo n.º 26
0
void *print80CharLines(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char toPrint[LINE_TO_PRINT_SIZE + 1] = ""; // +1 for null-termination
  int index = 0;
  int toBreak = 0;

while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0))
        toBreak = 1;
    }
    else {
      printf("in print while\n");
      
      down(init->bin_sem);
      printf("in print bin_sem\n");
      theCharacter = consume(init->from);
      printf("after print consume\n");
      toPrint[index] = theCharacter;
      index++;
      if (index == LINE_TO_PRINT_SIZE){
        toPrint[80] = '\0'; // terminates string
        printf("%s\n", toPrint);
        toPrint[0] = '\0'; // resets string
      }
      up(init->bin_sem);
      printf("exit print bin_sem\n");
    }
  }

  // done, exit thread
  printf("EXIT PRINT\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 27
0
//**See documentation above for produces and consumes**
//
//Define these functions
//read function: takess in raw characters and turns them into ascii code which it passes
//to the first-processing thread. Ends at EOF asfter passing it along
//
//Observer 
void *read_thread_func (void *s){
	IOThreadInit *i = s; //keep the compiler from whining about void stuf
	int c;
	
	while (1){
		//we can assert that there's a empty buffer for two reasons
		//first, this is the only thread that produces to it so no other one can touch it
		//second, if the empty buffers semaphore here passes its down, it means the first processing
		//thread has run empty buffers up so at least one caracter has to have been consumed

		c = fgetc(INPUT);
		down(i->emptybuffs);
			down(i->mutex);
				cbProduce(i->buffer, c);
			up(i->mutex);
		up(i->fullbuffs);
		if (c == EOF)
			break;
		 //by ending at EOF, we will pass the final WOF character which we'll use to end the program
		 //This also helps assert when the threads should end because we can say that after EOF has 
		 //passed through the previous thread, we know there's no more to be processed
	}
	st_thread_exit(NULL);
}
Ejemplo n.º 28
0
main(){
  // initialize the ST library runtime, necessary for up() and down()
  st_init();

  //BoundedBuffer into which input from stdin is stored
  BoundedBuffer theInput;
  createBuffer(&theInput, MAX_BUFF_SIZE);

  // create a binary semaphore for use with input thread
  semaphore input_sem;
  createSem(&input_sem, 1);

  ThreadInit getInputThread = {
    NULL, // no input buffer for getInput thread, comes from stdin
    &theInput, // puts data from stdin into BoundedBuffer theInput 
    NULL, //no "from" semaphore
    &input_sem //mutual exclusion for input buffer
  };

  // create input thread
  if (st_thread_create(getInput, &getInputThread, 0, 0) == NULL){
    perror("st_thread_create for getInput failure");
    exit(1);
  }

  // BoundedBuffer into which processed data w/o newlines are stored
  BoundedBuffer newLinesProcessed;
  createBuffer(&newLinesProcessed, MAX_BUFF_SIZE);
  
  // create binary semaphore for use with newline thread
  semaphore nl_sem;
  createSem(&nl_sem, 1);

  ThreadInit nlToSpaceThread = {
    &theInput, // processes input from the BoundedBuffer theInput
    &newLinesProcessed, // puts processed data into BB newLinesProcessed
    &input_sem, //mutual exclusion for input buffer
    &nl_sem // mutual exclusion for processed newlines buffer
  };

  //create newline processing thread
  if (st_thread_create(newlineToSpace, &nlToSpaceThread,0,0) == NULL){
    perror("st_thread_create for newlineToSpace failure");
    exit(1);
  }

  // BoundedBuffer into which processed data after asterisks are handled go
  BoundedBuffer caratsProcessed;
  createBuffer(&caratsProcessed, MAX_BUFF_SIZE);
  
  // create binary semaphore for use with newline thread
  semaphore carat_sem;
  createSem(&carat_sem, 1);

  ThreadInit caratThread = {
    &newLinesProcessed, // buffer from wich input is processed
    &caratsProcessed, // puts processed data into BB caratsProcessed
    &nl_sem, // for mutual exclusion in previous buffer
    &carat_sem // for mutual exclusion in processed carat buffer
  };

  // create asterisks to carat processing thread
  if (st_thread_create(asterisksToCarat, &caratThread,0,0) == NULL){
    perror("st_thread_create for newlineToSpace failure");
    exit(1);
  }

  ThreadInit printThread = {
    &caratsProcessed, // buffer from which input is processed
    NULL, // no output buffer, just printing to stdout
    &carat_sem, // for mutual exclusion in previous buffer
    NULL // no mutex needed, just printing to stdout
  };

  // create print thread
  if (st_thread_create(print80CharLines, &printThread,0,0) == NULL){
    perror("st_thread_create for print80CharLines failure");
    exit(1);
  }

  // exit main thread
  st_thread_exit(NULL);
}
Ejemplo n.º 29
0
//thread to change asterisks to carats
void *asterisksToCarat(void *t){
  ThreadInit *init = t;
  char theCharacter;
  char nextCharacter;
  char carat = '^'; //used for produce() if it needs a carat
  int toBreak = 0;

  while(toBreak == 0) {
    //if from is done inserting and there are no elements, break
    down(init->from_bin_sem);

    //printf("ast. done inserting?[%d]\n", *(init->from->doneInserting));
    //printf("ast. numElements?[%d]\n", *(init->from->numElements));

    if( *(init->from->doneInserting) == 1){
      if( (*init->from->numElements == 0))
        toBreak = 1;
    }

    if (toBreak == 0){ 
      up(init->from_bin_sem);
      theCharacter = consume(init->from);
      if (theCharacter == '*'){
        nextCharacter = consume(init->from);
        if (nextCharacter == '*'){ // if two successive asterisks
          printf("producing: [%c]\n", carat);
          down(init->to_bin_sem);
          produce(init->to, &carat);
        }
        else { // if they're not both asterisks
          down(init->to_bin_sem);
          printf("producing: [%c]\n", theCharacter);
          produce(init->to, &theCharacter);
          printf("producing: [%c]\n", nextCharacter);
          produce(init->to, &nextCharacter); 
        }
      }
      else { //the character was not an asterisk
        down(init->to_bin_sem);
printf("ast. producing: [%c]\n", theCharacter);
        produce(init->to, &theCharacter);
        //pretty sure produce context switches to waiting print func.
        //so this is always 0, even though it's being updated right
printf("elems. after ast. produce: [%d]\n", *(init->to->numElements));
      }
      up(init->to_bin_sem);
    }
    up(init->from_bin_sem);
  }

  // lets next buffer know when to stop consuming

  down(init->to_bin_sem);
  *(init->to->doneInserting) = 1;
  up(init->to_bin_sem);

  char theNull = '\0';
  produce(init->to, &theNull);

  // done, exit thread
  printf("EXIT ASTERISK\n");
  st_thread_exit(NULL);
}
Ejemplo n.º 30
0
int main(int argc, char *argv[])
{
    int loop_count;
    int sleep_secs;
    int buffer_size;

    const int ping_arg = 1;
    const int pong_arg = 2;
    const int loop_arg = 3;
    const int sleep_arg = 4;
    const int size_arg = 5;

    thread_init ping_init;
    thread_init pong_init;

    /* validity check parameter count */
    if (argc != NUM_ARGS)
    {
        printf("Bad parameter count %d\n", argc);
        printf("Positional parameters: ping & pong strings, loop count, sleep limit, buffer size\n");
        exit (ERR_RETURN);
    }

    /* the loop count is the third positional parameter */
    loop_count = atoi(argv[loop_arg]);  /* atoi converts string to integer */

    /* the sleep limit seconds is the fourth positional */
    sleep_secs = atoi(argv[sleep_arg]);  /* atoi converts string to integer */
    if (sleep_secs > MAX_SLEEP)
    {
        printf("Sleep of %d exceeds maximum %d\n", sleep_secs, MAX_SLEEP);
        exit (ERR_RETURN);
    }

    /* the buffer size is the fifth positional */
    buffer_size = atoi(argv[size_arg]);  /* atoi converts string to integer */

    /* This call is required to initialize the thread library */

    if (st_init() < 0) {
        perror("st_init");
        exit(1);
    }

    /* This call is required to initialize the bounded buffer.
     * The size (in characters) may be set to any value between
     * one and MAX_BUFFER (defined in BB.h).  The call must be
     * made AFTER the st_init() call and BEFORE any producers or
     * consumers using the bounded buffer are started.
     */

    if (BB_init(buffer_size) != 0)
    {
        printf("Buffer size initializer %d not in valid range\n", buffer_size);
        exit(-1);
    }

    /* Create a separate thread for each of ping and pong */

    /* create an initializer for pong thread */
    pong_init.my_call = argv[pong_arg];
    pong_init.my_seed = 0;  /* not used by pong */
    pong_init.count = 0;  /* not used by pong */
    pong_init.max_sleep = 0;  /* not used by pong */

    /* start it first so it will block first
     * The first parameter is the initial function executed in
     * the thread.  The second is the only allowed parameter to
     * the initial function and must be a pointer to any type.
     */

    if (st_thread_create(pong, &pong_init, 0, 0) == NULL)
    {
        perror("st_thread_create");
        exit(1);
    }

    /* create an initializer for ping thread */
    ping_init.my_call = argv[ping_arg];
    ping_init.my_seed = (unsigned int) getpid();  /* unique random seed each run */
    ping_init.count = loop_count;
    ping_init.max_sleep = sleep_secs;

    if (st_thread_create(ping, &ping_init, 0, 0) == NULL)
    {
        perror("st_thread_create");
        exit(1);
    }
    /* causes the main thread to exit with others still running */
    printf("Main thread exiting\n");
    fflush(stdout);
    st_thread_exit(NULL);
}