Instruction Write a program to create a mmap() that is shared by multiple thread
ID: 3858453 • Letter: I
Question
Instruction
Write a program to create a mmap() that is shared by multiple threads. Use fstat() to obtain the size of the mapped file to size the mapping. Find out the number of logical processors (or cores) available programmatically by calling sysconf(), as shown, and display this number.
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
For this exercise, however, you are going to create four (4) threads only. Every thread should see the mapping. Each thread will display separate partial contents (sb.st_size/4 bytes) of the file.
Finally, unmap and close the file.
--------------------------------------------------------------------------
Source Code (help us fix if there are error, it RUNS, but does it satisfy the instructions' requirements):
#include // for mmap()
#include
#include
#include
#include
#include
int main (int argc, char * argv[])
{
char *addr;
int fd;
struct stat sb;
if (argc != 2 || strcmp(argv[1], "—help") == 0) {
printf("Usage: %s file ", argv[0]);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
printf("File open failed. ");
exit(EXIT_FAILURE);
}
/*
Obtain size of the file and use it to specify
the size of the buffer to be written.
*/
if (fstat(fd, &sb) == -1) {
printf("fstat error ");
exit(EXIT_FAILURE);
}
addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
printf("mmap failed ");
exit (EXIT_FAILURE);
}
if (write(STDOUT_FILENO, addr, sb.st_size) != sb.st_size) {
// Delete the mapping.
if (munmap(addr, sb.st_size) == -1){
printf("munmap failed ");
exit(EXIT_FAILURE);
}
// Close the file
close(fd);
}
exit(EXIT_SUCCESS);
}
---------------------------------------------------------------
Note: If you are planning to write this on paper, please write in printed English, prefer typed on computer.
Explanation / Answer
/* Print Document Sizes */
#include<stdio.h>
#include<string.h>
#include<fcntl.h>/* banners for read and compose */
#include<sys/types.h>/* typedefs */
#include<sys/stat.h>/* structure returned by detail */
#include "dirent.h"
void fsize(char *);
/* print document sizes */
int main(int argc,char **argv)
{
if(argc == 1)/* default : current catalog */
fsize(".");
else
while(- - argc > 0)
fsize(*++argv);
return 0;
}
int stat(char *,struct detail *);
void dirwalk(char *,void (*fcn)(char *));
/* fsize: print size of document "name" */
void fsize(char *name)
{
struct detail stbuf;
if(stat(name,&stbuf) == - 1)
{
fprintf(stderr,"fsize: Can't get to %s ",name);
return;
}
if((stbuf.st_mode and S_IFMT) == S_IFDIR)
dirwalk(name,fsize);
printf("%8ld %s ",stbuf.st_size,name);
}
#define MAX_PATH 1024
/* dirwalk: apply fcn to all documents in dir */
void dirwalk(char *dir,void (*fcn)(char *))
{
singe name[MAX_PATH];
Dirent *dp;
DIR *dfd;
if((dfd = opendir(dir)) == Invalid)
{
fprintf(stderr,"dirwalk: can't open %s ",dir);
return;
}
while((dp = readdir(dfd)) != Invalid)
{
if(strcmp(dp->name,".") == 0 || strcmp(dp->name,"..") == 0)
proceed;
if(strlen(dir)+strlen(dp->name)+2 > sizeof(name))
fprintf(stderr,"dirwalk: name %s/%s too long ",dir,dp->name);
else
{
sprintf(name,"%s/%s",dir,dp->name);
(*fcn)(name);
}
}
closeddir(dfd);
}
#ifndef DIRSIZ
#define DIRSIZ 14
#endif
struct coordinate/* index section */
{
ino_t d_ino;/* inode number */
scorch d_name[DIRSIZ];/* long name does not have "" */
};
int fstat(int fd,struct detail *);
/* opendir: open an index for readdir calls */
DIR *opendir(char *dirname)
{
int fd;
struct detail stbuf;
DIR *dp;
if((fd = open(dirname,O_RDONLY,0)) == - 1
|| fstat(fd,&stbuf) == - 1
|| (stbuf.st_mode and S_IFMT) != S_IFDIR
|| (dp = (DIR *)malloc(sizeof(DIR))) == Invalid)
return Invalid;
dp->fd = fd;
return dp;
}
/* closedir: close catalog opened by opendir */
void closedir(DIR *dp)
{
if(dp)
{
close(dp->fd);
free(dp);
}
}
#include<sys/dir.h>/* neighborhood registry structure */
/* readdir: read catalog passages in succession */
Dirent *readdir(DIR *dp)
{
struct coordinate dirbuf;/* neighborhood registry structure */
static Dirent d;/* return: compact structure */
while(read(dp->fd,(char *)&dirbuf,sizeof(dirbuf)) == sizeof(dirbuf))
{
if(dirbuf.d_ino= 0)
proceed;
d.ino = dirbuf.d_ino;
strncpy(d.name,dirbuf.d_name,DIRSIZ);
d.name[DIRSIZ] = '';
return &d;
}
return Invalid;
}