run clang-format

This commit is contained in:
Bassem Girgis
2018-10-17 23:47:57 -05:00
parent 558e8e22da
commit c8a8949366
56 changed files with 4153 additions and 3900 deletions

104
.clang-format Normal file
View File

@@ -0,0 +1,104 @@
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: TopLevelDefinitions
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBraces : Custom
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeInheritanceComma: true
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 2
UseTab: Never

View File

@@ -73,7 +73,13 @@ ch04/pipe_cpp.cpp
NAMES_CXX=$(SOURCES_CXX:.cpp=) NAMES_CXX=$(SOURCES_CXX:.cpp=)
PROGRAMS_CXX=$(addprefix $(BIN)/, $(NAMES_CXX)) PROGRAMS_CXX=$(addprefix $(BIN)/, $(NAMES_CXX))
all: dirs ${PROGRAMS_C} ${PROGRAMS_CXX} all: format dirs ${PROGRAMS_C} ${PROGRAMS_CXX}
format:
#clang-format -i $(SOURCE)/*.c*
#clang-format -i $(SOURCE)/*.h*
clang-format -i $(SOURCE)/*/*.c*
clang-format -i $(SOURCE)/*/*.h*
dirs: dirs:
mkdir -p $(BIN) mkdir -p $(BIN)

View File

@@ -7,7 +7,8 @@
*/ */
#include "errors.h" #include "errors.h"
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int seconds; int seconds;
char line[128]; char line[128];
@@ -15,18 +16,20 @@ int main (int argc, char *argv[])
while (1) { while (1) {
printf("Alarm> "); printf("Alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen (line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
/* /*
* Parse input line into seconds (%d) and a message * Parse input line into seconds (%d) and a message
* (%64[^\n]), consisting of up to 64 characters * (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace. * separated from the seconds by whitespace.
*/ */
if (sscanf (line, "%d %64[^\n]", if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2) {
&seconds, message) < 2) {
fprintf(stderr, "Bad command\n"); fprintf(stderr, "Bad command\n");
} else { }
else {
sleep(seconds); sleep(seconds);
printf("(%d) %s\n", seconds, message); printf("(%d) %s\n", seconds, message);
} }

View File

@@ -8,7 +8,8 @@
#include <wait.h> #include <wait.h>
#include "errors.h" #include "errors.h"
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int status; int status;
char line[128]; char line[128];
@@ -18,18 +19,20 @@ int main (int argc, char *argv[])
while (1) { while (1) {
printf("Alarm> "); printf("Alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen (line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
/* /*
* Parse input line into seconds (%d) and a message * Parse input line into seconds (%d) and a message
* (%64[^\n]), consisting of up to 64 characters * (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace. * separated from the seconds by whitespace.
*/ */
if (sscanf (line, "%d %64[^\n]", if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2) {
&seconds, message) < 2) {
fprintf(stderr, "Bad command\n"); fprintf(stderr, "Bad command\n");
} else { }
else {
pid = fork(); pid = fork();
if (pid == (pid_t) -1) if (pid == (pid_t) -1)
errno_abort("Fork"); errno_abort("Fork");
@@ -40,7 +43,8 @@ int main (int argc, char *argv[])
sleep(seconds); sleep(seconds);
printf("(%d) %s\n", seconds, message); printf("(%d) %s\n", seconds, message);
exit(0); exit(0);
} else { }
else {
/* /*
* In the parent, call waitpid() to collect any children that * In the parent, call waitpid() to collect any children that
* have already terminated. * have already terminated.

View File

@@ -12,7 +12,8 @@ typedef struct alarm_tag {
char message[64]; char message[64];
} alarm_t; } alarm_t;
void *alarm_thread (void *arg) void*
alarm_thread(void* arg)
{ {
alarm_t* alarm = (alarm_t*) arg; alarm_t* alarm = (alarm_t*) arg;
int status; int status;
@@ -25,7 +26,8 @@ void *alarm_thread (void *arg)
free(alarm); free(alarm);
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int status; int status;
char line[128]; char line[128];
@@ -34,8 +36,10 @@ int main (int argc, char *argv[])
while (1) { while (1) {
printf("Alarm> "); printf("Alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen (line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
alarm = (alarm_t*) malloc(sizeof(alarm_t)); alarm = (alarm_t*) malloc(sizeof(alarm_t));
if (alarm == NULL) if (alarm == NULL)
errno_abort("Allocate alarm"); errno_abort("Allocate alarm");
@@ -45,13 +49,12 @@ int main (int argc, char *argv[])
* (%64[^\n]), consisting of up to 64 characters * (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace. * separated from the seconds by whitespace.
*/ */
if (sscanf (line, "%d %64[^\n]", if (sscanf(line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2) {
&alarm->seconds, alarm->message) < 2) {
fprintf(stderr, "Bad command\n"); fprintf(stderr, "Bad command\n");
free(alarm); free(alarm);
} else { }
status = pthread_create ( else {
&thread, NULL, alarm_thread, alarm); status = pthread_create(&thread, NULL, alarm_thread, alarm);
if (status != 0) if (status != 0)
err_abort(status, "Create alarm thread"); err_abort(status, "Create alarm thread");
} }

View File

@@ -4,11 +4,12 @@
* Demonstrate detection of errors from a typical POSIX 1003.1c-1995 * Demonstrate detection of errors from a typical POSIX 1003.1c-1995
* function, pthread_join. * function, pthread_join.
*/ */
#include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h>
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread; pthread_t thread;
int status; int status;

View File

@@ -7,13 +7,15 @@
#include <pthread.h> #include <pthread.h>
#include "errors.h" #include "errors.h"
void *hello_world (void *arg) void*
hello_world(void* arg)
{ {
printf("Hello world\n"); printf("Hello world\n");
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t hello_id; pthread_t hello_id;
int status; int status;

View File

@@ -10,7 +10,8 @@
/* /*
* Thread start routine. * Thread start routine.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
printf("Inside thread %i\n", pthread_self()); printf("Inside thread %i\n", pthread_self());
return arg; return arg;
@@ -23,8 +24,7 @@ main (int argc, char *argv[])
int status; int status;
printf("Inside thread %i\n", pthread_self()); printf("Inside thread %i\n", pthread_self());
status = pthread_create ( status = pthread_create(&thread_id, NULL, thread_routine, NULL);
&thread_id, NULL, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
sleep(1.0); sleep(1.0);

View File

@@ -10,14 +10,16 @@
/* /*
* Thread start routine that writes a message. * Thread start routine that writes a message.
*/ */
void *writer_thread (void *arg) void*
writer_thread(void* arg)
{ {
sleep(5); sleep(5);
printf("Thread I/O\n"); printf("Thread I/O\n");
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t writer_id; pthread_t writer_id;
char *input, buffer[64]; char *input, buffer[64];

View File

@@ -36,7 +36,8 @@ time_t current_alarm = 0;
/* /*
* Insert alarm entry on list, in order. * Insert alarm entry on list, in order.
*/ */
void alarm_insert (alarm_t *alarm) void
alarm_insert(alarm_t* alarm)
{ {
int status; int status;
alarm_t **last, *next; alarm_t **last, *next;
@@ -70,8 +71,8 @@ void alarm_insert (alarm_t *alarm)
#ifdef DEBUG #ifdef DEBUG
printf("[list: "); printf("[list: ");
for (next = alarm_list; next != NULL; next = next->link) for (next = alarm_list; next != NULL; next = next->link)
printf ("%d(%d)[\"%s\"] ", next->time, printf(
next->time - time (NULL), next->message); "%d(%d)[\"%s\"] ", next->time, next->time - time(NULL), next->message);
printf("]\n"); printf("]\n");
#endif #endif
/* /*
@@ -91,7 +92,8 @@ void alarm_insert (alarm_t *alarm)
/* /*
* The alarm thread's start routine. * The alarm thread's start routine.
*/ */
void *alarm_thread (void *arg) void*
alarm_thread(void* arg)
{ {
alarm_t* alarm; alarm_t* alarm;
struct timespec cond_time; struct timespec cond_time;
@@ -125,15 +127,16 @@ void *alarm_thread (void *arg)
expired = 0; expired = 0;
if (alarm->time > now) { if (alarm->time > now) {
#ifdef DEBUG #ifdef DEBUG
printf ("[waiting: %d(%d)\"%s\"]\n", alarm->time, printf("[waiting: %d(%d)\"%s\"]\n",
alarm->time - time (NULL), alarm->message); alarm->time,
alarm->time - time(NULL),
alarm->message);
#endif #endif
cond_time.tv_sec = alarm->time; cond_time.tv_sec = alarm->time;
cond_time.tv_nsec = 0; cond_time.tv_nsec = 0;
current_alarm = alarm->time; current_alarm = alarm->time;
while (current_alarm == alarm->time) { while (current_alarm == alarm->time) {
status = pthread_cond_timedwait ( status = pthread_cond_timedwait(&alarm_cond, &alarm_mutex, &cond_time);
&alarm_cond, &alarm_mutex, &cond_time);
if (status == ETIMEDOUT) { if (status == ETIMEDOUT) {
expired = 1; expired = 1;
break; break;
@@ -143,7 +146,8 @@ void *alarm_thread (void *arg)
} }
if (!expired) if (!expired)
alarm_insert(alarm); alarm_insert(alarm);
} else }
else
expired = 1; expired = 1;
if (expired) { if (expired) {
printf("(%d) %s\n", alarm->seconds, alarm->message); printf("(%d) %s\n", alarm->seconds, alarm->message);
@@ -152,21 +156,23 @@ void *alarm_thread (void *arg)
} }
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int status; int status;
char line[128]; char line[128];
alarm_t* alarm; alarm_t* alarm;
pthread_t thread; pthread_t thread;
status = pthread_create ( status = pthread_create(&thread, NULL, alarm_thread, NULL);
&thread, NULL, alarm_thread, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create alarm thread"); err_abort(status, "Create alarm thread");
while (1) { while (1) {
printf("Alarm> "); printf("Alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen (line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
alarm = (alarm_t*) malloc(sizeof(alarm_t)); alarm = (alarm_t*) malloc(sizeof(alarm_t));
if (alarm == NULL) if (alarm == NULL)
errno_abort("Allocate alarm"); errno_abort("Allocate alarm");
@@ -176,11 +182,11 @@ int main (int argc, char *argv[])
* (%64[^\n]), consisting of up to 64 characters * (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace. * separated from the seconds by whitespace.
*/ */
if (sscanf (line, "%d %64[^\n]", if (sscanf(line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2) {
&alarm->seconds, alarm->message) < 2) {
fprintf(stderr, "Bad command\n"); fprintf(stderr, "Bad command\n");
free(alarm); free(alarm);
} else { }
else {
status = pthread_mutex_lock(&alarm_mutex); status = pthread_mutex_lock(&alarm_mutex);
if (status != 0) if (status != 0)
err_abort(status, "Lock mutex"); err_abort(status, "Lock mutex");

View File

@@ -34,7 +34,8 @@ alarm_t *alarm_list = NULL;
/* /*
* The alarm thread's start routine. * The alarm thread's start routine.
*/ */
void *alarm_thread (void *arg) void*
alarm_thread(void* arg)
{ {
alarm_t* alarm; alarm_t* alarm;
int sleep_time; int sleep_time;
@@ -69,8 +70,8 @@ void *alarm_thread (void *arg)
else else
sleep_time = alarm->time - now; sleep_time = alarm->time - now;
#ifdef DEBUG #ifdef DEBUG
printf ("[waiting: %d(%d)\"%s\"]\n", alarm->time, printf(
sleep_time, alarm->message); "[waiting: %d(%d)\"%s\"]\n", alarm->time, sleep_time, alarm->message);
#endif #endif
} }
@@ -101,21 +102,23 @@ void *alarm_thread (void *arg)
} }
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int status; int status;
char line[128]; char line[128];
alarm_t *alarm, **last, *next; alarm_t *alarm, **last, *next;
pthread_t thread; pthread_t thread;
status = pthread_create ( status = pthread_create(&thread, NULL, alarm_thread, NULL);
&thread, NULL, alarm_thread, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create alarm thread"); err_abort(status, "Create alarm thread");
while (1) { while (1) {
printf("alarm> "); printf("alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen (line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
alarm = (alarm_t*) malloc(sizeof(alarm_t)); alarm = (alarm_t*) malloc(sizeof(alarm_t));
if (alarm == NULL) if (alarm == NULL)
errno_abort("Allocate alarm"); errno_abort("Allocate alarm");
@@ -125,11 +128,11 @@ int main (int argc, char *argv[])
* (%64[^\n]), consisting of up to 64 characters * (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace. * separated from the seconds by whitespace.
*/ */
if (sscanf (line, "%d %64[^\n]", if (sscanf(line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2) {
&alarm->seconds, alarm->message) < 2) {
fprintf(stderr, "Bad command\n"); fprintf(stderr, "Bad command\n");
free(alarm); free(alarm);
} else { }
else {
status = pthread_mutex_lock(&alarm_mutex); status = pthread_mutex_lock(&alarm_mutex);
if (status != 0) if (status != 0)
err_abort(status, "Lock mutex"); err_abort(status, "Lock mutex");
@@ -163,8 +166,10 @@ int main (int argc, char *argv[])
#ifdef DEBUG #ifdef DEBUG
printf("[list: "); printf("[list: ");
for (next = alarm_list; next != NULL; next = next->link) for (next = alarm_list; next != NULL; next = next->link)
printf ("%d(%d)[\"%s\"] ", next->time, printf("%d(%d)[\"%s\"] ",
next->time - time (NULL), next->message); next->time,
next->time - time(NULL),
next->message);
printf("]\n"); printf("]\n");
#endif #endif
status = pthread_mutex_unlock(&alarm_mutex); status = pthread_mutex_unlock(&alarm_mutex);

View File

@@ -39,7 +39,9 @@ std::list<alarm_t> alarm_list;
/* /*
* The alarm thread's start routine. * The alarm thread's start routine.
*/ */
void *alarm_thread(void *arg) { void*
alarm_thread(void* arg)
{
int sleep_time; int sleep_time;
time_t now; time_t now;
int status; int status;
@@ -50,7 +52,8 @@ void *alarm_thread(void *arg) {
*/ */
while (1) { while (1) {
status = pthread_mutex_lock(&alarm_mutex); status = pthread_mutex_lock(&alarm_mutex);
if (status != 0) err_abort(status, "Lock mutex"); if (status != 0)
err_abort(status, "Lock mutex");
now = time(NULL); now = time(NULL);
sleep_time = 0; sleep_time = 0;
@@ -59,7 +62,8 @@ void *alarm_thread(void *arg) {
if (it->time <= now) { if (it->time <= now) {
printf("(%d) %s\n", it->seconds, it->message); printf("(%d) %s\n", it->seconds, it->message);
it = alarm_list.erase(it); it = alarm_list.erase(it);
} else { }
else {
sleep_time = MIN(it->time - now, sleep_time); sleep_time = MIN(it->time - now, sleep_time);
++it; ++it;
} }
@@ -74,7 +78,8 @@ void *alarm_thread(void *arg) {
* if there's no input. * if there's no input.
*/ */
status = pthread_mutex_unlock(&alarm_mutex); status = pthread_mutex_unlock(&alarm_mutex);
if (status != 0) err_abort(status, "Unlock mutex"); if (status != 0)
err_abort(status, "Unlock mutex");
if (sleep_time > 0) if (sleep_time > 0)
sleep(sleep_time); sleep(sleep_time);
else else
@@ -82,17 +87,22 @@ void *alarm_thread(void *arg) {
} }
} }
int main(int argc, char *argv[]) { int
main(int argc, char* argv[])
{
int status; int status;
char line[128]; char line[128];
pthread_t thread; pthread_t thread;
status = pthread_create(&thread, NULL, alarm_thread, NULL); status = pthread_create(&thread, NULL, alarm_thread, NULL);
if (status != 0) err_abort(status, "Create alarm thread"); if (status != 0)
err_abort(status, "Create alarm thread");
while (1) { while (1) {
printf("alarm> "); printf("alarm> ");
if (fgets(line, sizeof(line), stdin) == NULL) exit(0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen(line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
alarm_t alarm; alarm_t alarm;
/* /*
@@ -102,11 +112,13 @@ int main(int argc, char *argv[]) {
*/ */
if (sscanf(line, "%d %64[^\n]", &alarm.seconds, alarm.message) < 2) { if (sscanf(line, "%d %64[^\n]", &alarm.seconds, alarm.message) < 2) {
fprintf(stderr, "Bad command\n"); fprintf(stderr, "Bad command\n");
} else { }
else {
alarm.time = time(NULL) + alarm.seconds; alarm.time = time(NULL) + alarm.seconds;
status = pthread_mutex_lock(&alarm_mutex); status = pthread_mutex_lock(&alarm_mutex);
if (status != 0) err_abort(status, "Lock mutex"); if (status != 0)
err_abort(status, "Lock mutex");
/* /*
* Insert the new alarm into the list of alarms. * Insert the new alarm into the list of alarms.
@@ -116,12 +128,15 @@ int main(int argc, char *argv[]) {
#ifdef DEBUG #ifdef DEBUG
printf("[list: "); printf("[list: ");
for (const auto& iAlarm : alarm_list) for (const auto& iAlarm : alarm_list)
printf("%d(%d)[\"%s\"] ", iAlarm.time, iAlarm.time - time(NULL), printf("%d(%d)[\"%s\"] ",
iAlarm.time,
iAlarm.time - time(NULL),
iAlarm.message); iAlarm.message);
printf("]\n"); printf("]\n");
#endif #endif
status = pthread_mutex_unlock(&alarm_mutex); status = pthread_mutex_unlock(&alarm_mutex);
if (status != 0) err_abort(status, "Unlock mutex"); if (status != 0)
err_abort(status, "Unlock mutex");
} }
} }
} }

View File

@@ -17,11 +17,9 @@
/* /*
* Initialize a static array of 3 mutexes. * Initialize a static array of 3 mutexes.
*/ */
pthread_mutex_t mutex[3] = { pthread_mutex_t mutex[3] = {PTHREAD_MUTEX_INITIALIZER,
PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER};
PTHREAD_MUTEX_INITIALIZER
};
int backoff = 1; /* Whether to backoff or deadlock */ int backoff = 1; /* Whether to backoff or deadlock */
int yield_flag = 0; /* 0: no yield, >0: yield, <0: sleep */ int yield_flag = 0; /* 0: no yield, >0: yield, <0: sleep */
@@ -31,7 +29,8 @@ int yield_flag = 0; /* 0: no yield, >0: yield, <0: sleep */
* order, to ensure a conflict with lock_reverse, which does the * order, to ensure a conflict with lock_reverse, which does the
* opposite. * opposite.
*/ */
void *lock_forward (void *arg) void*
lock_forward(void* arg)
{ {
int i, iterate, backoffs; int i, iterate, backoffs;
int status; int status;
@@ -43,22 +42,22 @@ void *lock_forward (void *arg)
status = pthread_mutex_lock(&mutex[i]); status = pthread_mutex_lock(&mutex[i]);
if (status != 0) if (status != 0)
err_abort(status, "First lock"); err_abort(status, "First lock");
} else { }
else {
if (backoff) if (backoff)
status = pthread_mutex_trylock(&mutex[i]); status = pthread_mutex_trylock(&mutex[i]);
else else
status = pthread_mutex_lock(&mutex[i]); status = pthread_mutex_lock(&mutex[i]);
if (status == EBUSY) { if (status == EBUSY) {
backoffs++; backoffs++;
DPRINTF (( DPRINTF((" [forward locker backing off at %d]\n", i));
" [forward locker backing off at %d]\n",
i));
for (; i >= 0; i--) { for (; i >= 0; i--) {
status = pthread_mutex_unlock(&mutex[i]); status = pthread_mutex_unlock(&mutex[i]);
if (status != 0) if (status != 0)
err_abort(status, "Backoff"); err_abort(status, "Backoff");
} }
} else { }
else {
if (status != 0) if (status != 0)
err_abort(status, "Lock mutex"); err_abort(status, "Lock mutex");
DPRINTF((" forward locker got %d\n", i)); DPRINTF((" forward locker got %d\n", i));
@@ -78,8 +77,7 @@ void *lock_forward (void *arg)
/* /*
* Report that we got 'em, and unlock to try again. * Report that we got 'em, and unlock to try again.
*/ */
printf ( printf("lock forward got all locks, %d backoffs\n", backoffs);
"lock forward got all locks, %d backoffs\n", backoffs);
pthread_mutex_unlock(&mutex[2]); pthread_mutex_unlock(&mutex[2]);
pthread_mutex_unlock(&mutex[1]); pthread_mutex_unlock(&mutex[1]);
pthread_mutex_unlock(&mutex[0]); pthread_mutex_unlock(&mutex[0]);
@@ -93,7 +91,8 @@ void *lock_forward (void *arg)
* reverse order, to ensure a conflict with lock_forward, which * reverse order, to ensure a conflict with lock_forward, which
* does the opposite. * does the opposite.
*/ */
void *lock_backward (void *arg) void*
lock_backward(void* arg)
{ {
int i, iterate, backoffs; int i, iterate, backoffs;
int status; int status;
@@ -105,22 +104,22 @@ void *lock_backward (void *arg)
status = pthread_mutex_lock(&mutex[i]); status = pthread_mutex_lock(&mutex[i]);
if (status != 0) if (status != 0)
err_abort(status, "First lock"); err_abort(status, "First lock");
} else { }
else {
if (backoff) if (backoff)
status = pthread_mutex_trylock(&mutex[i]); status = pthread_mutex_trylock(&mutex[i]);
else else
status = pthread_mutex_lock(&mutex[i]); status = pthread_mutex_lock(&mutex[i]);
if (status == EBUSY) { if (status == EBUSY) {
backoffs++; backoffs++;
DPRINTF (( DPRINTF((" [backward locker backing off at %d]\n", i));
" [backward locker backing off at %d]\n",
i));
for (; i < 3; i++) { for (; i < 3; i++) {
status = pthread_mutex_unlock(&mutex[i]); status = pthread_mutex_unlock(&mutex[i]);
if (status != 0) if (status != 0)
err_abort(status, "Backoff"); err_abort(status, "Backoff");
} }
} else { }
else {
if (status != 0) if (status != 0)
err_abort(status, "Lock mutex"); err_abort(status, "Lock mutex");
DPRINTF((" backward locker got %d\n", i)); DPRINTF((" backward locker got %d\n", i));
@@ -140,8 +139,7 @@ void *lock_backward (void *arg)
/* /*
* Report that we got 'em, and unlock to try again. * Report that we got 'em, and unlock to try again.
*/ */
printf ( printf("lock backward got all locks, %d backoffs\n", backoffs);
"lock backward got all locks, %d backoffs\n", backoffs);
pthread_mutex_unlock(&mutex[0]); pthread_mutex_unlock(&mutex[0]);
pthread_mutex_unlock(&mutex[1]); pthread_mutex_unlock(&mutex[1]);
pthread_mutex_unlock(&mutex[2]); pthread_mutex_unlock(&mutex[2]);
@@ -150,7 +148,8 @@ void *lock_backward (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t forward, backward; pthread_t forward, backward;
int status; int status;
@@ -187,12 +186,10 @@ int main (int argc, char *argv[])
*/ */
if (argc > 2) if (argc > 2)
yield_flag = atoi(argv[2]); yield_flag = atoi(argv[2]);
status = pthread_create ( status = pthread_create(&forward, NULL, lock_forward, NULL);
&forward, NULL, lock_forward, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create forward"); err_abort(status, "Create forward");
status = pthread_create ( status = pthread_create(&backward, NULL, lock_backward, NULL);
&backward, NULL, lock_backward, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create backward"); err_abort(status, "Create backward");
pthread_exit(NULL); pthread_exit(NULL);

View File

@@ -13,8 +13,7 @@ typedef struct my_struct_tag {
int value; /* Access protected by mutex */ int value; /* Access protected by mutex */
} my_struct_t; } my_struct_t;
my_struct_t data = { my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
int hibernation = 1; /* Default to 1 second */ int hibernation = 1; /* Default to 1 second */
@@ -41,7 +40,8 @@ wait_thread (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int status; int status;
pthread_t wait_thread_id; pthread_t wait_thread_id;
@@ -76,8 +76,7 @@ int main (int argc, char *argv[])
err_abort(status, "Lock mutex"); err_abort(status, "Lock mutex");
while (data.value == 0) { while (data.value == 0) {
status = pthread_cond_timedwait ( status = pthread_cond_timedwait(&data.cond, &data.mutex, &timeout);
&data.cond, &data.mutex, &timeout);
if (status == ETIMEDOUT) { if (status == ETIMEDOUT) {
printf("Condition wait timed out.\n"); printf("Condition wait timed out.\n");
break; break;

View File

@@ -15,7 +15,8 @@ typedef struct my_struct_tag {
int value; /* Access protected by mutex */ int value; /* Access protected by mutex */
} my_struct_t; } my_struct_t;
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
my_struct_t* data; my_struct_t* data;
int status; int status;

View File

@@ -18,10 +18,10 @@ typedef struct my_struct_tag {
int value; /* Access protected by mutex */ int value; /* Access protected by mutex */
} my_struct_t; } my_struct_t;
my_struct_t data = { my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
return 0; return 0;
} }

View File

@@ -14,7 +14,8 @@ typedef struct my_struct_tag {
int value; /* Access protected by mutex */ int value; /* Access protected by mutex */
} my_struct_t; } my_struct_t;
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
my_struct_t* data; my_struct_t* data;
int status; int status;

View File

@@ -17,7 +17,8 @@ typedef struct my_struct_tag {
my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, 0}; my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, 0};
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
return 0; return 0;
} }

View File

@@ -24,7 +24,9 @@ time_t end_time;
* Thread start routine that repeatedly locks a mutex and * Thread start routine that repeatedly locks a mutex and
* increments a counter. * increments a counter.
*/ */
void *counter_thread(void *arg) { void*
counter_thread(void* arg)
{
int status; int status;
int spin; int spin;
@@ -36,11 +38,13 @@ void *counter_thread(void *arg) {
*/ */
while (time(NULL) < end_time) { while (time(NULL) < end_time) {
status = pthread_mutex_lock(&mutex); status = pthread_mutex_lock(&mutex);
if (status != 0) err_abort(status, "Lock mutex"); if (status != 0)
err_abort(status, "Lock mutex");
for (spin = 0; spin < SPIN; spin++) counter++; for (spin = 0; spin < SPIN; spin++) counter++;
sleep(4); sleep(4);
status = pthread_mutex_unlock(&mutex); status = pthread_mutex_unlock(&mutex);
if (status != 0) err_abort(status, "Unlock mutex"); if (status != 0)
err_abort(status, "Unlock mutex");
sleep(1); sleep(1);
} }
printf("Counter is %#lx\n", counter); printf("Counter is %#lx\n", counter);
@@ -52,7 +56,9 @@ void *counter_thread(void *arg) {
* seconds, try to lock the mutex and read the counter. If the * seconds, try to lock the mutex and read the counter. If the
* trylock fails, skip this cycle. * trylock fails, skip this cycle.
*/ */
void *monitor_thread(void *arg) { void*
monitor_thread(void* arg)
{
int status; int status;
int misses = 0; int misses = 0;
@@ -64,18 +70,23 @@ void *monitor_thread(void *arg) {
sleep(3); sleep(3);
status = pthread_mutex_trylock(&mutex); status = pthread_mutex_trylock(&mutex);
if (status != EBUSY) { if (status != EBUSY) {
if (status != 0) err_abort(status, "Trylock mutex"); if (status != 0)
err_abort(status, "Trylock mutex");
printf("Counter is %ld\n", counter / SPIN); printf("Counter is %ld\n", counter / SPIN);
status = pthread_mutex_unlock(&mutex); status = pthread_mutex_unlock(&mutex);
if (status != 0) err_abort(status, "Unlock mutex"); if (status != 0)
} else err_abort(status, "Unlock mutex");
}
else
misses++; /* Count "misses" on the lock */ misses++; /* Count "misses" on the lock */
} }
printf("Monitor thread missed update %d times.\n", misses); printf("Monitor thread missed update %d times.\n", misses);
return NULL; return NULL;
} }
int main(int argc, char *argv[]) { int
main(int argc, char* argv[])
{
int status; int status;
pthread_t counter_thread_id; pthread_t counter_thread_id;
pthread_t monitor_thread_id; pthread_t monitor_thread_id;
@@ -92,12 +103,16 @@ int main(int argc, char *argv[]) {
end_time = time(NULL) + 60; /* Run for 1 minute */ end_time = time(NULL) + 60; /* Run for 1 minute */
status = pthread_create(&counter_thread_id, NULL, counter_thread, NULL); status = pthread_create(&counter_thread_id, NULL, counter_thread, NULL);
if (status != 0) err_abort(status, "Create counter thread"); if (status != 0)
err_abort(status, "Create counter thread");
status = pthread_create(&monitor_thread_id, NULL, monitor_thread, NULL); status = pthread_create(&monitor_thread_id, NULL, monitor_thread, NULL);
if (status != 0) err_abort(status, "Create monitor thread"); if (status != 0)
err_abort(status, "Create monitor thread");
status = pthread_join(counter_thread_id, NULL); status = pthread_join(counter_thread_id, NULL);
if (status != 0) err_abort(status, "Join counter thread"); if (status != 0)
err_abort(status, "Join counter thread");
status = pthread_join(monitor_thread_id, NULL); status = pthread_join(monitor_thread_id, NULL);
if (status != 0) err_abort(status, "Join monitor thread"); if (status != 0)
err_abort(status, "Join monitor thread");
return 0; return 0;
} }

View File

@@ -9,10 +9,10 @@
* by calling thr_setconcurrency(), because threads are not * by calling thr_setconcurrency(), because threads are not
* timesliced. * timesliced.
*/ */
#include <sys/types.h> #include <dirent.h>
#include <pthread.h> #include <pthread.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h> #include <sys/types.h>
#include "errors.h" #include "errors.h"
#define CREW_SIZE 4 #define CREW_SIZE 4
@@ -58,7 +58,8 @@ size_t name_max; /* Name length */
* The thread start routine for crew threads. Waits until "go" * The thread start routine for crew threads. Waits until "go"
* command, processes work items until requested to shut down. * command, processes work items until requested to shut down.
*/ */
void *worker_routine (void *arg) void*
worker_routine(void* arg)
{ {
worker_p mine = (worker_t*) arg; worker_p mine = (worker_t*) arg;
crew_p crew = mine->crew; crew_p crew = mine->crew;
@@ -73,8 +74,7 @@ void *worker_routine (void *arg)
* buffer. Thus, allocate a "big chunk" of memory, and use * buffer. Thus, allocate a "big chunk" of memory, and use
* it as a buffer. * it as a buffer.
*/ */
entry = (struct dirent*)malloc ( entry = (struct dirent*) malloc(sizeof(struct dirent) + name_max);
sizeof (struct dirent) + name_max);
if (entry == NULL) if (entry == NULL)
errno_abort("Allocating dirent"); errno_abort("Allocating dirent");
@@ -113,7 +113,9 @@ void *worker_routine (void *arg)
err_abort(status, "Lock crew mutex"); err_abort(status, "Lock crew mutex");
DPRINTF(("Crew %d top: first is %#lx, count is %d\n", DPRINTF(("Crew %d top: first is %#lx, count is %d\n",
mine->index, crew->first, crew->work_count)); mine->index,
crew->first,
crew->work_count));
while (crew->first == NULL) { while (crew->first == NULL) {
status = pthread_cond_wait(&crew->go, &crew->mutex); status = pthread_cond_wait(&crew->go, &crew->mutex);
if (status != 0) if (status != 0)
@@ -121,7 +123,9 @@ void *worker_routine (void *arg)
} }
DPRINTF(("Crew %d woke: %#lx, %d\n", DPRINTF(("Crew %d woke: %#lx, %d\n",
mine->index, crew->first, crew->work_count)); mine->index,
crew->first,
crew->work_count));
/* /*
* Remove and process a work item * Remove and process a work item
@@ -132,7 +136,10 @@ void *worker_routine (void *arg)
crew->last = NULL; crew->last = NULL;
DPRINTF(("Crew %d took %#lx, leaves first %#lx, last %#lx\n", DPRINTF(("Crew %d took %#lx, leaves first %#lx, last %#lx\n",
mine->index, work, crew->first, crew->last)); mine->index,
work,
crew->first,
crew->last));
status = pthread_mutex_unlock(&crew->mutex); status = pthread_mutex_unlock(&crew->mutex);
if (status != 0) if (status != 0)
@@ -145,10 +152,7 @@ void *worker_routine (void *arg)
status = lstat(work->path, &filestat); status = lstat(work->path, &filestat);
if (S_ISLNK(filestat.st_mode)) if (S_ISLNK(filestat.st_mode))
printf ( printf("Thread %d: %s is a link, skipping.\n", mine->index, work->path);
"Thread %d: %s is a link, skipping.\n",
mine->index,
work->path);
else if (S_ISDIR(filestat.st_mode)) { else if (S_ISDIR(filestat.st_mode)) {
DIR* directory; DIR* directory;
struct dirent* result; struct dirent* result;
@@ -159,21 +163,22 @@ void *worker_routine (void *arg)
*/ */
directory = opendir(work->path); directory = opendir(work->path);
if (directory == NULL) { if (directory == NULL) {
fprintf ( fprintf(stderr,
stderr, "Unable to open directory %s: %d (%s)\n", "Unable to open directory %s: %d (%s)\n",
work->path, work->path,
errno, strerror (errno)); errno,
strerror(errno));
continue; continue;
} }
while (1) { while (1) {
status = readdir_r(directory, entry, &result); status = readdir_r(directory, entry, &result);
if (status != 0) { if (status != 0) {
fprintf ( fprintf(stderr,
stderr,
"Unable to read directory %s: %d (%s)\n", "Unable to read directory %s: %d (%s)\n",
work->path, work->path,
status, strerror (status)); status,
strerror(status));
break; break;
} }
if (result == NULL) if (result == NULL)
@@ -203,15 +208,18 @@ void *worker_routine (void *arg)
if (crew->first == NULL) { if (crew->first == NULL) {
crew->first = new_work; crew->first = new_work;
crew->last = new_work; crew->last = new_work;
} else { }
else {
crew->last->next = new_work; crew->last->next = new_work;
crew->last = new_work; crew->last = new_work;
} }
crew->work_count++; crew->work_count++;
DPRINTF (( DPRINTF(("Crew %d: add work %#lx, first %#lx, last %#lx, %d\n",
"Crew %d: add work %#lx, first %#lx, last %#lx, %d\n", mine->index,
mine->index, new_work, crew->first, new_work,
crew->last, crew->work_count)); crew->first,
crew->last,
crew->work_count));
status = pthread_cond_signal(&crew->go); status = pthread_cond_signal(&crew->go);
status = pthread_mutex_unlock(&crew->mutex); status = pthread_mutex_unlock(&crew->mutex);
if (status != 0) if (status != 0)
@@ -219,7 +227,8 @@ void *worker_routine (void *arg)
} }
closedir(directory); closedir(directory);
} else if (S_ISREG (filestat.st_mode)) { }
else if (S_ISREG(filestat.st_mode)) {
FILE* search; FILE* search;
char buffer[256], *bufptr, *search_ptr; char buffer[256], *bufptr, *search_ptr;
@@ -229,33 +238,33 @@ void *worker_routine (void *arg)
*/ */
search = fopen(work->path, "r"); search = fopen(work->path, "r");
if (search == NULL) if (search == NULL)
fprintf ( fprintf(stderr,
stderr, "Unable to open %s: %d (%s)\n", "Unable to open %s: %d (%s)\n",
work->path, work->path,
errno, strerror (errno)); errno,
strerror(errno));
else { else {
while (1) { while (1) {
bufptr = fgets ( bufptr = fgets(buffer, sizeof(buffer), search);
buffer, sizeof (buffer), search);
if (bufptr == NULL) { if (bufptr == NULL) {
if (feof(search)) if (feof(search))
break; break;
if (ferror(search)) { if (ferror(search)) {
fprintf ( fprintf(stderr,
stderr,
"Unable to read %s: %d (%s)\n", "Unable to read %s: %d (%s)\n",
work->path, work->path,
errno, strerror (errno)); errno,
strerror(errno));
break; break;
} }
} }
search_ptr = strstr(buffer, work->string); search_ptr = strstr(buffer, work->string);
if (search_ptr != NULL) { if (search_ptr != NULL) {
flockfile(stdout); flockfile(stdout);
printf ( printf("Thread %d found \"%s\" in %s\n",
"Thread %d found \"%s\" in %s\n", mine->index,
mine->index, work->string, work->path); work->string,
work->path);
#if 0 #if 0
printf ("%s\n", buffer); printf ("%s\n", buffer);
#endif #endif
@@ -265,16 +274,19 @@ void *worker_routine (void *arg)
} }
fclose(search); fclose(search);
} }
} else }
fprintf ( else
stderr, fprintf(stderr,
"Thread %d: %s is type %o (%s))\n", "Thread %d: %s is type %o (%s))\n",
mine->index, mine->index,
work->path, work->path,
filestat.st_mode & S_IFMT, filestat.st_mode & S_IFMT,
(S_ISFIFO (filestat.st_mode) ? "FIFO" (S_ISFIFO(filestat.st_mode)
: (S_ISCHR (filestat.st_mode) ? "CHR" ? "FIFO"
: (S_ISBLK (filestat.st_mode) ? "BLK" : (S_ISCHR(filestat.st_mode)
? "CHR"
: (S_ISBLK(filestat.st_mode)
? "BLK"
: (S_ISSOCK(filestat.st_mode) ? "SOCK" : (S_ISSOCK(filestat.st_mode) ? "SOCK"
: "unknown"))))); : "unknown")))));
@@ -295,8 +307,8 @@ void *worker_routine (void *arg)
err_abort(status, "Lock crew mutex"); err_abort(status, "Lock crew mutex");
crew->work_count--; crew->work_count--;
DPRINTF (("Crew %d decremented work to %d\n", mine->index, DPRINTF(
crew->work_count)); ("Crew %d decremented work to %d\n", mine->index, crew->work_count));
if (crew->work_count <= 0) { if (crew->work_count <= 0) {
DPRINTF(("Crew thread %d done\n", mine->index)); DPRINTF(("Crew thread %d done\n", mine->index));
status = pthread_cond_broadcast(&crew->done); status = pthread_cond_broadcast(&crew->done);
@@ -311,7 +323,6 @@ void *worker_routine (void *arg)
status = pthread_mutex_unlock(&crew->mutex); status = pthread_mutex_unlock(&crew->mutex);
if (status != 0) if (status != 0)
err_abort(status, "Unlock mutex"); err_abort(status, "Unlock mutex");
} }
free(entry); free(entry);
@@ -321,7 +332,8 @@ void *worker_routine (void *arg)
/* /*
* Create a work crew. * Create a work crew.
*/ */
int crew_create (crew_t *crew, int crew_size) int
crew_create(crew_t* crew, int crew_size)
{ {
int crew_index; int crew_index;
int status; int status;
@@ -357,7 +369,9 @@ int crew_create (crew_t *crew, int crew_size)
crew->crew[crew_index].index = crew_index; crew->crew[crew_index].index = crew_index;
crew->crew[crew_index].crew = crew; crew->crew[crew_index].crew = crew;
status = pthread_create(&crew->crew[crew_index].thread, status = pthread_create(&crew->crew[crew_index].thread,
NULL, worker_routine, (void*)&crew->crew[crew_index]); NULL,
worker_routine,
(void*) &crew->crew[crew_index]);
if (status != 0) if (status != 0)
err_abort(status, "Create worker"); err_abort(status, "Create worker");
} }
@@ -368,10 +382,8 @@ int crew_create (crew_t *crew, int crew_size)
* Pass a file path to a work crew previously created * Pass a file path to a work crew previously created
* using crew_create * using crew_create
*/ */
int crew_start ( int
crew_p crew, crew_start(crew_p crew, char* filepath, char* search)
char *filepath,
char *search)
{ {
work_p request; work_p request;
int status; int status;
@@ -407,9 +419,10 @@ int crew_start (
else else
errno_abort("Unable to get NAME_MAX"); errno_abort("Unable to get NAME_MAX");
} }
DPRINTF (( DPRINTF(("PATH_MAX for %s is %ld, NAME_MAX is %ld\n",
"PATH_MAX for %s is %ld, NAME_MAX is %ld\n", filepath,
filepath, path_max, name_max)); path_max,
name_max));
path_max++; /* Add null byte */ path_max++; /* Add null byte */
name_max++; /* Add null byte */ name_max++; /* Add null byte */
request = (work_p) malloc(sizeof(work_t)); request = (work_p) malloc(sizeof(work_t));
@@ -425,7 +438,8 @@ int crew_start (
if (crew->first == NULL) { if (crew->first == NULL) {
crew->first = request; crew->first = request;
crew->last = request; crew->last = request;
} else { }
else {
crew->last->next = request; crew->last->next = request;
crew->last = request; crew->last = request;
} }
@@ -453,7 +467,8 @@ int crew_start (
/* /*
* The main program to "drive" the crew... * The main program to "drive" the crew...
*/ */
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
crew_t my_crew; crew_t my_crew;
char line[128], *next; char line[128], *next;

View File

@@ -42,7 +42,8 @@ typedef struct pipe_tag {
* specified pipe stage. Threads use this to pass * specified pipe stage. Threads use this to pass
* along the modified data item. * along the modified data item.
*/ */
int pipe_send (stage_t *stage, long data) int
pipe_send(stage_t* stage, long data)
{ {
int status; int status;
@@ -81,7 +82,8 @@ int pipe_send (stage_t *stage, long data)
* caller or the previous stage, modify the data * caller or the previous stage, modify the data
* and pass it along to the next (or final) stage. * and pass it along to the next (or final) stage.
*/ */
void *pipe_stage (void *arg) void*
pipe_stage(void* arg)
{ {
stage_t* stage = (stage_t*) arg; stage_t* stage = (stage_t*) arg;
stage_t* next_stage = stage->next; stage_t* next_stage = stage->next;
@@ -116,7 +118,8 @@ void *pipe_stage (void *arg)
* data is initialized and the threads created. They'll * data is initialized and the threads created. They'll
* wait for data. * wait for data.
*/ */
int pipe_create (pipe_t *pipe, int stages) int
pipe_create(pipe_t* pipe, int stages)
{ {
int pipe_index; int pipe_index;
stage_t **link = &pipe->head, *new_stage, *stage; stage_t **link = &pipe->head, *new_stage, *stage;
@@ -162,11 +165,8 @@ int pipe_create (pipe_t *pipe, int stages)
* memory cleanup done for earlier errors, it will simply * memory cleanup done for earlier errors, it will simply
* abort. * abort.
*/ */
for ( stage = pipe->head; for (stage = pipe->head; stage->next != NULL; stage = stage->next) {
stage->next != NULL; status = pthread_create(&stage->thread, NULL, pipe_stage, (void*) stage);
stage = stage->next) {
status = pthread_create (
&stage->thread, NULL, pipe_stage, (void*)stage);
if (status != 0) if (status != 0)
err_abort(status, "Create pipe stage"); err_abort(status, "Create pipe stage");
} }
@@ -181,7 +181,8 @@ int pipe_create (pipe_t *pipe, int stages)
* (note that the pipe will stall when each stage fills, * (note that the pipe will stall when each stage fills,
* until the result is collected). * until the result is collected).
*/ */
int pipe_start (pipe_t *pipe, long value) int
pipe_start(pipe_t* pipe, long value)
{ {
int status; int status;
@@ -200,7 +201,8 @@ int pipe_start (pipe_t *pipe, long value)
* Collect the result of the pipeline. Wait for a * Collect the result of the pipeline. Wait for a
* result if the pipeline hasn't produced one. * result if the pipeline hasn't produced one.
*/ */
int pipe_result (pipe_t *pipe, long *result) int
pipe_result(pipe_t* pipe, long* result)
{ {
stage_t* tail = pipe->tail; stage_t* tail = pipe->tail;
long value; long value;
@@ -222,8 +224,7 @@ int pipe_result (pipe_t *pipe, long *result)
return 0; return 0;
pthread_mutex_lock(&tail->mutex); pthread_mutex_lock(&tail->mutex);
while (!tail->data_ready) while (!tail->data_ready) pthread_cond_wait(&tail->avail, &tail->mutex);
pthread_cond_wait (&tail->avail, &tail->mutex);
*result = tail->data; *result = tail->data;
tail->data_ready = 0; tail->data_ready = 0;
pthread_cond_signal(&tail->ready); pthread_cond_signal(&tail->ready);
@@ -234,7 +235,8 @@ int pipe_result (pipe_t *pipe, long *result)
/* /*
* The main program to "drive" the pipeline... * The main program to "drive" the pipeline...
*/ */
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pipe_t my_pipe; pipe_t my_pipe;
long value, result; long value, result;
@@ -246,14 +248,17 @@ int main (int argc, char *argv[])
while (1) { while (1) {
printf("Data> "); printf("Data> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (fgets(line, sizeof(line), stdin) == NULL)
if (strlen (line) <= 1) continue; exit(0);
if (strlen(line) <= 1)
continue;
if (strlen(line) <= 2 && line[0] == '=') { if (strlen(line) <= 2 && line[0] == '=') {
if (pipe_result(&my_pipe, &result)) if (pipe_result(&my_pipe, &result))
printf("Result is %ld\n", result); printf("Result is %ld\n", result);
else else
printf("Pipe is empty\n"); printf("Pipe is empty\n");
} else { }
else {
if (sscanf(line, "%ld", &value) < 1) if (sscanf(line, "%ld", &value) < 1)
fprintf(stderr, "Enter an integer value\n"); fprintf(stderr, "Enter an integer value\n");
else else

View File

@@ -50,11 +50,14 @@ using pipe_t = pipe_tag;
* specified pipe stage. Threads use this to pass * specified pipe stage. Threads use this to pass
* along the modified data item. * along the modified data item.
*/ */
int pipe_send(stage_t &stage, long data) { int
pipe_send(stage_t& stage, long data)
{
int status; int status;
status = pthread_mutex_lock(&stage.mutex); status = pthread_mutex_lock(&stage.mutex);
if (status != 0) return status; if (status != 0)
return status;
/* /*
* If there's data in the pipe stage, wait for it * If there's data in the pipe stage, wait for it
@@ -90,18 +93,22 @@ int pipe_send(stage_t &stage, long data) {
* caller or the previous stage, modify the data * caller or the previous stage, modify the data
* and pass it along to the next (or final) stage. * and pass it along to the next (or final) stage.
*/ */
void *pipe_stage(void *arg) { void*
pipe_stage(void* arg)
{
stage_t& stage = *(stage_t*) arg; stage_t& stage = *(stage_t*) arg;
stage_t& nextStage = *stage.next; stage_t& nextStage = *stage.next;
int status; int status;
status = pthread_mutex_lock(&stage.mutex); status = pthread_mutex_lock(&stage.mutex);
if (status != 0) err_abort(status, "Lock pipe stage"); if (status != 0)
err_abort(status, "Lock pipe stage");
while (1) { while (1) {
while (!stage.isDataAvail) { while (!stage.isDataAvail) {
status = pthread_cond_wait(&stage.dataIsAvail, &stage.mutex); status = pthread_cond_wait(&stage.dataIsAvail, &stage.mutex);
if (status != 0) err_abort(status, "Wait for previous stage"); if (status != 0)
err_abort(status, "Wait for previous stage");
} }
pipe_send(nextStage, stage.data + 1); pipe_send(nextStage, stage.data + 1);
@@ -109,7 +116,8 @@ void *pipe_stage(void *arg) {
stage.isDataAvail = false; stage.isDataAvail = false;
status = pthread_cond_signal(&stage.threadIsIdle); status = pthread_cond_signal(&stage.threadIsIdle);
if (status != 0) err_abort(status, "Wake next stage"); if (status != 0)
err_abort(status, "Wake next stage");
} }
/* /*
@@ -126,20 +134,26 @@ void *pipe_stage(void *arg) {
* data is initialized and the threads created. They'll * data is initialized and the threads created. They'll
* wait for data. * wait for data.
*/ */
int pipe_create(pipe_t &pipe, size_t nStages) { int
pipe_create(pipe_t& pipe, size_t nStages)
{
int status = pthread_mutex_init(&pipe.mutex, NULL); int status = pthread_mutex_init(&pipe.mutex, NULL);
if (status != 0) err_abort(status, "Init pipe mutex"); if (status != 0)
err_abort(status, "Init pipe mutex");
pipe.stageList.resize(nStages); pipe.stageList.resize(nStages);
pipe.nActive = 0; pipe.nActive = 0;
for (auto& iStage : pipe.stageList) { for (auto& iStage : pipe.stageList) {
status = pthread_mutex_init(&iStage.mutex, NULL); status = pthread_mutex_init(&iStage.mutex, NULL);
if (status != 0) err_abort(status, "Init stage mutex"); if (status != 0)
err_abort(status, "Init stage mutex");
status = pthread_cond_init(&iStage.dataIsAvail, NULL); status = pthread_cond_init(&iStage.dataIsAvail, NULL);
if (status != 0) err_abort(status, "Init dataIsAvail condition"); if (status != 0)
err_abort(status, "Init dataIsAvail condition");
status = pthread_cond_init(&iStage.threadIsIdle, NULL); status = pthread_cond_init(&iStage.threadIsIdle, NULL);
if (status != 0) err_abort(status, "Init threadIsIdle condition"); if (status != 0)
err_abort(status, "Init threadIsIdle condition");
iStage.isDataAvail = false; iStage.isDataAvail = false;
} }
@@ -162,7 +176,8 @@ int pipe_create(pipe_t &pipe, size_t nStages) {
iit->next = &(*it); iit->next = &(*it);
status = pthread_create(&iit->thread, NULL, pipe_stage, (void*) &*iit); status = pthread_create(&iit->thread, NULL, pipe_stage, (void*) &*iit);
if (status != 0) err_abort(status, "Create pipe stage"); if (status != 0)
err_abort(status, "Create pipe stage");
} }
return 0; return 0;
} }
@@ -171,11 +186,14 @@ int pipe_create(pipe_t &pipe, size_t nStages) {
* Collect the result of the pipeline. Wait for a * Collect the result of the pipeline. Wait for a
* result if the pipeline hasn't produced one. * result if the pipeline hasn't produced one.
*/ */
int pipe_result(pipe_t &pipe) { int
pipe_result(pipe_t& pipe)
{
int status; int status;
status = pthread_mutex_lock(&pipe.mutex); status = pthread_mutex_lock(&pipe.mutex);
if (status != 0) err_abort(status, "Lock pipe mutex"); if (status != 0)
err_abort(status, "Lock pipe mutex");
bool isEmpty = false; bool isEmpty = false;
if (pipe.nActive <= 0) if (pipe.nActive <= 0)
@@ -184,7 +202,8 @@ int pipe_result(pipe_t &pipe) {
pipe.nActive--; pipe.nActive--;
status = pthread_mutex_unlock(&pipe.mutex); status = pthread_mutex_unlock(&pipe.mutex);
if (status != 0) err_abort(status, "Unlock pipe mutex"); if (status != 0)
err_abort(status, "Unlock pipe mutex");
if (isEmpty) { if (isEmpty) {
printf("Pipe is empty\n"); printf("Pipe is empty\n");
@@ -194,7 +213,8 @@ int pipe_result(pipe_t &pipe) {
auto& tail = pipe.stageList.back(); auto& tail = pipe.stageList.back();
status = pthread_mutex_lock(&tail.mutex); status = pthread_mutex_lock(&tail.mutex);
if (status != 0) err_abort(status, "Lock pipe tail mutex"); if (status != 0)
err_abort(status, "Lock pipe tail mutex");
while (!tail.isDataAvail) { while (!tail.isDataAvail) {
pthread_cond_wait(&tail.dataIsAvail, &tail.mutex); pthread_cond_wait(&tail.dataIsAvail, &tail.mutex);
@@ -204,10 +224,12 @@ int pipe_result(pipe_t &pipe) {
tail.isDataAvail = false; tail.isDataAvail = false;
status = pthread_cond_signal(&tail.threadIsIdle); status = pthread_cond_signal(&tail.threadIsIdle);
if (status != 0) err_abort(status, "Signal pipe tail threadIsIdle"); if (status != 0)
err_abort(status, "Signal pipe tail threadIsIdle");
status = pthread_mutex_unlock(&tail.mutex); status = pthread_mutex_unlock(&tail.mutex);
if (status != 0) err_abort(status, "Unlock pipe tail mutex"); if (status != 0)
err_abort(status, "Unlock pipe tail mutex");
printf("Result is %ld\n", result); printf("Result is %ld\n", result);
@@ -222,9 +244,12 @@ int pipe_result(pipe_t &pipe) {
* (note that the pipe will stall when each stage fills, * (note that the pipe will stall when each stage fills,
* until the result is collected). * until the result is collected).
*/ */
void pipe_start(pipe_t &pipe, long value) { void
pipe_start(pipe_t& pipe, long value)
{
int status = pthread_mutex_lock(&pipe.mutex); int status = pthread_mutex_lock(&pipe.mutex);
if (status != 0) err_abort(status, "Lock pipe mutex"); if (status != 0)
err_abort(status, "Lock pipe mutex");
if (pipe.nActive > pipe.stageList.size() - 1) { if (pipe.nActive > pipe.stageList.size() - 1) {
status = pthread_mutex_unlock(&pipe.mutex); status = pthread_mutex_unlock(&pipe.mutex);
@@ -235,7 +260,8 @@ void pipe_start(pipe_t &pipe, long value) {
pipe.nActive++; pipe.nActive++;
status = pthread_mutex_unlock(&pipe.mutex); status = pthread_mutex_unlock(&pipe.mutex);
if (status != 0) err_abort(status, "Unlock pipe mutex"); if (status != 0)
err_abort(status, "Unlock pipe mutex");
pipe_send(pipe.stageList.front(), value); pipe_send(pipe.stageList.front(), value);
} }
@@ -243,7 +269,9 @@ void pipe_start(pipe_t &pipe, long value) {
/* /*
* The main program to "drive" the pipeline... * The main program to "drive" the pipeline...
*/ */
int main(int argc, char *argv[]) { int
main(int argc, char* argv[])
{
pipe_t my_pipe; pipe_t my_pipe;
pipe_create(my_pipe, 2); pipe_create(my_pipe, 2);
@@ -252,12 +280,15 @@ int main(int argc, char *argv[]) {
char line[128]; char line[128];
while (1) { while (1) {
printf("Data> "); printf("Data> ");
if (fgets(line, sizeof(line), stdin) == NULL) exit(0); if (fgets(line, sizeof(line), stdin) == NULL)
exit(0);
printf(line); printf(line);
if (strlen(line) <= 1) continue; if (strlen(line) <= 1)
continue;
if (strlen(line) <= 2 && line[0] == '=') { if (strlen(line) <= 2 && line[0] == '=') {
pipe_result(my_pipe); pipe_result(my_pipe);
} else { }
else {
long value; long value;
if (sscanf(line, "%ld", &value) < 1) if (sscanf(line, "%ld", &value) < 1)
fprintf(stderr, "Enter an integer value\n"); fprintf(stderr, "Enter an integer value\n");

View File

@@ -7,8 +7,8 @@
* to allow interleaved thread execution, since threads are not * to allow interleaved thread execution, since threads are not
* timesliced. * timesliced.
*/ */
#include <pthread.h>
#include <math.h> #include <math.h>
#include <pthread.h>
#include "errors.h" #include "errors.h"
#define CLIENT_THREADS 4 /* Number of clients */ #define CLIENT_THREADS 4 /* Number of clients */
@@ -42,8 +42,7 @@ typedef struct tty_server_tag {
} tty_server_t; } tty_server_t;
tty_server_t tty_server = { tty_server_t tty_server = {
NULL, NULL, 0, NULL, NULL, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
/* /*
* Main program data * Main program data
@@ -62,7 +61,8 @@ pthread_cond_t clients_done = PTHREAD_COND_INITIALIZER;
* responsible for freeing the request. If the request was not * responsible for freeing the request. If the request was not
* synchronous, the server will free the request on completion. * synchronous, the server will free the request on completion.
*/ */
void *tty_server_routine (void *arg) void*
tty_server_routine(void* arg)
{ {
static pthread_mutex_t prompt_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t prompt_mutex = PTHREAD_MUTEX_INITIALIZER;
request_t* request; request_t* request;
@@ -78,8 +78,7 @@ void *tty_server_routine (void *arg)
* Wait for data * Wait for data
*/ */
while (tty_server.first == NULL) { while (tty_server.first == NULL) {
status = pthread_cond_wait ( status = pthread_cond_wait(&tty_server.request, &tty_server.mutex);
&tty_server.request, &tty_server.mutex);
if (status != 0) if (status != 0)
err_abort(status, "Wait for request"); err_abort(status, "Wait for request");
} }
@@ -130,7 +129,8 @@ void *tty_server_routine (void *arg)
status = pthread_mutex_unlock(&tty_server.mutex); status = pthread_mutex_unlock(&tty_server.mutex);
if (status != 0) if (status != 0)
err_abort(status, "Unlock server mutex"); err_abort(status, "Unlock server mutex");
} else }
else
free(request); free(request);
if (operation == REQ_QUIT) if (operation == REQ_QUIT)
break; break;
@@ -141,11 +141,8 @@ void *tty_server_routine (void *arg)
/* /*
* Request an operation * Request an operation
*/ */
void tty_server_request ( void
int operation, tty_server_request(int operation, int sync, const char* prompt, char* string)
int sync,
const char *prompt,
char *string)
{ {
request_t* request; request_t* request;
int status; int status;
@@ -160,13 +157,12 @@ void tty_server_request (
status = pthread_attr_init(&detached_attr); status = pthread_attr_init(&detached_attr);
if (status != 0) if (status != 0)
err_abort(status, "Init attributes object"); err_abort(status, "Init attributes object");
status = pthread_attr_setdetachstate ( status =
&detached_attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&detached_attr, PTHREAD_CREATE_DETACHED);
if (status != 0) if (status != 0)
err_abort(status, "Set detach state"); err_abort(status, "Set detach state");
tty_server.running = 1; tty_server.running = 1;
status = pthread_create (&thread, &detached_attr, status = pthread_create(&thread, &detached_attr, tty_server_routine, NULL);
tty_server_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create server"); err_abort(status, "Create server");
@@ -210,7 +206,8 @@ void tty_server_request (
if (tty_server.first == NULL) { if (tty_server.first == NULL) {
tty_server.first = request; tty_server.first = request;
tty_server.last = request; tty_server.last = request;
} else { }
else {
(tty_server.last)->next = request; (tty_server.last)->next = request;
tty_server.last = request; tty_server.last = request;
} }
@@ -227,8 +224,7 @@ void tty_server_request (
*/ */
if (sync) { if (sync) {
while (!request->done_flag) { while (!request->done_flag) {
status = pthread_cond_wait ( status = pthread_cond_wait(&request->done, &tty_server.mutex);
&request->done, &tty_server.mutex);
if (status != 0) if (status != 0)
err_abort(status, "Wait for sync request"); err_abort(status, "Wait for sync request");
} }
@@ -251,7 +247,8 @@ void tty_server_request (
/* /*
* Client routine -- multiple copies will request server. * Client routine -- multiple copies will request server.
*/ */
void *client_routine (void *arg) void*
client_routine(void* arg)
{ {
int my_number = (int) arg, loops; int my_number = (int) arg, loops;
char prompt[32]; char prompt[32];
@@ -264,8 +261,7 @@ void *client_routine (void *arg)
if (strlen(string) == 0) if (strlen(string) == 0)
break; break;
for (loops = 0; loops < 4; loops++) { for (loops = 0; loops < 4; loops++) {
sprintf ( sprintf(formatted, "(%d#%d) %s", my_number, loops, string);
formatted, "(%d#%d) %s", my_number, loops, string);
tty_server_request(REQ_WRITE, 0, NULL, formatted); tty_server_request(REQ_WRITE, 0, NULL, formatted);
sleep(1); sleep(1);
} }
@@ -285,7 +281,8 @@ void *client_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread; pthread_t thread;
int count; int count;
@@ -306,8 +303,7 @@ int main (int argc, char *argv[])
*/ */
client_threads = CLIENT_THREADS; client_threads = CLIENT_THREADS;
for (count = 0; count < client_threads; count++) { for (count = 0; count < client_threads; count++) {
status = pthread_create (&thread, NULL, status = pthread_create(&thread, NULL, client_routine, (void*) count);
client_routine, (void*)count);
if (status != 0) if (status != 0)
err_abort(status, "Create client thread"); err_abort(status, "Create client thread");
} }

View File

@@ -18,7 +18,8 @@ static int counter;
* when it calls pthread_testcancel, which it does each 1000 * when it calls pthread_testcancel, which it does each 1000
* iterations. * iterations.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
DPRINTF(("thread_routine starting\n")); DPRINTF(("thread_routine starting\n"));
for (counter = 0;; counter++) for (counter = 0;; counter++)
@@ -28,7 +29,8 @@ void *thread_routine (void *arg)
} }
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
void* result; void* result;
@@ -43,8 +45,7 @@ int main (int argc, char *argv[])
DPRINTF(("Setting concurrency level to 2\n")); DPRINTF(("Setting concurrency level to 2\n"));
thr_setconcurrency(2); thr_setconcurrency(2);
#endif #endif
status = pthread_create ( status = pthread_create(&thread_id, NULL, thread_routine, NULL);
&thread_id, NULL, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
sleep(2); sleep(2);

View File

@@ -18,7 +18,8 @@ static int matrixb[SIZE][SIZE];
static int matrixc[SIZE][SIZE]; static int matrixc[SIZE][SIZE];
#ifdef DEBUG #ifdef DEBUG
void print_array (int matrix[SIZE][SIZE]) void
print_array(int matrix[SIZE][SIZE])
{ {
int i, j; int i, j;
int first; int first;
@@ -34,7 +35,6 @@ void print_array (int matrix[SIZE][SIZE])
} }
printf("]\n"); printf("]\n");
} }
} }
#endif #endif
@@ -44,7 +44,8 @@ void print_array (int matrix[SIZE][SIZE])
* is enabled. The loop multiplies the two matrices matrixa * is enabled. The loop multiplies the two matrices matrixa
* and matrixb. * and matrixb.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
int cancel_type, status; int cancel_type, status;
int i, j, k, value = 1; int i, j, k, value = 1;
@@ -62,9 +63,7 @@ void *thread_routine (void *arg)
/* /*
* Compute the matrix product of matrixa and matrixb. * Compute the matrix product of matrixa and matrixb.
*/ */
status = pthread_setcanceltype ( status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &cancel_type);
PTHREAD_CANCEL_ASYNCHRONOUS,
&cancel_type);
if (status != 0) if (status != 0)
err_abort(status, "Set cancel type"); err_abort(status, "Set cancel type");
for (i = 0; i < SIZE; i++) for (i = 0; i < SIZE; i++)
@@ -73,9 +72,7 @@ void *thread_routine (void *arg)
for (k = 0; k < SIZE; k++) for (k = 0; k < SIZE; k++)
matrixc[i][j] += matrixa[i][k] * matrixb[k][j]; matrixc[i][j] += matrixa[i][k] * matrixb[k][j];
} }
status = pthread_setcanceltype ( status = pthread_setcanceltype(cancel_type, &cancel_type);
cancel_type,
&cancel_type);
if (status != 0) if (status != 0)
err_abort(status, "Set cancel type"); err_abort(status, "Set cancel type");
@@ -83,12 +80,12 @@ void *thread_routine (void *arg)
* Copy the result (matrixc) into matrixa to start again * Copy the result (matrixc) into matrixa to start again
*/ */
for (i = 0; i < SIZE; i++) for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++) for (j = 0; j < SIZE; j++) matrixa[i][j] = matrixc[i][j];
matrixa[i][j] = matrixc[i][j];
} }
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
void* result; void* result;
@@ -103,8 +100,7 @@ int main (int argc, char *argv[])
DPRINTF(("Setting concurrency level to 2\n")); DPRINTF(("Setting concurrency level to 2\n"));
thr_setconcurrency(2); thr_setconcurrency(2);
#endif #endif
status = pthread_create ( status = pthread_create(&thread_id, NULL, thread_routine, NULL);
&thread_id, NULL, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
sleep(1); sleep(1);

View File

@@ -19,15 +19,15 @@ typedef struct control_tag {
pthread_cond_t cv; pthread_cond_t cv;
} control_t; } control_t;
control_t control = control_t control = {0, 1, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
{0, 1, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
/* /*
* This routine is installed as the cancellation cleanup * This routine is installed as the cancellation cleanup
* handler around the cancellable condition wait. It will * handler around the cancellable condition wait. It will
* be called by the system when the thread is cancelled. * be called by the system when the thread is cancelled.
*/ */
void cleanup_handler (void *arg) void
cleanup_handler(void* arg)
{ {
control_t* st = (control_t*) arg; control_t* st = (control_t*) arg;
int status; int status;
@@ -46,7 +46,8 @@ void cleanup_handler (void *arg)
* nonzero value to pthread_cleanup_pop to run the same * nonzero value to pthread_cleanup_pop to run the same
* "finalization" action when cancellation does not occur. * "finalization" action when cancellation does not occur.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
int status; int status;
@@ -67,7 +68,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id[THREADS]; pthread_t thread_id[THREADS];
int count; int count;
@@ -75,8 +77,7 @@ int main (int argc, char *argv[])
int status; int status;
for (count = 0; count < THREADS; count++) { for (count = 0; count < THREADS; count++) {
status = pthread_create ( status = pthread_create(&thread_id[count], NULL, thread_routine, NULL);
&thread_id[count], NULL, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }

View File

@@ -12,13 +12,13 @@ static int counter;
/* /*
* Thread start routine. * Thread start routine.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
int state; int state;
int status; int status;
for (counter = 0;; counter++) { for (counter = 0;; counter++) {
/* /*
* Each 755 iterations, disable cancellation and sleep * Each 755 iterations, disable cancellation and sleep
* for one second. * for one second.
@@ -27,29 +27,27 @@ void *thread_routine (void *arg)
* calling pthread_testcancel(). * calling pthread_testcancel().
*/ */
if ((counter % 755) == 0) { if ((counter % 755) == 0) {
status = pthread_setcancelstate ( status = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
PTHREAD_CANCEL_DISABLE, &state);
if (status != 0) if (status != 0)
err_abort(status, "Disable cancel"); err_abort(status, "Disable cancel");
sleep(1); sleep(1);
status = pthread_setcancelstate ( status = pthread_setcancelstate(state, &state);
state, &state);
if (status != 0) if (status != 0)
err_abort(status, "Restore cancel"); err_abort(status, "Restore cancel");
} else }
if ((counter % 1000) == 0) else if ((counter % 1000) == 0)
pthread_testcancel(); pthread_testcancel();
} }
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
void* result; void* result;
int status; int status;
status = pthread_create ( status = pthread_create(&thread_id, NULL, thread_routine, NULL);
&thread_id, NULL, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
sleep(2); sleep(2);

View File

@@ -26,7 +26,8 @@ typedef struct team_tag {
* Start routine for worker threads. They loop waiting for a * Start routine for worker threads. They loop waiting for a
* cancellation request. * cancellation request.
*/ */
void *worker_routine (void *arg) void*
worker_routine(void* arg)
{ {
int counter; int counter;
@@ -39,7 +40,8 @@ void *worker_routine (void *arg)
* Cancellation cleanup handler for the contractor thread. It * Cancellation cleanup handler for the contractor thread. It
* will cancel and detach each worker in the team. * will cancel and detach each worker in the team.
*/ */
void cleanup (void *arg) void
cleanup(void* arg)
{ {
team_t* team = (team_t*) arg; team_t* team = (team_t*) arg;
int count, status; int count, status;
@@ -61,7 +63,8 @@ void cleanup (void *arg)
* worker threads, and then joins with them. When cancelled, the * worker threads, and then joins with them. When cancelled, the
* cleanup handler will cancel and detach the remaining threads. * cleanup handler will cancel and detach the remaining threads.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
team_t team; /* team info */ team_t team; /* team info */
int count; int count;
@@ -69,8 +72,7 @@ void *thread_routine (void *arg)
int status; int status;
for (count = 0; count < THREADS; count++) { for (count = 0; count < THREADS; count++) {
status = pthread_create ( status = pthread_create(&team.workers[count], NULL, worker_routine, NULL);
&team.workers[count], NULL, worker_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create worker"); err_abort(status, "Create worker");
} }
@@ -86,7 +88,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
int status; int status;

View File

@@ -13,7 +13,8 @@
pthread_cond_t cond; pthread_cond_t cond;
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_condattr_t cond_attr; pthread_condattr_t cond_attr;
int status; int status;
@@ -22,8 +23,7 @@ int main (int argc, char *argv[])
if (status != 0) if (status != 0)
err_abort(status, "Create attr"); err_abort(status, "Create attr");
#ifdef _POSIX_THREAD_PROCESS_SHARED #ifdef _POSIX_THREAD_PROCESS_SHARED
status = pthread_condattr_setpshared ( status = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_PRIVATE);
&cond_attr, PTHREAD_PROCESS_PRIVATE);
if (status != 0) if (status != 0)
err_abort(status, "Set pshared"); err_abort(status, "Set pshared");
#endif #endif

View File

@@ -14,7 +14,8 @@
pthread_mutex_t mutex; pthread_mutex_t mutex;
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_mutexattr_t mutex_attr; pthread_mutexattr_t mutex_attr;
int status; int status;
@@ -23,8 +24,7 @@ int main (int argc, char *argv[])
if (status != 0) if (status != 0)
err_abort(status, "Create attr"); err_abort(status, "Create attr");
#ifdef _POSIX_THREAD_PROCESS_SHARED #ifdef _POSIX_THREAD_PROCESS_SHARED
status = pthread_mutexattr_setpshared ( status = pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_PRIVATE);
&mutex_attr, PTHREAD_PROCESS_PRIVATE);
if (status != 0) if (status != 0)
err_abort(status, "Set pshared"); err_abort(status, "Set pshared");
#endif #endif

View File

@@ -16,7 +16,8 @@ pthread_mutex_t mutex;
* with the same control structure are made during the course of * with the same control structure are made during the course of
* the program. * the program.
*/ */
void once_init_routine (void) void
once_init_routine(void)
{ {
int status; int status;
@@ -28,7 +29,8 @@ void once_init_routine (void)
/* /*
* Thread start routine that calls pthread_once. * Thread start routine that calls pthread_once.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
int status; int status;
@@ -45,7 +47,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
char *input, buffer[64]; char *input, buffer[64];

View File

@@ -9,16 +9,17 @@
* _POSIX_THREAD_PRIORITY_SCHEDULING, it does not support the * _POSIX_THREAD_PRIORITY_SCHEDULING, it does not support the
* SCHED_RR policy for threads. * SCHED_RR policy for threads.
*/ */
#include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#include <unistd.h>
#include "errors.h" #include "errors.h"
/* /*
* Thread start routine. If priority scheduling is supported, * Thread start routine. If priority scheduling is supported,
* report the thread's scheduling attributes. * report the thread's scheduling attributes.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
int my_policy; int my_policy;
struct sched_param my_param; struct sched_param my_param;
@@ -30,15 +31,15 @@ void *thread_routine (void *arg)
* so just report that the thread ran, and exit. * so just report that the thread ran, and exit.
*/ */
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined(sun) #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined(sun)
status = pthread_getschedparam ( status = pthread_getschedparam(pthread_self(), &my_policy, &my_param);
pthread_self (), &my_policy, &my_param);
if (status != 0) if (status != 0)
err_abort(status, "Get sched"); err_abort(status, "Get sched");
printf("thread_routine running at %s/%d\n", printf("thread_routine running at %s/%d\n",
(my_policy == SCHED_FIFO ? "FIFO" (my_policy == SCHED_FIFO
: (my_policy == SCHED_RR ? "RR" ? "FIFO"
: (my_policy == SCHED_OTHER ? "OTHER" : (my_policy == SCHED_RR
: "unknown"))), ? "RR"
: (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))),
my_param.sched_priority); my_param.sched_priority);
#else #else
printf("thread_routine running\n"); printf("thread_routine running\n");
@@ -46,7 +47,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
pthread_attr_t thread_attr; pthread_attr_t thread_attr;
@@ -67,24 +69,21 @@ int main (int argc, char *argv[])
* thread. * thread.
*/ */
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined(sun) #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined(sun)
status = pthread_attr_getschedpolicy ( status = pthread_attr_getschedpolicy(&thread_attr, &thread_policy);
&thread_attr, &thread_policy);
if (status != 0) if (status != 0)
err_abort(status, "Get policy"); err_abort(status, "Get policy");
status = pthread_attr_getschedparam ( status = pthread_attr_getschedparam(&thread_attr, &thread_param);
&thread_attr, &thread_param);
if (status != 0) if (status != 0)
err_abort(status, "Get sched param"); err_abort(status, "Get sched param");
printf ( printf("Default policy is %s, priority is %d\n",
"Default policy is %s, priority is %d\n", (thread_policy == SCHED_FIFO
(thread_policy == SCHED_FIFO ? "FIFO" ? "FIFO"
: (thread_policy == SCHED_RR ? "RR" : (thread_policy == SCHED_RR
: (thread_policy == SCHED_OTHER ? "OTHER" ? "RR"
: "unknown"))), : (thread_policy == SCHED_OTHER ? "OTHER" : "unknown"))),
thread_param.sched_priority); thread_param.sched_priority);
status = pthread_attr_setschedpolicy ( status = pthread_attr_setschedpolicy(&thread_attr, SCHED_RR);
&thread_attr, SCHED_RR);
if (status != 0) if (status != 0)
printf("Unable to set SCHED_RR policy.\n"); printf("Unable to set SCHED_RR policy.\n");
else { else {
@@ -105,30 +104,23 @@ int main (int argc, char *argv[])
rr_max_priority = sched_get_priority_max(SCHED_RR); rr_max_priority = sched_get_priority_max(SCHED_RR);
if (rr_max_priority == -1) if (rr_max_priority == -1)
errno_abort("Get SCHED_RR max priority"); errno_abort("Get SCHED_RR max priority");
thread_param.sched_priority = thread_param.sched_priority = (rr_min_priority + rr_max_priority) / 2;
(rr_min_priority + rr_max_priority)/2; printf("SCHED_RR priority range is %d to %d: using %d\n",
printf (
"SCHED_RR priority range is %d to %d: using %d\n",
rr_min_priority, rr_min_priority,
rr_max_priority, rr_max_priority,
thread_param.sched_priority); thread_param.sched_priority);
status = pthread_attr_setschedparam ( status = pthread_attr_setschedparam(&thread_attr, &thread_param);
&thread_attr, &thread_param);
if (status != 0) if (status != 0)
err_abort(status, "Set params"); err_abort(status, "Set params");
printf ( printf("Creating thread at RR/%d\n", thread_param.sched_priority);
"Creating thread at RR/%d\n", status = pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED);
thread_param.sched_priority);
status = pthread_attr_setinheritsched (
&thread_attr, PTHREAD_EXPLICIT_SCHED);
if (status != 0) if (status != 0)
err_abort(status, "Set inherit"); err_abort(status, "Set inherit");
} }
#else #else
printf("Priority scheduling not supported\n"); printf("Priority scheduling not supported\n");
#endif #endif
status = pthread_create ( status = pthread_create(&thread_id, &thread_attr, thread_routine, NULL);
&thread_id, &thread_attr, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
status = pthread_join(thread_id, NULL); status = pthread_join(thread_id, NULL);

View File

@@ -6,9 +6,9 @@
* Special note: This demonstration will fail on Solaris 2.5 * Special note: This demonstration will fail on Solaris 2.5
* because it does not implement SCHED_RR. * because it does not implement SCHED_RR.
*/ */
#include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#include <unistd.h>
#include "errors.h" #include "errors.h"
#define THREADS 5 #define THREADS 5
@@ -27,7 +27,8 @@ int rr_min_priority;
/* /*
* Thread start routine that will set its own priority * Thread start routine that will set its own priority
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
thread_t* self = (thread_t*) arg; thread_t* self = (thread_t*) arg;
int my_policy; int my_policy;
@@ -35,28 +36,28 @@ void *thread_routine (void *arg)
int status; int status;
my_param.sched_priority = rr_min_priority + self->index; my_param.sched_priority = rr_min_priority + self->index;
DPRINTF (( DPRINTF(("Thread %d will set SCHED_FIFO, priority %d\n",
"Thread %d will set SCHED_FIFO, priority %d\n", self->index,
self->index, my_param.sched_priority)); my_param.sched_priority));
status = pthread_setschedparam ( status = pthread_setschedparam(self->id, SCHED_RR, &my_param);
self->id, SCHED_RR, &my_param);
if (status != 0) if (status != 0)
err_abort(status, "Set sched"); err_abort(status, "Set sched");
status = pthread_getschedparam ( status = pthread_getschedparam(self->id, &my_policy, &my_param);
self->id, &my_policy, &my_param);
if (status != 0) if (status != 0)
err_abort(status, "Get sched"); err_abort(status, "Get sched");
printf("thread_routine %d running at %s/%d\n", printf("thread_routine %d running at %s/%d\n",
self->index, self->index,
(my_policy == SCHED_FIFO ? "FIFO" (my_policy == SCHED_FIFO
: (my_policy == SCHED_RR ? "RR" ? "FIFO"
: (my_policy == SCHED_OTHER ? "OTHER" : (my_policy == SCHED_RR
: "unknown"))), ? "RR"
: (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))),
my_param.sched_priority); my_param.sched_priority);
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int count, status; int count, status;
@@ -73,8 +74,7 @@ int main (int argc, char *argv[])
for (count = 0; count < THREADS; count++) { for (count = 0; count < THREADS; count++) {
threads[count].index = count; threads[count].index = count;
status = pthread_create( status = pthread_create(
&threads[count].id, NULL, &threads[count].id, NULL, thread_routine, (void*) &threads[count]);
thread_routine, (void*)&threads[count]);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }

View File

@@ -14,13 +14,15 @@
/* /*
* Thread start routine that reports it ran, and then exits. * Thread start routine that reports it ran, and then exits.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
printf("The thread is here\n"); printf("The thread is here\n");
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
pthread_attr_t thread_attr; pthread_attr_t thread_attr;
@@ -35,8 +37,7 @@ int main (int argc, char *argv[])
/* /*
* Create a detached thread. * Create a detached thread.
*/ */
status = pthread_attr_setdetachstate ( status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
&thread_attr, PTHREAD_CREATE_DETACHED);
if (status != 0) if (status != 0)
err_abort(status, "Set detach"); err_abort(status, "Set detach");
#ifdef _POSIX_THREAD_ATTR_STACKSIZE #ifdef _POSIX_THREAD_ATTR_STACKSIZE
@@ -53,14 +54,13 @@ int main (int argc, char *argv[])
if (status != 0) if (status != 0)
err_abort(status, "Get stack size"); err_abort(status, "Get stack size");
printf("Default stack size is %u; minimum is %u\n", printf("Default stack size is %u; minimum is %u\n",
stack_size, PTHREAD_STACK_MIN); stack_size,
status = pthread_attr_setstacksize ( PTHREAD_STACK_MIN);
&thread_attr, PTHREAD_STACK_MIN*2); status = pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN * 2);
if (status != 0) if (status != 0)
err_abort(status, "Set stack size"); err_abort(status, "Set stack size");
#endif #endif
status = pthread_create ( status = pthread_create(&thread_id, &thread_attr, thread_routine, NULL);
&thread_id, &thread_attr, thread_routine, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
printf("Main exiting\n"); printf("Main exiting\n");

View File

@@ -24,7 +24,8 @@ long identity_key_counter = 0;
* threads still have values, and deletes the key when there are * threads still have values, and deletes the key when there are
* no more references. * no more references.
*/ */
void identity_key_destructor (void *value) void
identity_key_destructor(void* value)
{ {
private_t* private = (private_t*) value; private_t* private = (private_t*) value;
int status; int status;
@@ -50,7 +51,8 @@ void identity_key_destructor (void *value)
* Helper routine to allocate a new value for thread-specific * Helper routine to allocate a new value for thread-specific
* data key if the thread doesn't already have one. * data key if the thread doesn't already have one.
*/ */
void *identity_key_get (void) void*
identity_key_get(void)
{ {
void* value; void* value;
int status; int status;
@@ -70,7 +72,8 @@ void *identity_key_get (void)
/* /*
* Thread start routine to use thread-specific data. * Thread start routine to use thread-specific data.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
private_t* value; private_t* value;
@@ -82,7 +85,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
void main (int argc, char *argv[]) void
main(int argc, char* argv[])
{ {
pthread_t thread_1, thread_2; pthread_t thread_1, thread_2;
private_t* value; private_t* value;
@@ -106,12 +110,10 @@ void main (int argc, char *argv[])
value = (private_t*) identity_key_get(); value = (private_t*) identity_key_get();
value->thread_id = pthread_self(); value->thread_id = pthread_self();
value->string = "Main thread"; value->string = "Main thread";
status = pthread_create (&thread_1, NULL, status = pthread_create(&thread_1, NULL, thread_routine, "Thread 1");
thread_routine, "Thread 1");
if (status != 0) if (status != 0)
err_abort(status, "Create thread 1"); err_abort(status, "Create thread 1");
status = pthread_create (&thread_2, NULL, status = pthread_create(&thread_2, NULL, thread_routine, "Thread 2");
thread_routine, "Thread 2");
if (status != 0) if (status != 0)
err_abort(status, "Create thread 2"); err_abort(status, "Create thread 2");
pthread_exit(NULL); pthread_exit(NULL);

View File

@@ -25,7 +25,8 @@ pthread_once_t key_once = PTHREAD_ONCE_INIT;
* One-time initialization routine used with the pthread_once * One-time initialization routine used with the pthread_once
* control block. * control block.
*/ */
void once_routine (void) void
once_routine(void)
{ {
int status; int status;
@@ -39,7 +40,8 @@ void once_routine (void)
* Thread start routine that uses pthread_once to dynamically * Thread start routine that uses pthread_once to dynamically
* create a thread-specific data key. * create a thread-specific data key.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
tsd_t* value; tsd_t* value;
int status; int status;
@@ -64,17 +66,16 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
void main (int argc, char *argv[]) void
main(int argc, char* argv[])
{ {
pthread_t thread1, thread2; pthread_t thread1, thread2;
int status; int status;
status = pthread_create ( status = pthread_create(&thread1, NULL, thread_routine, "thread 1");
&thread1, NULL, thread_routine, "thread 1");
if (status != 0) if (status != 0)
err_abort(status, "Create thread 1"); err_abort(status, "Create thread 1");
status = pthread_create ( status = pthread_create(&thread2, NULL, thread_routine, "thread 2");
&thread2, NULL, thread_routine, "thread 2");
if (status != 0) if (status != 0)
err_abort(status, "Create thread 2"); err_abort(status, "Create thread 2");
pthread_exit(NULL); pthread_exit(NULL);

View File

@@ -4,8 +4,8 @@
* Demonstrate the use of "fork handlers" to protect data * Demonstrate the use of "fork handlers" to protect data
* invariants across a fork. * invariants across a fork.
*/ */
#include <sys/types.h>
#include <pthread.h> #include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "errors.h" #include "errors.h"
@@ -16,7 +16,8 @@ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
* This routine will be called prior to executing the fork, * This routine will be called prior to executing the fork,
* within the parent process. * within the parent process.
*/ */
void fork_prepare (void) void
fork_prepare(void)
{ {
int status; int status;
@@ -34,7 +35,8 @@ void fork_prepare (void)
* This routine will be called after executing the fork, within * This routine will be called after executing the fork, within
* the parent process * the parent process
*/ */
void fork_parent (void) void
fork_parent(void)
{ {
int status; int status;
@@ -50,7 +52,8 @@ void fork_parent (void)
* This routine will be called after executing the fork, within * This routine will be called after executing the fork, within
* the child process * the child process
*/ */
void fork_child (void) void
fork_child(void)
{ {
int status; int status;
@@ -67,7 +70,8 @@ void fork_child (void)
/* /*
* Thread start routine, which will fork a new child process. * Thread start routine, which will fork a new child process.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
pid_t child_pid; pid_t child_pid;
int status; int status;
@@ -95,7 +99,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t fork_thread; pthread_t fork_thread;
int atfork_flag = 1; int atfork_flag = 1;

View File

@@ -14,7 +14,8 @@
* is prevented by the file locks until both prompt and fgets are * is prevented by the file locks until both prompt and fgets are
* complete. * complete.
*/ */
void *prompt_routine (void *arg) void*
prompt_routine(void* arg)
{ {
char* prompt = (char*) arg; char* prompt = (char*) arg;
char* string; char* string;
@@ -38,7 +39,8 @@ void *prompt_routine (void *arg)
return (void*) string; return (void*) string;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread1, thread2, thread3; pthread_t thread1, thread2, thread3;
char* string; char* string;
@@ -53,16 +55,13 @@ int main (int argc, char *argv[])
DPRINTF(("Setting concurrency level to 4\n")); DPRINTF(("Setting concurrency level to 4\n"));
thr_setconcurrency(4); thr_setconcurrency(4);
#endif #endif
status = pthread_create ( status = pthread_create(&thread1, NULL, prompt_routine, "Thread 1> ");
&thread1, NULL, prompt_routine, "Thread 1> ");
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
status = pthread_create ( status = pthread_create(&thread2, NULL, prompt_routine, "Thread 2> ");
&thread2, NULL, prompt_routine, "Thread 2> ");
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
status = pthread_create ( status = pthread_create(&thread3, NULL, prompt_routine, "Thread 3> ");
&thread3, NULL, prompt_routine, "Thread 3> ");
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
status = pthread_join(thread1, (void**) &string); status = pthread_join(thread1, (void**) &string);

View File

@@ -20,7 +20,8 @@
#define LOGIN_NAME_MAX 32 #define LOGIN_NAME_MAX 32
#endif #endif
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
char login_str[LOGIN_NAME_MAX]; char login_str[LOGIN_NAME_MAX];
char stdin_str[TTY_NAME_MAX]; char stdin_str[TTY_NAME_MAX];
@@ -36,7 +37,6 @@ int main (int argc, char *argv[])
status = ttyname_r(0, stdin_str, sizeof(stdin_str)); status = ttyname_r(0, stdin_str, sizeof(stdin_str));
if (status != 0) if (status != 0)
err_abort(status, "Get stdin"); err_abort(status, "Get stdin");
printf ("User: %s, cterm: %s, fd 0: %s\n", printf("User: %s, cterm: %s, fd 0: %s\n", login_str, cterm_str, stdin_str);
login_str, cterm_str, stdin_str);
return 0; return 0;
} }

View File

@@ -37,7 +37,8 @@
* by locking the file stream and using putchar_unlocked to * by locking the file stream and using putchar_unlocked to
* write each character individually. * write each character individually.
*/ */
void *lock_routine (void *arg) void*
lock_routine(void* arg)
{ {
char* pointer; char* pointer;
@@ -56,7 +57,8 @@ void *lock_routine (void *arg)
* Although the internal locking of putchar prevents file stream * Although the internal locking of putchar prevents file stream
* corruption, the writes of various threads may be interleaved. * corruption, the writes of various threads may be interleaved.
*/ */
void *unlock_routine (void *arg) void*
unlock_routine(void* arg)
{ {
char* pointer; char* pointer;
@@ -67,7 +69,8 @@ void *unlock_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread1, thread2, thread3; pthread_t thread1, thread2, thread3;
int flock_flag = 1; int flock_flag = 1;
@@ -80,16 +83,13 @@ int main (int argc, char *argv[])
thread_func = lock_routine; thread_func = lock_routine;
else else
thread_func = unlock_routine; thread_func = unlock_routine;
status = pthread_create ( status = pthread_create(&thread1, NULL, thread_func, "this is thread 1\n");
&thread1, NULL, thread_func, "this is thread 1\n");
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
status = pthread_create ( status = pthread_create(&thread2, NULL, thread_func, "this is thread 2\n");
&thread2, NULL, thread_func, "this is thread 2\n");
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
status = pthread_create ( status = pthread_create(&thread3, NULL, thread_func, "this is thread 3\n");
&thread3, NULL, thread_func, "this is thread 3\n");
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
pthread_exit(NULL); pthread_exit(NULL);

View File

@@ -8,12 +8,12 @@
* and _POSIX_SEMAPHORES features of POSIX 1003.1b-1993. It will * and _POSIX_SEMAPHORES features of POSIX 1003.1b-1993. It will
* not run (and may not compile) without them. * not run (and may not compile) without them.
*/ */
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <signal.h> #include <signal.h>
#include <sys/types.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "errors.h" #include "errors.h"
sem_t semaphore; sem_t semaphore;
@@ -21,7 +21,8 @@ sem_t semaphore;
/* /*
* Signal catching function. * Signal catching function.
*/ */
void signal_catcher (int sig) void
signal_catcher(int sig)
{ {
if (sem_post(&semaphore) == -1) if (sem_post(&semaphore) == -1)
errno_abort("Post semaphore"); errno_abort("Post semaphore");
@@ -30,7 +31,8 @@ void signal_catcher (int sig)
/* /*
* Thread start routine which waits on the semaphore. * Thread start routine which waits on the semaphore.
*/ */
void *sem_waiter (void *arg) void*
sem_waiter(void* arg)
{ {
int number = (int) arg; int number = (int) arg;
int counter; int counter;
@@ -48,7 +50,8 @@ void *sem_waiter (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int thread_count, status; int thread_count, status;
struct sigevent sig_event; struct sigevent sig_event;
@@ -74,8 +77,7 @@ int main (int argc, char *argv[])
*/ */
for (thread_count = 0; thread_count < 5; thread_count++) { for (thread_count = 0; thread_count < 5; thread_count++) {
status = pthread_create( status = pthread_create(
&sem_waiters[thread_count], NULL, &sem_waiters[thread_count], NULL, sem_waiter, (void*) thread_count);
sem_waiter, (void*)thread_count);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }

View File

@@ -3,11 +3,11 @@
* *
* Demonstrate use of semaphores for synchronization. * Demonstrate use of semaphores for synchronization.
*/ */
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <signal.h> #include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include "errors.h" #include "errors.h"
sem_t semaphore; sem_t semaphore;
@@ -15,7 +15,8 @@ sem_t semaphore;
/* /*
* Thread start routine to wait on a semaphore. * Thread start routine to wait on a semaphore.
*/ */
void *sem_waiter (void *arg) void*
sem_waiter(void* arg)
{ {
long num = (long) arg; long num = (long) arg;
@@ -26,7 +27,8 @@ void *sem_waiter (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int thread_count; int thread_count;
pthread_t sem_waiters[5]; pthread_t sem_waiters[5];
@@ -45,8 +47,7 @@ int main (int argc, char *argv[])
*/ */
for (thread_count = 0; thread_count < 5; thread_count++) { for (thread_count = 0; thread_count < 5; thread_count++) {
status = pthread_create( status = pthread_create(
&sem_waiters[thread_count], NULL, &sem_waiters[thread_count], NULL, sem_waiter, (void*) thread_count);
sem_waiter, (void*)thread_count);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }

View File

@@ -55,8 +55,7 @@ main()
struct sigevent se; struct sigevent se;
#ifdef sun #ifdef sun
fprintf ( fprintf(stderr,
stderr,
"This program cannot compile on Solaris 2.5.\n" "This program cannot compile on Solaris 2.5.\n"
"To build and run on Solaris 2.6, remove the\n" "To build and run on Solaris 2.6, remove the\n"
"\"#ifdef sun\" block in main().\n"); "\"#ifdef sun\" block in main().\n");
@@ -83,8 +82,7 @@ main()
if (status == -1) if (status == -1)
errno_abort("Create timer"); errno_abort("Create timer");
DPRINTF (( DPRINTF(("Setting timer %d for 5-second expiration...\n", timer_id));
"Setting timer %d for 5-second expiration...\n", timer_id));
status = timer_settime(timer_id, 0, &ts, 0); status = timer_settime(timer_id, 0, &ts, 0);
if (status == -1) if (status == -1)
errno_abort("Set timer"); errno_abort("Set timer");

View File

@@ -4,10 +4,10 @@
* Demonstrate use of sigwait() to synchronously handle * Demonstrate use of sigwait() to synchronously handle
* asynchrnous signals within a threaded program. * asynchrnous signals within a threaded program.
*/ */
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include "errors.h" #include "errors.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -20,7 +20,8 @@ sigset_t signal_set;
* the "interrupted" flag (the main thread's wait predicate) and * the "interrupted" flag (the main thread's wait predicate) and
* signal a condition variable. The main thread will exit. * signal a condition variable. The main thread will exit.
*/ */
void *signal_waiter (void *arg) void*
signal_waiter(void* arg)
{ {
int sig_number; int sig_number;
int signal_count = 0; int signal_count = 0;
@@ -48,7 +49,8 @@ void *signal_waiter (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t signal_thread_id; pthread_t signal_thread_id;
int status; int status;
@@ -73,8 +75,7 @@ int main (int argc, char *argv[])
/* /*
* Create the sigwait thread. * Create the sigwait thread.
*/ */
status = pthread_create (&signal_thread_id, NULL, status = pthread_create(&signal_thread_id, NULL, signal_waiter, NULL);
signal_waiter, NULL);
if (status != 0) if (status != 0)
err_abort(status, "Create sigwaiter"); err_abort(status, "Create sigwaiter");

View File

@@ -161,12 +161,10 @@ thd_suspend (pthread_t target_thread)
* the end, realloc the array for more space. * the end, realloc the array for more space.
*/ */
i = 0; i = 0;
while (array[i] != 0) while (array[i] != 0) i++;
i++;
if (i == bottom) { if (i == bottom) {
array = (pthread_t*) realloc ( array = (pthread_t*) realloc(array, (++bottom * sizeof(pthread_t)));
array, (++bottom * sizeof (pthread_t)));
if (array == NULL) { if (array == NULL) {
pthread_mutex_unlock(&mut); pthread_mutex_unlock(&mut);
return errno; return errno;
@@ -188,8 +186,7 @@ thd_suspend (pthread_t target_thread)
/* /*
* Wait for the sentinel to change. * Wait for the sentinel to change.
*/ */
while (sentinel == 0) while (sentinel == 0) sched_yield();
sched_yield ();
array[i] = target_thread; array[i] = target_thread;
@@ -229,8 +226,7 @@ thd_continue (pthread_t target_thread)
* hasn't been suspended (or it has already been resumed) and * hasn't been suspended (or it has already been resumed) and
* we can just carry on. * we can just carry on.
*/ */
while (array[i] != target_thread && i < bottom) while (array[i] != target_thread && i < bottom) i++;
i++;
if (i >= bottom) { if (i >= bottom) {
pthread_mutex_unlock(&mut); pthread_mutex_unlock(&mut);
@@ -266,9 +262,7 @@ thread_routine (void *arg)
* a progress report. * a progress report.
*/ */
if (i % 2000 == 0) { if (i % 2000 == 0) {
sprintf ( sprintf(buffer, "Thread %02d: %d\n", number, i);
buffer, "Thread %02d: %d\n",
number, i);
write(1, buffer, strlen(buffer)); write(1, buffer, strlen(buffer));
} }
@@ -290,14 +284,12 @@ main (int argc, char *argv[])
status = pthread_attr_init(&detach); status = pthread_attr_init(&detach);
if (status != 0) if (status != 0)
err_abort(status, "Init attributes object"); err_abort(status, "Init attributes object");
status = pthread_attr_setdetachstate ( status = pthread_attr_setdetachstate(&detach, PTHREAD_CREATE_DETACHED);
&detach, PTHREAD_CREATE_DETACHED);
if (status != 0) if (status != 0)
err_abort(status, "Set create-detached"); err_abort(status, "Set create-detached");
for (i = 0; i < THREAD_COUNT; i++) { for (i = 0; i < THREAD_COUNT; i++) {
status = pthread_create ( status = pthread_create(&threads[i], &detach, thread_routine, (void*) i);
&threads[i], &detach, thread_routine, (void *)i);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }

View File

@@ -20,14 +20,15 @@
* to do something in a serial region before entering another * to do something in a serial region before entering another
* parallel section of code. * parallel section of code.
*/ */
#include "barrier.h"
#include <pthread.h> #include <pthread.h>
#include "errors.h" #include "errors.h"
#include "barrier.h"
/* /*
* Initialize a barrier for use. * Initialize a barrier for use.
*/ */
int barrier_init (barrier_t *barrier, int count) int
barrier_init(barrier_t* barrier, int count)
{ {
int status; int status;
@@ -48,7 +49,8 @@ int barrier_init (barrier_t *barrier, int count)
/* /*
* Destroy a barrier when done using it. * Destroy a barrier when done using it.
*/ */
int barrier_destroy (barrier_t *barrier) int
barrier_destroy(barrier_t* barrier)
{ {
int status, status2; int status, status2;
@@ -87,7 +89,8 @@ int barrier_destroy (barrier_t *barrier)
* the count (of remaining members) reaches 0, broadcast to wake * the count (of remaining members) reaches 0, broadcast to wake
* all threads waiting. * all threads waiting.
*/ */
int barrier_wait (barrier_t *barrier) int
barrier_wait(barrier_t* barrier)
{ {
int status, cancel, tmp, cycle; int status, cancel, tmp, cycle;
@@ -111,7 +114,8 @@ int barrier_wait (barrier_t *barrier)
*/ */
if (status == 0) if (status == 0)
status = -1; status = -1;
} else { }
else {
/* /*
* Wait with cancellation disabled, because barrier_wait * Wait with cancellation disabled, because barrier_wait
* should not be a cancellation point. * should not be a cancellation point.
@@ -124,9 +128,9 @@ int barrier_wait (barrier_t *barrier)
* anymore. * anymore.
*/ */
while (cycle == barrier->cycle) { while (cycle == barrier->cycle) {
status = pthread_cond_wait ( status = pthread_cond_wait(&barrier->cv, &barrier->mutex);
&barrier->cv, &barrier->mutex); if (status != 0)
if (status != 0) break; break;
} }
pthread_setcancelstate(cancel, &tmp); pthread_setcancelstate(cancel, &tmp);

View File

@@ -31,8 +31,10 @@ typedef struct barrier_tag {
* Support static initialization of barriers * Support static initialization of barriers
*/ */
#define BARRIER_INITIALIZER(cnt) \ #define BARRIER_INITIALIZER(cnt) \
{PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, \ { \
BARRIER_VALID, cnt, cnt, 0} PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, BARRIER_VALID, cnt, \
cnt, 0 \
}
/* /*
* Define barrier functions * Define barrier functions

View File

@@ -29,7 +29,8 @@ thread_t thread[THREADS];
/* /*
* Start routine for threads. * Start routine for threads.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
thread_t* self = (thread_t*) arg; /* Thread's thread_t */ thread_t* self = (thread_t*) arg; /* Thread's thread_t */
int in_loop, out_loop, count, status; int in_loop, out_loop, count, status;
@@ -69,7 +70,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int arg, char *argv[]) int
main(int arg, char* argv[])
{ {
int thread_count, array_count; int thread_count, array_count;
int status; int status;
@@ -87,7 +89,9 @@ int main (int arg, char *argv[])
thread[thread_count].array[array_count] = array_count + 1; thread[thread_count].array[array_count] = array_count + 1;
status = pthread_create(&thread[thread_count].thread_id, status = pthread_create(&thread[thread_count].thread_id,
NULL, thread_routine, (void*)&thread[thread_count]); NULL,
thread_routine,
(void*) &thread[thread_count]);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }

View File

@@ -21,14 +21,15 @@
* lock. rwl_writetrylock() attempts to lock a read-write lock * lock. rwl_writetrylock() attempts to lock a read-write lock
* for write access, and returns EBUSY instead of blocking. * for write access, and returns EBUSY instead of blocking.
*/ */
#include "rwlock.h"
#include <pthread.h> #include <pthread.h>
#include "errors.h" #include "errors.h"
#include "rwlock.h"
/* /*
* Initialize a read-write lock * Initialize a read-write lock
*/ */
int rwl_init (rwlock_t *rwl) int
rwl_init(rwlock_t* rwl)
{ {
int status; int status;
@@ -58,7 +59,8 @@ int rwl_init (rwlock_t *rwl)
/* /*
* Destroy a read-write lock * Destroy a read-write lock
*/ */
int rwl_destroy (rwlock_t *rwl) int
rwl_destroy(rwlock_t* rwl)
{ {
int status, status1, status2; int status, status1, status2;
@@ -103,7 +105,8 @@ int rwl_destroy (rwlock_t *rwl)
* Simply record that the thread is no longer waiting, * Simply record that the thread is no longer waiting,
* and unlock the mutex. * and unlock the mutex.
*/ */
static void rwl_readcleanup (void *arg) static void
rwl_readcleanup(void* arg)
{ {
rwlock_t* rwl = (rwlock_t*) arg; rwlock_t* rwl = (rwlock_t*) arg;
@@ -114,7 +117,8 @@ static void rwl_readcleanup (void *arg)
/* /*
* Lock a read-write lock for read access. * Lock a read-write lock for read access.
*/ */
int rwl_readlock (rwlock_t *rwl) int
rwl_readlock(rwlock_t* rwl)
{ {
int status; int status;
@@ -144,7 +148,8 @@ int rwl_readlock (rwlock_t *rwl)
* Attempt to lock a read-write lock for read access (don't * Attempt to lock a read-write lock for read access (don't
* block if unavailable). * block if unavailable).
*/ */
int rwl_readtrylock (rwlock_t *rwl) int
rwl_readtrylock(rwlock_t* rwl)
{ {
int status, status2; int status, status2;
@@ -164,7 +169,8 @@ int rwl_readtrylock (rwlock_t *rwl)
/* /*
* Unlock a read-write lock from read access. * Unlock a read-write lock from read access.
*/ */
int rwl_readunlock (rwlock_t *rwl) int
rwl_readunlock(rwlock_t* rwl)
{ {
int status, status2; int status, status2;
@@ -187,7 +193,8 @@ int rwl_readunlock (rwlock_t *rwl)
* Simply record that the thread is no longer waiting, * Simply record that the thread is no longer waiting,
* and unlock the mutex. * and unlock the mutex.
*/ */
static void rwl_writecleanup (void *arg) static void
rwl_writecleanup(void* arg)
{ {
rwlock_t* rwl = (rwlock_t*) arg; rwlock_t* rwl = (rwlock_t*) arg;
@@ -198,7 +205,8 @@ static void rwl_writecleanup (void *arg)
/* /*
* Lock a read-write lock for write access. * Lock a read-write lock for write access.
*/ */
int rwl_writelock (rwlock_t *rwl) int
rwl_writelock(rwlock_t* rwl)
{ {
int status; int status;
@@ -228,7 +236,8 @@ int rwl_writelock (rwlock_t *rwl)
* Attempt to lock a read-write lock for write access. Don't * Attempt to lock a read-write lock for write access. Don't
* block if unavailable. * block if unavailable.
*/ */
int rwl_writetrylock (rwlock_t *rwl) int
rwl_writetrylock(rwlock_t* rwl)
{ {
int status, status2; int status, status2;
@@ -248,7 +257,8 @@ int rwl_writetrylock (rwlock_t *rwl)
/* /*
* Unlock a read-write lock from write access. * Unlock a read-write lock from write access.
*/ */
int rwl_writeunlock (rwlock_t *rwl) int
rwl_writeunlock(rwlock_t* rwl)
{ {
int status; int status;
@@ -264,7 +274,8 @@ int rwl_writeunlock (rwlock_t *rwl)
pthread_mutex_unlock(&rwl->mutex); pthread_mutex_unlock(&rwl->mutex);
return status; return status;
} }
} else if (rwl->w_wait > 0) { }
else if (rwl->w_wait > 0) {
status = pthread_cond_signal(&rwl->write); status = pthread_cond_signal(&rwl->write);
if (status != 0) { if (status != 0) {
pthread_mutex_unlock(&rwl->mutex); pthread_mutex_unlock(&rwl->mutex);

View File

@@ -33,8 +33,10 @@ typedef struct rwlock_tag {
* Support static initialization of barriers * Support static initialization of barriers
*/ */
#define RWL_INITIALIZER \ #define RWL_INITIALIZER \
{PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, \ { \
PTHREAD_COND_INITIALIZER, RWLOCK_VALID, 0, 0, 0, 0} PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, \
PTHREAD_COND_INITIALIZER, RWLOCK_VALID, 0, 0, 0, 0 \
}
/* /*
* Define read-write lock functions * Define read-write lock functions

View File

@@ -8,8 +8,8 @@
* to allow interleaved thread execution, since threads are not * to allow interleaved thread execution, since threads are not
* timesliced. * timesliced.
*/ */
#include "rwlock.h"
#include "errors.h" #include "errors.h"
#include "rwlock.h"
#define THREADS 5 #define THREADS 5
#define DATASIZE 15 #define DATASIZE 15
@@ -41,7 +41,8 @@ data_t data[DATASIZE];
/* /*
* Thread start routine that uses read-write locks * Thread start routine that uses read-write locks
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
thread_t* self = (thread_t*) arg; thread_t* self = (thread_t*) arg;
int repeats = 0; int repeats = 0;
@@ -65,7 +66,8 @@ void *thread_routine (void *arg)
status = rwl_writeunlock(&data[element].lock); status = rwl_writeunlock(&data[element].lock);
if (status != 0) if (status != 0)
err_abort(status, "Write unlock"); err_abort(status, "Write unlock");
} else { }
else {
/* /*
* Look at the current data element to see whether * Look at the current data element to see whether
* the current thread last updated it. Count the * the current thread last updated it. Count the
@@ -87,13 +89,14 @@ void *thread_routine (void *arg)
} }
if (repeats > 0) if (repeats > 0)
printf ( printf("Thread %d found unchanged elements %d times\n",
"Thread %d found unchanged elements %d times\n", self->thread_num,
self->thread_num, repeats); repeats);
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int count; int count;
int data_count; int data_count;
@@ -132,7 +135,9 @@ int main (int argc, char *argv[])
threads[count].reads = 0; threads[count].reads = 0;
threads[count].interval = rand_r(&seed) % 71; threads[count].interval = rand_r(&seed) % 71;
status = pthread_create(&threads[count].thread_id, status = pthread_create(&threads[count].thread_id,
NULL, thread_routine, (void*)&threads[count]); NULL,
thread_routine,
(void*) &threads[count]);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }
@@ -147,8 +152,10 @@ int main (int argc, char *argv[])
err_abort(status, "Join thread"); err_abort(status, "Join thread");
thread_updates += threads[count].updates; thread_updates += threads[count].updates;
printf("%02d: interval %d, updates %d, reads %d\n", printf("%02d: interval %d, updates %d, reads %d\n",
count, threads[count].interval, count,
threads[count].updates, threads[count].reads); threads[count].interval,
threads[count].updates,
threads[count].reads);
} }
/* /*
@@ -157,11 +164,12 @@ int main (int argc, char *argv[])
for (data_count = 0; data_count < DATASIZE; data_count++) { for (data_count = 0; data_count < DATASIZE; data_count++) {
data_updates += data[data_count].updates; data_updates += data[data_count].updates;
printf("data %02d: value %d, %d updates\n", printf("data %02d: value %d, %d updates\n",
data_count, data[data_count].data, data[data_count].updates); data_count,
data[data_count].data,
data[data_count].updates);
rwl_destroy(&data[data_count].lock); rwl_destroy(&data[data_count].lock);
} }
printf ("%d thread updates, %d data updates\n", printf("%d thread updates, %d data updates\n", thread_updates, data_updates);
thread_updates, data_updates);
return 0; return 0;
} }

View File

@@ -8,8 +8,8 @@
* timesliced. * timesliced.
*/ */
#include <pthread.h> #include <pthread.h>
#include "rwlock.h"
#include "errors.h" #include "errors.h"
#include "rwlock.h"
#define THREADS 5 #define THREADS 5
#define ITERATIONS 1000 #define ITERATIONS 1000
@@ -42,7 +42,8 @@ data_t data[DATASIZE];
/* /*
* Thread start routine that uses read-write locks * Thread start routine that uses read-write locks
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
thread_t* self = (thread_t*) arg; thread_t* self = (thread_t*) arg;
int iteration; int iteration;
@@ -61,19 +62,24 @@ void *thread_routine (void *arg)
data[element].updates++; data[element].updates++;
self->updates++; self->updates++;
rwl_writeunlock(&data[element].lock); rwl_writeunlock(&data[element].lock);
} else }
else
err_abort(status, "Try write lock"); err_abort(status, "Try write lock");
} else { }
else {
status = rwl_readtrylock(&data[element].lock); status = rwl_readtrylock(&data[element].lock);
if (status == EBUSY) if (status == EBUSY)
self->r_collisions++; self->r_collisions++;
else if (status != 0) { else if (status != 0) {
err_abort(status, "Try read lock"); err_abort(status, "Try read lock");
} else { }
else {
if (data[element].data != data[element].updates) if (data[element].data != data[element].updates)
printf("%d: data[%d] %d != %d\n", printf("%d: data[%d] %d != %d\n",
self->thread_num, element, self->thread_num,
data[element].data, data[element].updates); element,
data[element].data,
data[element].updates);
rwl_readunlock(&data[element].lock); rwl_readunlock(&data[element].lock);
} }
} }
@@ -85,7 +91,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
int count, data_count; int count, data_count;
unsigned int seed = 1; unsigned int seed = 1;
@@ -121,7 +128,9 @@ int main (int argc, char *argv[])
threads[count].updates = 0; threads[count].updates = 0;
threads[count].interval = rand_r(&seed) % ITERATIONS; threads[count].interval = rand_r(&seed) % ITERATIONS;
status = pthread_create(&threads[count].thread_id, status = pthread_create(&threads[count].thread_id,
NULL, thread_routine, (void*)&threads[count]); NULL,
thread_routine,
(void*) &threads[count]);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
} }
@@ -135,11 +144,14 @@ int main (int argc, char *argv[])
if (status != 0) if (status != 0)
err_abort(status, "Join thread"); err_abort(status, "Join thread");
thread_updates += threads[count].updates; thread_updates += threads[count].updates;
printf ("%02d: interval %d, updates %d, " printf(
"%02d: interval %d, updates %d, "
"r_collisions %d, w_collisions %d\n", "r_collisions %d, w_collisions %d\n",
count, threads[count].interval, count,
threads[count].interval,
threads[count].updates, threads[count].updates,
threads[count].r_collisions, threads[count].w_collisions); threads[count].r_collisions,
threads[count].w_collisions);
} }
/* /*
@@ -148,7 +160,9 @@ int main (int argc, char *argv[])
for (data_count = 0; data_count < DATASIZE; data_count++) { for (data_count = 0; data_count < DATASIZE; data_count++) {
data_updates += data[data_count].updates; data_updates += data[data_count].updates;
printf("data %02d: value %d, %d updates\n", printf("data %02d: value %d, %d updates\n",
data_count, data[data_count].data, data[data_count].updates); data_count,
data[data_count].data,
data[data_count].updates);
rwl_destroy(&data[data_count].lock); rwl_destroy(&data[data_count].lock);
} }

View File

@@ -20,16 +20,17 @@
* processing threads will begin to shut down. (They will be * processing threads will begin to shut down. (They will be
* restarted when work appears.) * restarted when work appears.)
*/ */
#include "workq.h"
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include "errors.h" #include "errors.h"
#include "workq.h"
/* /*
* Thread start routine to serve the work queue. * Thread start routine to serve the work queue.
*/ */
static void *workq_server (void *arg) static void*
workq_server(void* arg)
{ {
struct timespec timeout; struct timespec timeout;
workq_t* wq = (workq_t*) arg; workq_t* wq = (workq_t*) arg;
@@ -59,13 +60,13 @@ static void *workq_server (void *arg)
* Server threads time out after spending 2 seconds * Server threads time out after spending 2 seconds
* waiting for new work, and exit. * waiting for new work, and exit.
*/ */
status = pthread_cond_timedwait ( status = pthread_cond_timedwait(&wq->cv, &wq->mutex, &timeout);
&wq->cv, &wq->mutex, &timeout);
if (status == ETIMEDOUT) { if (status == ETIMEDOUT) {
DPRINTF(("Worker wait timed out\n")); DPRINTF(("Worker wait timed out\n"));
timedout = 1; timedout = 1;
break; break;
} else if (status != 0) { }
else if (status != 0) {
/* /*
* This shouldn't happen, so the work queue * This shouldn't happen, so the work queue
* package should fail. Because the work queue * package should fail. Because the work queue
@@ -80,9 +81,7 @@ static void *workq_server (void *arg)
* queued. That could be fixed by creating a new * queued. That could be fixed by creating a new
* server here. * server here.
*/ */
DPRINTF (( DPRINTF(("Worker wait failed, %d (%s)\n", status, strerror(status)));
"Worker wait failed, %d (%s)\n",
status, strerror (status)));
wq->counter--; wq->counter--;
pthread_mutex_unlock(&wq->mutex); pthread_mutex_unlock(&wq->mutex);
return NULL; return NULL;
@@ -149,15 +148,15 @@ static void *workq_server (void *arg)
/* /*
* Initialize a work queue. * Initialize a work queue.
*/ */
int workq_init (workq_t *wq, int threads, void (*engine)(void *arg)) int
workq_init(workq_t* wq, int threads, void (*engine)(void* arg))
{ {
int status; int status;
status = pthread_attr_init(&wq->attr); status = pthread_attr_init(&wq->attr);
if (status != 0) if (status != 0)
return status; return status;
status = pthread_attr_setdetachstate ( status = pthread_attr_setdetachstate(&wq->attr, PTHREAD_CREATE_DETACHED);
&wq->attr, PTHREAD_CREATE_DETACHED);
if (status != 0) { if (status != 0) {
pthread_attr_destroy(&wq->attr); pthread_attr_destroy(&wq->attr);
return status; return status;
@@ -186,7 +185,8 @@ int workq_init (workq_t *wq, int threads, void (*engine)(void *arg))
/* /*
* Destroy a work queue. * Destroy a work queue.
*/ */
int workq_destroy (workq_t *wq) int
workq_destroy(workq_t* wq)
{ {
int status, status1, status2; int status, status1, status2;
@@ -246,7 +246,8 @@ int workq_destroy (workq_t *wq)
/* /*
* Add an item to a work queue. * Add an item to a work queue.
*/ */
int workq_add (workq_t *wq, void *element) int
workq_add(workq_t* wq, void* element)
{ {
workq_ele_t* item; workq_ele_t* item;
pthread_t id; pthread_t id;
@@ -288,14 +289,14 @@ int workq_add (workq_t *wq, void *element)
pthread_mutex_unlock(&wq->mutex); pthread_mutex_unlock(&wq->mutex);
return status; return status;
} }
} else if (wq->counter < wq->parallelism) { }
else if (wq->counter < wq->parallelism) {
/* /*
* If there were no idling threads, and we're allowed to * If there were no idling threads, and we're allowed to
* create a new thread, do so. * create a new thread, do so.
*/ */
DPRINTF(("Creating new worker\n")); DPRINTF(("Creating new worker\n"));
status = pthread_create ( status = pthread_create(&id, &wq->attr, workq_server, (void*) wq);
&id, &wq->attr, workq_server, (void*)wq);
if (status != 0) { if (status != 0) {
pthread_mutex_unlock(&wq->mutex); pthread_mutex_unlock(&wq->mutex);
return status; return status;

View File

@@ -51,8 +51,7 @@ typedef struct workq_tag {
/* /*
* Define work queue functions * Define work queue functions
*/ */
extern int workq_init ( extern int workq_init(workq_t* wq,
workq_t *wq,
int threads, /* maximum threads */ int threads, /* maximum threads */
void (*engine)(void*)); /* engine routine */ void (*engine)(void*)); /* engine routine */
extern int workq_destroy(workq_t* wq); extern int workq_destroy(workq_t* wq);

View File

@@ -4,11 +4,11 @@
* Demonstrate a use of work queues. * Demonstrate a use of work queues.
*/ */
#include <pthread.h> #include <pthread.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <time.h> #include <time.h>
#include "workq.h"
#include "errors.h" #include "errors.h"
#include "workq.h"
#define ITERATIONS 25 #define ITERATIONS 25
@@ -31,7 +31,8 @@ workq_t workq;
/* /*
* Thread-specific data destructor routine for engine_key * Thread-specific data destructor routine for engine_key
*/ */
void destructor (void *value_ptr) void
destructor(void* value_ptr)
{ {
engine_t* engine = (engine_t*) value_ptr; engine_t* engine = (engine_t*) value_ptr;
@@ -45,7 +46,8 @@ void destructor (void *value_ptr)
* This is the routine called by the work queue servers to * This is the routine called by the work queue servers to
* perform operations in parallel. * perform operations in parallel.
*/ */
void engine_routine (void *arg) void
engine_routine(void* arg)
{ {
engine_t* engine; engine_t* engine;
power_t* power = (power_t*) arg; power_t* power = (power_t*) arg;
@@ -55,27 +57,25 @@ void engine_routine (void *arg)
engine = pthread_getspecific(engine_key); engine = pthread_getspecific(engine_key);
if (engine == NULL) { if (engine == NULL) {
engine = (engine_t*) malloc(sizeof(engine_t)); engine = (engine_t*) malloc(sizeof(engine_t));
status = pthread_setspecific ( status = pthread_setspecific(engine_key, (void*) engine);
engine_key, (void*)engine);
if (status != 0) if (status != 0)
err_abort(status, "Set tsd"); err_abort(status, "Set tsd");
engine->thread_id = pthread_self(); engine->thread_id = pthread_self();
engine->calls = 1; engine->calls = 1;
} else }
else
engine->calls++; engine->calls++;
result = 1; result = 1;
printf ( printf("Engine: computing %d^%d\n", power->value, power->power);
"Engine: computing %d^%d\n", for (count = 1; count <= power->power; count++) result *= power->value;
power->value, power->power);
for (count = 1; count <= power->power; count++)
result *= power->value;
free(arg); free(arg);
} }
/* /*
* Thread start routine that issues work queue requests. * Thread start routine that issues work queue requests.
*/ */
void *thread_routine (void *arg) void*
thread_routine(void* arg)
{ {
power_t* element; power_t* element;
int count; int count;
@@ -91,9 +91,7 @@ void *thread_routine (void *arg)
errno_abort("Allocate element"); errno_abort("Allocate element");
element->value = rand_r(&seed) % 20; element->value = rand_r(&seed) % 20;
element->power = rand_r(&seed) % 7; element->power = rand_r(&seed) % 7;
DPRINTF (( DPRINTF(("Request: %d^%d\n", element->value, element->power));
"Request: %d^%d\n",
element->value, element->power));
status = workq_add(&workq, (void*) element); status = workq_add(&workq, (void*) element);
if (status != 0) if (status != 0)
err_abort(status, "Add to work queue"); err_abort(status, "Add to work queue");
@@ -102,7 +100,8 @@ void *thread_routine (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t thread_id; pthread_t thread_id;
engine_t* engine; engine_t* engine;
@@ -138,7 +137,6 @@ int main (int argc, char *argv[])
printf("engine %d: %d calls\n", count, engine->calls); printf("engine %d: %d calls\n", count, engine->calls);
engine = engine->link; engine = engine->link;
} }
printf ("%d engine threads processed %d calls\n", printf("%d engine threads processed %d calls\n", count, calls);
count, calls);
return 0; return 0;
} }

View File

@@ -11,7 +11,8 @@
#include <pthread.h> #include <pthread.h>
#include "errors.h" #include "errors.h"
void *printer_thread (void *arg) void*
printer_thread(void* arg)
{ {
char* string = *(char**) arg; char* string = *(char**) arg;
@@ -19,7 +20,8 @@ void *printer_thread (void *arg)
return NULL; return NULL;
} }
int main (int argc, char *argv[]) int
main(int argc, char* argv[])
{ {
pthread_t printer_id; pthread_t printer_id;
char* string_ptr; char* string_ptr;
@@ -35,8 +37,8 @@ int main (int argc, char *argv[])
thr_setconcurrency(2); thr_setconcurrency(2);
#endif #endif
string_ptr = "Before value"; string_ptr = "Before value";
status = pthread_create ( status =
&printer_id, NULL, printer_thread, (void*)&string_ptr); pthread_create(&printer_id, NULL, printer_thread, (void*) &string_ptr);
if (status != 0) if (status != 0)
err_abort(status, "Create thread"); err_abort(status, "Create thread");
@@ -46,7 +48,8 @@ int main (int argc, char *argv[])
* to be timesliced. (This is a tricky balance, and the loop may * to be timesliced. (This is a tricky balance, and the loop may
* need to be adjusted on your system before you can see the bug.) * need to be adjusted on your system before you can see the bug.)
*/ */
for (i = 0; i < 10000000; i++); for (i = 0; i < 10000000; i++)
;
string_ptr = "After value"; string_ptr = "After value";
status = pthread_join(printer_id, NULL); status = pthread_join(printer_id, NULL);