APPFS
Advanced practical programming for scientists
 All Data Structures Files Functions Variables Typedefs Macros
Macros | Functions
ex1c.c File Reference

Appfs Exercise 1: memory mapped file input. More...

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

Go to the source code of this file.

Macros

#define MAX_NUMS   ((INT_MAX >> 5) + 1)
 Maximum number of 32 bit ints we need to store bits. More...
 

Functions

int main (int argc, char **argv)
 Program to read a file with binary positive 32 bit integers, sort the numbers and print them sorted. More...
 

Detailed Description

Author
Thorsten Koch
Date
18Oct2014

gcc -O3 -Wall -std=c99 -o ex1c ex1c.c

Use memory mapped file for input

Definition in file ex1c.c.

Macro Definition Documentation

#define MAX_NUMS   ((INT_MAX >> 5) + 1)

Definition at line 21 of file ex1c.c.

Function Documentation

int main ( int  argc,
char **  argv 
)

Actually, the numbers are not sorted. There is an array with one bit for each possible number. Upon reading the respective bit is set for the number recognized. At the end the array is scanned in order and the numbers present are printed.

Parameters
argv[1] name of file to read

Definition at line 31 of file ex1c.c.

32 {
33  const char* usage = "usage: %s filename\n";
34 
35  /* made static, because otherwise, the stack size might be too small.
36  */
37  static unsigned int have_num[MAX_NUMS];
38 
39  struct stat stat;
40  int* map;
41  int fd;
42  int total_nums = 0;
43 
44  /* we assume 32 bit integers, otherwise it will not work
45  */
46  assert(sizeof(int) == 4);
47 
48  /* Check arguments, we need a filename.
49  */
50  if (argc < 2)
51  {
52  fprintf(stderr, usage, argv[0]);
53  exit(EXIT_FAILURE);
54  }
55  memset(have_num, 0, sizeof(have_num)); // Proably uneccessary
56 
57  /* Open file
58  */
59  if (0 > (fd = open(argv[1], O_RDONLY)))
60  {
61  perror(argv[1]);
62  exit(EXIT_FAILURE);
63  }
64 
65  if (fstat(fd, &stat))
66  {
67  perror("fstat: ");
68  exit(EXIT_FAILURE);
69  }
70 
71  if (MAP_FAILED == (map = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, fd, 0)))
72  {
73  close(fd);
74  perror("mmap: ");
75  exit(EXIT_FAILURE);
76  }
77 
78  /* Read from file until data exhausted
79  */
80  total_nums = stat.st_size / sizeof(int);
81 
82  for(int i = 0; i < total_nums; i++)
83  {
84  /* Check input: really >= 0 ? Otherwise ignore
85  */
86  if (map[i] >= 0)
87  {
88  int idx = map[i] >> 5; // n / 32
89  unsigned int msk = 1 << (map[i] & 31); // bit number n mod 32
90 
91  assert(idx >= 0 && idx < MAX_NUMS);
92 
93  have_num[idx] |= msk;
94  }
95  }
96 
97  if (munmap(map, stat.st_size))
98  {
99  perror("munmap: ");
100  exit(EXIT_FAILURE);
101  }
102  if (close(fd))
103  {
104  perror("close: ");
105  exit(EXIT_FAILURE);
106  }
107 
108  fprintf(stderr, "Total numbers read = %d\n", total_nums);
109 
110  for(int i = 0; i < MAX_NUMS; i++)
111  if (have_num[i]) // just for speed up
112  for(int k = 0; k < 31; k++)
113  if (have_num[i] & (1 << k))
114  printf("%d\n", (i << 5) + k);
115 
116  return EXIT_SUCCESS;
117 }
#define MAX_NUMS
Maximum number of 32 bit ints we need to store bits.
Definition: ex1c.c:21