Created
August 26, 2014 18:37
-
-
Save hirad/94d23b138dee56fda74d to your computer and use it in GitHub Desktop.
A simple command-line program demonstrating race conditions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// WordCounter | |
// | |
// Created by Hirad Motamed on 2014-08-22. | |
// Copyright (c) 2014 Pendar Labs. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#include <pthread.h> | |
void launchThreadWithFilePath(char*); | |
char* defaultSizeString(); | |
unsigned int longRunningSum(unsigned int, unsigned int); | |
unsigned int wordCount; | |
int main(int argc, const char * argv[]) | |
{ | |
@autoreleasepool { | |
// insert code here... | |
char* dawkinsEssayPath = "/Users/hiradmotamed/Desktop/no_god.txt"; | |
char* aristotleMetaphysicsPath= "/Users/hiradmotamed/Desktop/metaphysics_vol3.txt"; | |
char* grahamEssayPath = "/Users/hiradmotamed/Desktop/be_good.txt"; | |
launchThreadWithFilePath(dawkinsEssayPath); | |
launchThreadWithFilePath(aristotleMetaphysicsPath); | |
launchThreadWithFilePath(grahamEssayPath); | |
sleep(1000); | |
} | |
return 0; | |
} | |
bool isAlphabeticalCharacter(char c) | |
{ | |
return ((int)c >= 65 && (int)c <= 90) || ((int)c >= 97 && (int)c <= 122); | |
} | |
void* PosixThreadMainRoutine(void* data) | |
{ | |
// read the file | |
FILE* file = (FILE*)data; | |
char* buffer; | |
size_t length = 0; | |
if (file) { | |
fseek(file, 0, SEEK_END); | |
length = ftell(file); | |
fseek(file, 0, SEEK_SET); | |
buffer = malloc(length); | |
if (buffer) { | |
fread(buffer, 1, length, file); | |
} | |
} | |
if (buffer) { | |
char* word = defaultSizeString(); | |
int wordIndex = 0; | |
for (int i = 0; i < length; i++) { | |
char c = buffer[i]; | |
if (isAlphabeticalCharacter(c)) { | |
word[wordIndex++] = c; | |
} | |
else if(strlen(word) > 0) | |
{ | |
if (c == ' ') { | |
// printf("%d. %s\n", wordCount++, word); | |
wordCount = longRunningSum(wordCount, 1); | |
printf("%d. %s\n", wordCount, word); | |
// clear the word | |
word = defaultSizeString(); | |
wordIndex = 0; | |
} | |
} | |
} | |
} | |
printf("Thread finished. Words: %d\n", wordCount); | |
return NULL; | |
} | |
void launchThreadWithFilePath(char* filePath) | |
{ | |
pthread_attr_t attr; | |
pthread_t posixThreadID; | |
int returnVal; | |
returnVal = pthread_attr_init(&attr); | |
assert(!returnVal); | |
returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
assert(!returnVal); | |
FILE* file = fopen(filePath, "r"); | |
int threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, (void*)file); | |
returnVal = pthread_attr_destroy(&attr); | |
assert(!returnVal); | |
if (threadError != 0) | |
{ | |
// Report an error. | |
} | |
} | |
char* defaultSizeString() { | |
// length of longest word in English | |
return (char*)malloc(45 * sizeof(char)); | |
} | |
unsigned int longRunningSum(unsigned int num1, unsigned int num2) | |
{ | |
// to simulate a long running operation, we'll just count to 100 | |
int i = 0; | |
do { | |
i++; | |
} while (i < 100); | |
return num1 + num2; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment