Lab 3 (5 points)
        CS550, Operating Systems
        Introduction to C-Style Pointers, C-Style Strings, POSIX
        Threads, and Processes 
Name: _____________________________________________
This assignment is based upon the UNIX labs from the CS2351 course at Oklahoma State University, previously available at cs.okstate.edu/newuser/index.html. To submit this assignment, you may copy and paste the assignment into a text editor such as nano, vi, notepad, MS Word, OpenOffice Writer, etc. Enter your answers into the document and submit it to the dropbox for lab 3. The purpose of this lesson is to learn to about command line debugging, pointers, threads, and processes in the C programming language.
1. Enter, compile, and run the following application:
#include
      <stdio.h>
      
      int main(int argc, char ** argv)
      {
        int arr[3] = {1,2,3};
        int x = 7;
        int * intPointer = &x;  //This is an integer
      pointer and contains the
                               
      //address of x.
      
        printf("Welcome to C!\n");
        printf("arr contains %d, %d, and %d\n", arr[0], arr[1],
      arr[2]);
      
        printf("x is %d, the address of x is %u, the address of arr
      is %u\n", x, intPointer, arr);
      
        //Notice that an integer pointer can also hold the address
      of an integer array.
        intPointer = arr;
        printf("The address of arr is %u\n", intPointer);
      
        //The * operator, when applied to a pointer, dereferences a
      pointer or an address
        intPointer = &x;
      
        printf("Dereferencing the address of x gives its value,
      which is %d\n", *intPointer);
      
        printf("Dereferencing arr provides arr[0] which is %d\n",
      *arr);
        printf("Dereferencing arr+1 provides arr[1] which is %d\n",
      *(arr+1));
        printf("Dereferencing arr+2 provides arr[2] which is %d\n",
      *(arr+2));
    
  return
      0;
      }
You may type this file into the nano text editor, or copy and paste it.
PuTTY users will open PuTTY and connect to the LittleFe server as
      shown in class.  Log on to LittleFe and create a new file
      called Welcome.c
      with the nano editor.  Users wishing to copy and paste the
      text into nano should return to this webpage, highlight the text
      of the source code, right click, and click copy.  Return to
      the nano editor, and right click inside the editor.  The text
      of the source code should now be inside the editor.  Press
      Ctrl-X to save and exit from nano.
    
Non-PuTTY users will log on to LittleFe as usual and create a new file called Welcome.c with the nano editor. Users may copy the code from this website. When inside the nano editor, right click and choose paste. The text of the source code should now be inside the editor. Press Ctrl-X to save and exit from nano.
Introduce the following errors, one at a time to the program Welcome.c. Compile the program and write down any error messages that the compiler produces. Fix the previous error message before you introduce a new error. If no errors were produced, explain why.
a. Change argc to argx.
b. Change Welcome to welcome.
c. Remove the first quote in the printf statement.
d. Remove the last quote in the printf statement.
e. Change main to mai.
f. Change printf to println.
g. Remove the semicolon at the end of the printf statement.
h. Remove the last curly bracket in the program.
i. Remove arr[0], arr[1], and arr[2] from the second printf
      statement.
    
j. Change arr[0] to arr[4].
    
k. Change arr[0] to arr[50000] (this should cause a segmentation
      fault).
    
    
2. Complete, compile, and run the following application. Name it Lab3.c
You may copy and paste the following code into nano while using PuTTY or another ssh client.
//
      <Name>
      // cs550
      // Lab3
      
      #include <stdio.h>
      
      int main(int argc, char ** argv)
      {
        char str[300];
        int iX;
        double dX;
      
        //Prompt the user to enter a line of text.
        printf("Please enter a line of text (less than 300
      characters): ");
      
        //Use fgets to store a line of text from stdin in str.
      
        //Prompt the user to enter an integer.
        printf("Enter an integer: ");
      
        //Use scanf to store the integer in iX.
      
        //Prompt the user to enter a double.
        printf("Please enter a real number: ");
      
        //Use fgets and sscanf to store the double value in dX.
      
        //Print the results.
        printf("%s %d %lf\n", str, iX, dX);
        return 0;
      }
    
To create an output file, use the UNIX command script:
$script
      Lab3.out
      Script started, file is Lab3.out
      $cat Lab3.c
      
      <code is automatically printed here via the cat command>
      
      $gcc Lab3.c -o Lab3.exe
      $./Lab3.exe
      
      <run the program to completion>
      
      $exit
      Script done, file is Lab3.out
Copy your file from the LittleFe system to your own system using
      SFTP (the Secure File Transfer Protocol).  Instructions for
      an sftp client are provided at the following site:
      http://catpages.nwmissouri.edu/m/monismi/cs550/examples/sftp.html
    
    
3. The following program prints hello from ten POSIX (Portable
      Operating System Interface) threads.  Read through the
      following program and run it.  Provide a copy of your output
      when you submit the assignment.
    
#include <stdio.h>
        #include <stdlib.h>
        #include <pthread.h>
        
        #define NUM_THREADS 10
        //Add your static array here
        
        //Define our thread function
        void * HelloThread(void * threadId)
        {
          long tid;  // This thread's identifier
          tid = (long) threadId;
          //Modify the static array here
        
          printf("Hello from thread %ld\n", tid);
        
          pthread_exit(NULL); //Cause the thread to die.
        }
        
        int main(int argc, char ** argv)
        {
          pthread_t threadList[NUM_THREADS];  //Declare and
        allocate memory for t$
                                             
        //list of threads
        
          int returnCode;
          long i;  //Counter to keep track of the current
        thread
        
          for(i = 0; i < NUM_THREADS; i++)
         {
            printf("From main, creating thread %ld\n",
        i);
        
            //Create the threads storing the thread
        identifier in the thread
            //list.  Note that we pass in the name
        of the function that will
            //act as the thread as the third parameter,
        and the following
            //parameters are the parameters passed into
        the thread.
        
            returnCode =
        pthread_create(&threadList[i], NULL, HelloThread, 
              (void *) i);
        
            if(returnCode != 0)
            {
              printf("The return code from
        thread %ld is %d\n", i, returnCode);
              exit(-1);
            }
          }
        
          //Print the static array here
        
          //Kill the main thread
          pthread_exit(NULL);
        }
    
To compile the program above assuming it is named lab3Threads.c,
      use the following command on any Linux system:
    
gcc lab3Threads.c -pthread -o
        lab3Threads.exe
    
4. The following program creates ten processes and prints hello
      from each of them.  Read through the program and run
      it.  Include your output with your submission.
    
#include <sys/types.h>
        #include <stdio.h>
        #include <unistd.h>
        #include <stdlib.h>
        
        #define NUM_PROCESSES 10
        //Declare your static array here
        
        int main(int argc, char ** argv)
        {
          pid_t pid;
          int i;
        
          //Fork a child process
          for(i = 0; i < NUM_PROCESSES; i++)
          {
            pid = fork();
        
            if(pid < 0)
            {
              fprintf(stderr, "Fork failed\n");
              return 1;
            }
            else if(pid == 0)
            {
              //Each child process starts here
              //Modify the static array here
              printf("Child %d complete!\n",
        i);
              exit(0);
            } 
            else
            {
              //parent process
              printf("Parent started process
        %d\n", i);
            }
          }
          wait(NULL);
          printf("Finished parent process\n");
          return 0;
        }
    
To compile the program above, assuming it is called lab3Processes.c,
      use the following command:
    
gcc lab3Processes.c -o lab3Processes.exe
    
5. Add a static integer array of size NUM_THREADS
      immediately after the line containing the #define in the
      thread program from problem 3.  The code for this array
      follows below.
    
static int arr[NUM_THREADS];
    
Set arr[(int) tid)] to a value of your choice within each
      thread.  Note that this value must be different for every
      thread.  It could be the same as the thread identifier, if
      you wish.
    
Print the contents of this array immediately before you kill the
      main thread.
    
Include a copy of your source code and the output in your
      submission.
    
6. Repeat problem 5 using processes instead of threads for the
      program in problem 4.  Why is the output different? 
      Hint: think about process memory space.
    
7. Compile and run the following program on Stampede (Host Name:
      stampede.tacc.utexas.edu ).  You should be able to login to
      Stampede using PuTTY and your Stampede username.  Note that
      you are not allowed to run your program (also called a
      job) on the login node.  Instructions to submit, run, check,
      and, if necessary, to kill a job follow after the program. 
      Note that Stampede runs a variation of Linux called CentOS. 
      Most of the commands you used on Littlefe such as ps, ls, cat,
      nano, etc., work on Stampede.  
    
#include <stdio.h>
        #include <stdlib.h>
        #include "mpi.h"
        
        int main (int argc, char** argv)
        {
          int number_of_processes;
          int my_rank;
          int mpi_error_code;
        
          mpi_error_code = MPI_Init(&argc, &argv);
        
          mpi_error_code = MPI_Comm_rank(MPI_COMM_WORLD,
        &my_rank);
        
          mpi_error_code = MPI_Comm_size(MPI_COMM_WORLD,
        &number_of_processes);
        
          printf("%d o%d: Hello, world!\n", my_rank,
        number_of_processes);
        
          mpi_error_code = MPI_Finalize();
        }
    
Save this program in a file named hello_world.c on
      Stampede.  
    
On Stampede, you must submit batch scripts to run your
      programs.  This means your job waits in a virtual line before
      it may run.  The batch queue scheduler on Stampede is called
      SLURM (like the drink on Futurama).  Write a SLURM batch
      script for your program as follows:
    
#!/bin/bash
        #SBATCH -A TG-SEE120004  #Account number
        #SBATCH -n
        16           
        #Number of tasks (cores)
        #SBATCH -J helloWorld    #Job name
        #SBATCH -o hw.o%j      #Output file
        name
        #SBATCH -p normal       
        #Queue to use
        #SBATCH -t 00:15:00     #Run (wall) time
        15min
        ibrun hello_world.exe
    
Save this batch script in a file called hello.sbatch on
      Stampede.
    
Compile your program on the head node using the following
      command.  Note that this is ok because the compilation uses
      very few resources.
    
mpicc hello_world.c -O3 -o
        hello_world.exe
    
Note that the executable file name matches exactly with what will
      run in the batch script using ibrun.
    
Fix any errors in your program, and submit your program to the
      batch queue using the following command:
    
sbatch hello.sbatch
    
Once your program finishes, the output will show up in a file
      called hw.oJobNumber, where JobNumber is the job
      number assigned to your job by Stampede.  You can find this
      file by using the ls command.  Turn in the
          contents of this file.
    
While your program is in the batch, run the following commands on
      Stampede.  If necessary, submit your program to the batch
      queue again and quickly run the commands below.  Note that
      the up and down arrow keys can be used to scroll through
      previously issued commands.
    
showq
    
What happened after running showq?
    
squeue -u Username
    
Where Username is your Stampede username.  What happened
      after running the command above?
    
Note that you may have a program that runs in an infinite loop or
      enters a condition called deadlock or livelock.  To end such
      a program that is running on Stampede, you may first determine the
      job number using squeue as shown above and killing the program
      with the following command:
    
scancel JobNumber