run clang-format
This commit is contained in:
104
.clang-format
Normal file
104
.clang-format
Normal 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
|
||||
8
Makefile
8
Makefile
@@ -73,7 +73,13 @@ ch04/pipe_cpp.cpp
|
||||
NAMES_CXX=$(SOURCES_CXX:.cpp=)
|
||||
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:
|
||||
mkdir -p $(BIN)
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
*/
|
||||
#include "errors.h"
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int seconds;
|
||||
char line[128];
|
||||
@@ -15,18 +16,20 @@ int main (int argc, char *argv[])
|
||||
|
||||
while (1) {
|
||||
printf("Alarm> ");
|
||||
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
|
||||
if (strlen (line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Parse input line into seconds (%d) and a message
|
||||
* (%64[^\n]), consisting of up to 64 characters
|
||||
* separated from the seconds by whitespace.
|
||||
*/
|
||||
if (sscanf (line, "%d %64[^\n]",
|
||||
&seconds, message) < 2) {
|
||||
if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2) {
|
||||
fprintf(stderr, "Bad command\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sleep(seconds);
|
||||
printf("(%d) %s\n", seconds, message);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include <wait.h>
|
||||
#include "errors.h"
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
char line[128];
|
||||
@@ -18,18 +19,20 @@ int main (int argc, char *argv[])
|
||||
|
||||
while (1) {
|
||||
printf("Alarm> ");
|
||||
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
|
||||
if (strlen (line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Parse input line into seconds (%d) and a message
|
||||
* (%64[^\n]), consisting of up to 64 characters
|
||||
* separated from the seconds by whitespace.
|
||||
*/
|
||||
if (sscanf (line, "%d %64[^\n]",
|
||||
&seconds, message) < 2) {
|
||||
if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2) {
|
||||
fprintf(stderr, "Bad command\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
pid = fork();
|
||||
if (pid == (pid_t) -1)
|
||||
errno_abort("Fork");
|
||||
@@ -40,7 +43,8 @@ int main (int argc, char *argv[])
|
||||
sleep(seconds);
|
||||
printf("(%d) %s\n", seconds, message);
|
||||
exit(0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* In the parent, call waitpid() to collect any children that
|
||||
* have already terminated.
|
||||
|
||||
@@ -12,7 +12,8 @@ typedef struct alarm_tag {
|
||||
char message[64];
|
||||
} alarm_t;
|
||||
|
||||
void *alarm_thread (void *arg)
|
||||
void*
|
||||
alarm_thread(void* arg)
|
||||
{
|
||||
alarm_t* alarm = (alarm_t*) arg;
|
||||
int status;
|
||||
@@ -25,7 +26,8 @@ void *alarm_thread (void *arg)
|
||||
free(alarm);
|
||||
return NULL;
|
||||
}
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
char line[128];
|
||||
@@ -34,8 +36,10 @@ int main (int argc, char *argv[])
|
||||
|
||||
while (1) {
|
||||
printf("Alarm> ");
|
||||
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
|
||||
if (strlen (line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
alarm = (alarm_t*) malloc(sizeof(alarm_t));
|
||||
if (alarm == NULL)
|
||||
errno_abort("Allocate alarm");
|
||||
@@ -45,13 +49,12 @@ int main (int argc, char *argv[])
|
||||
* (%64[^\n]), consisting of up to 64 characters
|
||||
* separated from the seconds by whitespace.
|
||||
*/
|
||||
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");
|
||||
free(alarm);
|
||||
} else {
|
||||
status = pthread_create (
|
||||
&thread, NULL, alarm_thread, alarm);
|
||||
}
|
||||
else {
|
||||
status = pthread_create(&thread, NULL, alarm_thread, alarm);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create alarm thread");
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
* Demonstrate detection of errors from a typical POSIX 1003.1c-1995
|
||||
* function, pthread_join.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread;
|
||||
int status;
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
#include <pthread.h>
|
||||
#include "errors.h"
|
||||
|
||||
void *hello_world (void *arg)
|
||||
void*
|
||||
hello_world(void* arg)
|
||||
{
|
||||
printf("Hello world\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t hello_id;
|
||||
int status;
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
/*
|
||||
* Thread start routine.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
printf("Inside thread %i\n", pthread_self());
|
||||
return arg;
|
||||
@@ -23,8 +24,7 @@ main (int argc, char *argv[])
|
||||
int status;
|
||||
|
||||
printf("Inside thread %i\n", pthread_self());
|
||||
status = pthread_create (
|
||||
&thread_id, NULL, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id, NULL, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
sleep(1.0);
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
/*
|
||||
* Thread start routine that writes a message.
|
||||
*/
|
||||
void *writer_thread (void *arg)
|
||||
void*
|
||||
writer_thread(void* arg)
|
||||
{
|
||||
sleep(5);
|
||||
printf("Thread I/O\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t writer_id;
|
||||
char *input, buffer[64];
|
||||
|
||||
@@ -36,7 +36,8 @@ time_t current_alarm = 0;
|
||||
/*
|
||||
* Insert alarm entry on list, in order.
|
||||
*/
|
||||
void alarm_insert (alarm_t *alarm)
|
||||
void
|
||||
alarm_insert(alarm_t* alarm)
|
||||
{
|
||||
int status;
|
||||
alarm_t **last, *next;
|
||||
@@ -70,8 +71,8 @@ void alarm_insert (alarm_t *alarm)
|
||||
#ifdef DEBUG
|
||||
printf("[list: ");
|
||||
for (next = alarm_list; next != NULL; next = next->link)
|
||||
printf ("%d(%d)[\"%s\"] ", next->time,
|
||||
next->time - time (NULL), next->message);
|
||||
printf(
|
||||
"%d(%d)[\"%s\"] ", next->time, next->time - time(NULL), next->message);
|
||||
printf("]\n");
|
||||
#endif
|
||||
/*
|
||||
@@ -91,7 +92,8 @@ void alarm_insert (alarm_t *alarm)
|
||||
/*
|
||||
* The alarm thread's start routine.
|
||||
*/
|
||||
void *alarm_thread (void *arg)
|
||||
void*
|
||||
alarm_thread(void* arg)
|
||||
{
|
||||
alarm_t* alarm;
|
||||
struct timespec cond_time;
|
||||
@@ -125,15 +127,16 @@ void *alarm_thread (void *arg)
|
||||
expired = 0;
|
||||
if (alarm->time > now) {
|
||||
#ifdef DEBUG
|
||||
printf ("[waiting: %d(%d)\"%s\"]\n", alarm->time,
|
||||
alarm->time - time (NULL), alarm->message);
|
||||
printf("[waiting: %d(%d)\"%s\"]\n",
|
||||
alarm->time,
|
||||
alarm->time - time(NULL),
|
||||
alarm->message);
|
||||
#endif
|
||||
cond_time.tv_sec = alarm->time;
|
||||
cond_time.tv_nsec = 0;
|
||||
current_alarm = alarm->time;
|
||||
while (current_alarm == alarm->time) {
|
||||
status = pthread_cond_timedwait (
|
||||
&alarm_cond, &alarm_mutex, &cond_time);
|
||||
status = pthread_cond_timedwait(&alarm_cond, &alarm_mutex, &cond_time);
|
||||
if (status == ETIMEDOUT) {
|
||||
expired = 1;
|
||||
break;
|
||||
@@ -143,7 +146,8 @@ void *alarm_thread (void *arg)
|
||||
}
|
||||
if (!expired)
|
||||
alarm_insert(alarm);
|
||||
} else
|
||||
}
|
||||
else
|
||||
expired = 1;
|
||||
if (expired) {
|
||||
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;
|
||||
char line[128];
|
||||
alarm_t* alarm;
|
||||
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");
|
||||
while (1) {
|
||||
printf("Alarm> ");
|
||||
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
|
||||
if (strlen (line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
alarm = (alarm_t*) malloc(sizeof(alarm_t));
|
||||
if (alarm == NULL)
|
||||
errno_abort("Allocate alarm");
|
||||
@@ -176,11 +182,11 @@ int main (int argc, char *argv[])
|
||||
* (%64[^\n]), consisting of up to 64 characters
|
||||
* separated from the seconds by whitespace.
|
||||
*/
|
||||
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");
|
||||
free(alarm);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
status = pthread_mutex_lock(&alarm_mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "Lock mutex");
|
||||
|
||||
@@ -34,7 +34,8 @@ alarm_t *alarm_list = NULL;
|
||||
/*
|
||||
* The alarm thread's start routine.
|
||||
*/
|
||||
void *alarm_thread (void *arg)
|
||||
void*
|
||||
alarm_thread(void* arg)
|
||||
{
|
||||
alarm_t* alarm;
|
||||
int sleep_time;
|
||||
@@ -69,8 +70,8 @@ void *alarm_thread (void *arg)
|
||||
else
|
||||
sleep_time = alarm->time - now;
|
||||
#ifdef DEBUG
|
||||
printf ("[waiting: %d(%d)\"%s\"]\n", alarm->time,
|
||||
sleep_time, alarm->message);
|
||||
printf(
|
||||
"[waiting: %d(%d)\"%s\"]\n", alarm->time, sleep_time, alarm->message);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -101,21 +102,23 @@ void *alarm_thread (void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
char line[128];
|
||||
alarm_t *alarm, **last, *next;
|
||||
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");
|
||||
while (1) {
|
||||
printf("alarm> ");
|
||||
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
|
||||
if (strlen (line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
alarm = (alarm_t*) malloc(sizeof(alarm_t));
|
||||
if (alarm == NULL)
|
||||
errno_abort("Allocate alarm");
|
||||
@@ -125,11 +128,11 @@ int main (int argc, char *argv[])
|
||||
* (%64[^\n]), consisting of up to 64 characters
|
||||
* separated from the seconds by whitespace.
|
||||
*/
|
||||
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");
|
||||
free(alarm);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
status = pthread_mutex_lock(&alarm_mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "Lock mutex");
|
||||
@@ -163,8 +166,10 @@ int main (int argc, char *argv[])
|
||||
#ifdef DEBUG
|
||||
printf("[list: ");
|
||||
for (next = alarm_list; next != NULL; next = next->link)
|
||||
printf ("%d(%d)[\"%s\"] ", next->time,
|
||||
next->time - time (NULL), next->message);
|
||||
printf("%d(%d)[\"%s\"] ",
|
||||
next->time,
|
||||
next->time - time(NULL),
|
||||
next->message);
|
||||
printf("]\n");
|
||||
#endif
|
||||
status = pthread_mutex_unlock(&alarm_mutex);
|
||||
|
||||
@@ -39,7 +39,9 @@ std::list<alarm_t> alarm_list;
|
||||
/*
|
||||
* The alarm thread's start routine.
|
||||
*/
|
||||
void *alarm_thread(void *arg) {
|
||||
void*
|
||||
alarm_thread(void* arg)
|
||||
{
|
||||
int sleep_time;
|
||||
time_t now;
|
||||
int status;
|
||||
@@ -50,7 +52,8 @@ void *alarm_thread(void *arg) {
|
||||
*/
|
||||
while (1) {
|
||||
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);
|
||||
sleep_time = 0;
|
||||
@@ -59,7 +62,8 @@ void *alarm_thread(void *arg) {
|
||||
if (it->time <= now) {
|
||||
printf("(%d) %s\n", it->seconds, it->message);
|
||||
it = alarm_list.erase(it);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sleep_time = MIN(it->time - now, sleep_time);
|
||||
++it;
|
||||
}
|
||||
@@ -74,7 +78,8 @@ void *alarm_thread(void *arg) {
|
||||
* if there's no input.
|
||||
*/
|
||||
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)
|
||||
sleep(sleep_time);
|
||||
else
|
||||
@@ -82,17 +87,22 @@ void *alarm_thread(void *arg) {
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
char line[128];
|
||||
pthread_t thread;
|
||||
|
||||
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) {
|
||||
printf("alarm> ");
|
||||
if (fgets(line, sizeof(line), stdin) == NULL) exit(0);
|
||||
if (strlen(line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
alarm_t alarm;
|
||||
|
||||
/*
|
||||
@@ -102,11 +112,13 @@ int main(int argc, char *argv[]) {
|
||||
*/
|
||||
if (sscanf(line, "%d %64[^\n]", &alarm.seconds, alarm.message) < 2) {
|
||||
fprintf(stderr, "Bad command\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
alarm.time = time(NULL) + alarm.seconds;
|
||||
|
||||
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.
|
||||
@@ -116,12 +128,15 @@ int main(int argc, char *argv[]) {
|
||||
#ifdef DEBUG
|
||||
printf("[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);
|
||||
printf("]\n");
|
||||
#endif
|
||||
status = pthread_mutex_unlock(&alarm_mutex);
|
||||
if (status != 0) err_abort(status, "Unlock mutex");
|
||||
if (status != 0)
|
||||
err_abort(status, "Unlock mutex");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
/*
|
||||
* 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};
|
||||
|
||||
int backoff = 1; /* Whether to backoff or deadlock */
|
||||
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
|
||||
* opposite.
|
||||
*/
|
||||
void *lock_forward (void *arg)
|
||||
void*
|
||||
lock_forward(void* arg)
|
||||
{
|
||||
int i, iterate, backoffs;
|
||||
int status;
|
||||
@@ -43,22 +42,22 @@ void *lock_forward (void *arg)
|
||||
status = pthread_mutex_lock(&mutex[i]);
|
||||
if (status != 0)
|
||||
err_abort(status, "First lock");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (backoff)
|
||||
status = pthread_mutex_trylock(&mutex[i]);
|
||||
else
|
||||
status = pthread_mutex_lock(&mutex[i]);
|
||||
if (status == EBUSY) {
|
||||
backoffs++;
|
||||
DPRINTF ((
|
||||
" [forward locker backing off at %d]\n",
|
||||
i));
|
||||
DPRINTF((" [forward locker backing off at %d]\n", i));
|
||||
for (; i >= 0; i--) {
|
||||
status = pthread_mutex_unlock(&mutex[i]);
|
||||
if (status != 0)
|
||||
err_abort(status, "Backoff");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (status != 0)
|
||||
err_abort(status, "Lock mutex");
|
||||
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.
|
||||
*/
|
||||
printf (
|
||||
"lock forward got all locks, %d backoffs\n", backoffs);
|
||||
printf("lock forward got all locks, %d backoffs\n", backoffs);
|
||||
pthread_mutex_unlock(&mutex[2]);
|
||||
pthread_mutex_unlock(&mutex[1]);
|
||||
pthread_mutex_unlock(&mutex[0]);
|
||||
@@ -93,7 +91,8 @@ void *lock_forward (void *arg)
|
||||
* reverse order, to ensure a conflict with lock_forward, which
|
||||
* does the opposite.
|
||||
*/
|
||||
void *lock_backward (void *arg)
|
||||
void*
|
||||
lock_backward(void* arg)
|
||||
{
|
||||
int i, iterate, backoffs;
|
||||
int status;
|
||||
@@ -105,22 +104,22 @@ void *lock_backward (void *arg)
|
||||
status = pthread_mutex_lock(&mutex[i]);
|
||||
if (status != 0)
|
||||
err_abort(status, "First lock");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (backoff)
|
||||
status = pthread_mutex_trylock(&mutex[i]);
|
||||
else
|
||||
status = pthread_mutex_lock(&mutex[i]);
|
||||
if (status == EBUSY) {
|
||||
backoffs++;
|
||||
DPRINTF ((
|
||||
" [backward locker backing off at %d]\n",
|
||||
i));
|
||||
DPRINTF((" [backward locker backing off at %d]\n", i));
|
||||
for (; i < 3; i++) {
|
||||
status = pthread_mutex_unlock(&mutex[i]);
|
||||
if (status != 0)
|
||||
err_abort(status, "Backoff");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (status != 0)
|
||||
err_abort(status, "Lock mutex");
|
||||
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.
|
||||
*/
|
||||
printf (
|
||||
"lock backward got all locks, %d backoffs\n", backoffs);
|
||||
printf("lock backward got all locks, %d backoffs\n", backoffs);
|
||||
pthread_mutex_unlock(&mutex[0]);
|
||||
pthread_mutex_unlock(&mutex[1]);
|
||||
pthread_mutex_unlock(&mutex[2]);
|
||||
@@ -150,7 +148,8 @@ void *lock_backward (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t forward, backward;
|
||||
int status;
|
||||
@@ -187,12 +186,10 @@ int main (int argc, char *argv[])
|
||||
*/
|
||||
if (argc > 2)
|
||||
yield_flag = atoi(argv[2]);
|
||||
status = pthread_create (
|
||||
&forward, NULL, lock_forward, NULL);
|
||||
status = pthread_create(&forward, NULL, lock_forward, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create forward");
|
||||
status = pthread_create (
|
||||
&backward, NULL, lock_backward, NULL);
|
||||
status = pthread_create(&backward, NULL, lock_backward, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create backward");
|
||||
pthread_exit(NULL);
|
||||
|
||||
@@ -13,8 +13,7 @@ typedef struct my_struct_tag {
|
||||
int value; /* Access protected by mutex */
|
||||
} my_struct_t;
|
||||
|
||||
my_struct_t data = {
|
||||
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
|
||||
my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
|
||||
|
||||
int hibernation = 1; /* Default to 1 second */
|
||||
|
||||
@@ -41,7 +40,8 @@ wait_thread (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
pthread_t wait_thread_id;
|
||||
@@ -76,8 +76,7 @@ int main (int argc, char *argv[])
|
||||
err_abort(status, "Lock mutex");
|
||||
|
||||
while (data.value == 0) {
|
||||
status = pthread_cond_timedwait (
|
||||
&data.cond, &data.mutex, &timeout);
|
||||
status = pthread_cond_timedwait(&data.cond, &data.mutex, &timeout);
|
||||
if (status == ETIMEDOUT) {
|
||||
printf("Condition wait timed out.\n");
|
||||
break;
|
||||
|
||||
@@ -15,7 +15,8 @@ typedef struct my_struct_tag {
|
||||
int value; /* Access protected by mutex */
|
||||
} my_struct_t;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
my_struct_t* data;
|
||||
int status;
|
||||
|
||||
@@ -18,10 +18,10 @@ typedef struct my_struct_tag {
|
||||
int value; /* Access protected by mutex */
|
||||
} my_struct_t;
|
||||
|
||||
my_struct_t data = {
|
||||
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
|
||||
my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ typedef struct my_struct_tag {
|
||||
int value; /* Access protected by mutex */
|
||||
} my_struct_t;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
my_struct_t* data;
|
||||
int status;
|
||||
|
||||
@@ -17,7 +17,8 @@ typedef struct my_struct_tag {
|
||||
|
||||
my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, 0};
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ time_t end_time;
|
||||
* Thread start routine that repeatedly locks a mutex and
|
||||
* increments a counter.
|
||||
*/
|
||||
void *counter_thread(void *arg) {
|
||||
void*
|
||||
counter_thread(void* arg)
|
||||
{
|
||||
int status;
|
||||
int spin;
|
||||
|
||||
@@ -36,11 +38,13 @@ void *counter_thread(void *arg) {
|
||||
*/
|
||||
while (time(NULL) < end_time) {
|
||||
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++;
|
||||
sleep(4);
|
||||
status = pthread_mutex_unlock(&mutex);
|
||||
if (status != 0) err_abort(status, "Unlock mutex");
|
||||
if (status != 0)
|
||||
err_abort(status, "Unlock mutex");
|
||||
sleep(1);
|
||||
}
|
||||
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
|
||||
* trylock fails, skip this cycle.
|
||||
*/
|
||||
void *monitor_thread(void *arg) {
|
||||
void*
|
||||
monitor_thread(void* arg)
|
||||
{
|
||||
int status;
|
||||
int misses = 0;
|
||||
|
||||
@@ -64,18 +70,23 @@ void *monitor_thread(void *arg) {
|
||||
sleep(3);
|
||||
status = pthread_mutex_trylock(&mutex);
|
||||
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);
|
||||
status = pthread_mutex_unlock(&mutex);
|
||||
if (status != 0) err_abort(status, "Unlock mutex");
|
||||
} else
|
||||
if (status != 0)
|
||||
err_abort(status, "Unlock mutex");
|
||||
}
|
||||
else
|
||||
misses++; /* Count "misses" on the lock */
|
||||
}
|
||||
printf("Monitor thread missed update %d times.\n", misses);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
pthread_t counter_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 */
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
if (status != 0) err_abort(status, "Join monitor thread");
|
||||
if (status != 0)
|
||||
err_abort(status, "Join monitor thread");
|
||||
return 0;
|
||||
}
|
||||
|
||||
127
src/ch04/crew.c
127
src/ch04/crew.c
@@ -9,10 +9,10 @@
|
||||
* by calling thr_setconcurrency(), because threads are not
|
||||
* timesliced.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include "errors.h"
|
||||
|
||||
#define CREW_SIZE 4
|
||||
@@ -58,7 +58,8 @@ size_t name_max; /* Name length */
|
||||
* The thread start routine for crew threads. Waits until "go"
|
||||
* 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;
|
||||
crew_p crew = mine->crew;
|
||||
@@ -73,8 +74,7 @@ void *worker_routine (void *arg)
|
||||
* buffer. Thus, allocate a "big chunk" of memory, and use
|
||||
* it as a buffer.
|
||||
*/
|
||||
entry = (struct dirent*)malloc (
|
||||
sizeof (struct dirent) + name_max);
|
||||
entry = (struct dirent*) malloc(sizeof(struct dirent) + name_max);
|
||||
if (entry == NULL)
|
||||
errno_abort("Allocating dirent");
|
||||
|
||||
@@ -113,7 +113,9 @@ void *worker_routine (void *arg)
|
||||
err_abort(status, "Lock crew mutex");
|
||||
|
||||
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) {
|
||||
status = pthread_cond_wait(&crew->go, &crew->mutex);
|
||||
if (status != 0)
|
||||
@@ -121,7 +123,9 @@ void *worker_routine (void *arg)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -132,7 +136,10 @@ void *worker_routine (void *arg)
|
||||
crew->last = NULL;
|
||||
|
||||
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);
|
||||
if (status != 0)
|
||||
@@ -145,10 +152,7 @@ void *worker_routine (void *arg)
|
||||
status = lstat(work->path, &filestat);
|
||||
|
||||
if (S_ISLNK(filestat.st_mode))
|
||||
printf (
|
||||
"Thread %d: %s is a link, skipping.\n",
|
||||
mine->index,
|
||||
work->path);
|
||||
printf("Thread %d: %s is a link, skipping.\n", mine->index, work->path);
|
||||
else if (S_ISDIR(filestat.st_mode)) {
|
||||
DIR* directory;
|
||||
struct dirent* result;
|
||||
@@ -159,21 +163,22 @@ void *worker_routine (void *arg)
|
||||
*/
|
||||
directory = opendir(work->path);
|
||||
if (directory == NULL) {
|
||||
fprintf (
|
||||
stderr, "Unable to open directory %s: %d (%s)\n",
|
||||
fprintf(stderr,
|
||||
"Unable to open directory %s: %d (%s)\n",
|
||||
work->path,
|
||||
errno, strerror (errno));
|
||||
errno,
|
||||
strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
status = readdir_r(directory, entry, &result);
|
||||
if (status != 0) {
|
||||
fprintf (
|
||||
stderr,
|
||||
fprintf(stderr,
|
||||
"Unable to read directory %s: %d (%s)\n",
|
||||
work->path,
|
||||
status, strerror (status));
|
||||
status,
|
||||
strerror(status));
|
||||
break;
|
||||
}
|
||||
if (result == NULL)
|
||||
@@ -203,15 +208,18 @@ void *worker_routine (void *arg)
|
||||
if (crew->first == NULL) {
|
||||
crew->first = new_work;
|
||||
crew->last = new_work;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
crew->last->next = new_work;
|
||||
crew->last = new_work;
|
||||
}
|
||||
crew->work_count++;
|
||||
DPRINTF ((
|
||||
"Crew %d: add work %#lx, first %#lx, last %#lx, %d\n",
|
||||
mine->index, new_work, crew->first,
|
||||
crew->last, crew->work_count));
|
||||
DPRINTF(("Crew %d: add work %#lx, first %#lx, last %#lx, %d\n",
|
||||
mine->index,
|
||||
new_work,
|
||||
crew->first,
|
||||
crew->last,
|
||||
crew->work_count));
|
||||
status = pthread_cond_signal(&crew->go);
|
||||
status = pthread_mutex_unlock(&crew->mutex);
|
||||
if (status != 0)
|
||||
@@ -219,7 +227,8 @@ void *worker_routine (void *arg)
|
||||
}
|
||||
|
||||
closedir(directory);
|
||||
} else if (S_ISREG (filestat.st_mode)) {
|
||||
}
|
||||
else if (S_ISREG(filestat.st_mode)) {
|
||||
FILE* search;
|
||||
char buffer[256], *bufptr, *search_ptr;
|
||||
|
||||
@@ -229,33 +238,33 @@ void *worker_routine (void *arg)
|
||||
*/
|
||||
search = fopen(work->path, "r");
|
||||
if (search == NULL)
|
||||
fprintf (
|
||||
stderr, "Unable to open %s: %d (%s)\n",
|
||||
fprintf(stderr,
|
||||
"Unable to open %s: %d (%s)\n",
|
||||
work->path,
|
||||
errno, strerror (errno));
|
||||
errno,
|
||||
strerror(errno));
|
||||
else {
|
||||
|
||||
while (1) {
|
||||
bufptr = fgets (
|
||||
buffer, sizeof (buffer), search);
|
||||
bufptr = fgets(buffer, sizeof(buffer), search);
|
||||
if (bufptr == NULL) {
|
||||
if (feof(search))
|
||||
break;
|
||||
if (ferror(search)) {
|
||||
fprintf (
|
||||
stderr,
|
||||
fprintf(stderr,
|
||||
"Unable to read %s: %d (%s)\n",
|
||||
work->path,
|
||||
errno, strerror (errno));
|
||||
errno,
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
search_ptr = strstr(buffer, work->string);
|
||||
if (search_ptr != NULL) {
|
||||
flockfile(stdout);
|
||||
printf (
|
||||
"Thread %d found \"%s\" in %s\n",
|
||||
mine->index, work->string, work->path);
|
||||
printf("Thread %d found \"%s\" in %s\n",
|
||||
mine->index,
|
||||
work->string,
|
||||
work->path);
|
||||
#if 0
|
||||
printf ("%s\n", buffer);
|
||||
#endif
|
||||
@@ -265,16 +274,19 @@ void *worker_routine (void *arg)
|
||||
}
|
||||
fclose(search);
|
||||
}
|
||||
} else
|
||||
fprintf (
|
||||
stderr,
|
||||
}
|
||||
else
|
||||
fprintf(stderr,
|
||||
"Thread %d: %s is type %o (%s))\n",
|
||||
mine->index,
|
||||
work->path,
|
||||
filestat.st_mode & S_IFMT,
|
||||
(S_ISFIFO (filestat.st_mode) ? "FIFO"
|
||||
: (S_ISCHR (filestat.st_mode) ? "CHR"
|
||||
: (S_ISBLK (filestat.st_mode) ? "BLK"
|
||||
(S_ISFIFO(filestat.st_mode)
|
||||
? "FIFO"
|
||||
: (S_ISCHR(filestat.st_mode)
|
||||
? "CHR"
|
||||
: (S_ISBLK(filestat.st_mode)
|
||||
? "BLK"
|
||||
: (S_ISSOCK(filestat.st_mode) ? "SOCK"
|
||||
: "unknown")))));
|
||||
|
||||
@@ -295,8 +307,8 @@ void *worker_routine (void *arg)
|
||||
err_abort(status, "Lock crew mutex");
|
||||
|
||||
crew->work_count--;
|
||||
DPRINTF (("Crew %d decremented work to %d\n", mine->index,
|
||||
crew->work_count));
|
||||
DPRINTF(
|
||||
("Crew %d decremented work to %d\n", mine->index, crew->work_count));
|
||||
if (crew->work_count <= 0) {
|
||||
DPRINTF(("Crew thread %d done\n", mine->index));
|
||||
status = pthread_cond_broadcast(&crew->done);
|
||||
@@ -311,7 +323,6 @@ void *worker_routine (void *arg)
|
||||
status = pthread_mutex_unlock(&crew->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "Unlock mutex");
|
||||
|
||||
}
|
||||
|
||||
free(entry);
|
||||
@@ -321,7 +332,8 @@ void *worker_routine (void *arg)
|
||||
/*
|
||||
* 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 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].crew = crew;
|
||||
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)
|
||||
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
|
||||
* using crew_create
|
||||
*/
|
||||
int crew_start (
|
||||
crew_p crew,
|
||||
char *filepath,
|
||||
char *search)
|
||||
int
|
||||
crew_start(crew_p crew, char* filepath, char* search)
|
||||
{
|
||||
work_p request;
|
||||
int status;
|
||||
@@ -407,9 +419,10 @@ int crew_start (
|
||||
else
|
||||
errno_abort("Unable to get NAME_MAX");
|
||||
}
|
||||
DPRINTF ((
|
||||
"PATH_MAX for %s is %ld, NAME_MAX is %ld\n",
|
||||
filepath, path_max, name_max));
|
||||
DPRINTF(("PATH_MAX for %s is %ld, NAME_MAX is %ld\n",
|
||||
filepath,
|
||||
path_max,
|
||||
name_max));
|
||||
path_max++; /* Add null byte */
|
||||
name_max++; /* Add null byte */
|
||||
request = (work_p) malloc(sizeof(work_t));
|
||||
@@ -425,7 +438,8 @@ int crew_start (
|
||||
if (crew->first == NULL) {
|
||||
crew->first = request;
|
||||
crew->last = request;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
crew->last->next = request;
|
||||
crew->last = request;
|
||||
}
|
||||
@@ -453,7 +467,8 @@ int crew_start (
|
||||
/*
|
||||
* The main program to "drive" the crew...
|
||||
*/
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
crew_t my_crew;
|
||||
char line[128], *next;
|
||||
|
||||
@@ -42,7 +42,8 @@ typedef struct pipe_tag {
|
||||
* specified pipe stage. Threads use this to pass
|
||||
* along the modified data item.
|
||||
*/
|
||||
int pipe_send (stage_t *stage, long data)
|
||||
int
|
||||
pipe_send(stage_t* stage, long data)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -81,7 +82,8 @@ int pipe_send (stage_t *stage, long data)
|
||||
* caller or the previous stage, modify the data
|
||||
* 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* next_stage = stage->next;
|
||||
@@ -116,7 +118,8 @@ void *pipe_stage (void *arg)
|
||||
* data is initialized and the threads created. They'll
|
||||
* wait for data.
|
||||
*/
|
||||
int pipe_create (pipe_t *pipe, int stages)
|
||||
int
|
||||
pipe_create(pipe_t* pipe, int stages)
|
||||
{
|
||||
int pipe_index;
|
||||
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
|
||||
* abort.
|
||||
*/
|
||||
for ( stage = pipe->head;
|
||||
stage->next != NULL;
|
||||
stage = stage->next) {
|
||||
status = pthread_create (
|
||||
&stage->thread, NULL, pipe_stage, (void*)stage);
|
||||
for (stage = pipe->head; stage->next != NULL; stage = stage->next) {
|
||||
status = pthread_create(&stage->thread, NULL, pipe_stage, (void*) stage);
|
||||
if (status != 0)
|
||||
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,
|
||||
* until the result is collected).
|
||||
*/
|
||||
int pipe_start (pipe_t *pipe, long value)
|
||||
int
|
||||
pipe_start(pipe_t* pipe, long value)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -200,7 +201,8 @@ int pipe_start (pipe_t *pipe, long value)
|
||||
* Collect the result of the pipeline. Wait for a
|
||||
* 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;
|
||||
long value;
|
||||
@@ -222,8 +224,7 @@ int pipe_result (pipe_t *pipe, long *result)
|
||||
return 0;
|
||||
|
||||
pthread_mutex_lock(&tail->mutex);
|
||||
while (!tail->data_ready)
|
||||
pthread_cond_wait (&tail->avail, &tail->mutex);
|
||||
while (!tail->data_ready) pthread_cond_wait(&tail->avail, &tail->mutex);
|
||||
*result = tail->data;
|
||||
tail->data_ready = 0;
|
||||
pthread_cond_signal(&tail->ready);
|
||||
@@ -234,7 +235,8 @@ int pipe_result (pipe_t *pipe, long *result)
|
||||
/*
|
||||
* The main program to "drive" the pipeline...
|
||||
*/
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pipe_t my_pipe;
|
||||
long value, result;
|
||||
@@ -246,14 +248,17 @@ int main (int argc, char *argv[])
|
||||
|
||||
while (1) {
|
||||
printf("Data> ");
|
||||
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
|
||||
if (strlen (line) <= 1) continue;
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
if (strlen(line) <= 2 && line[0] == '=') {
|
||||
if (pipe_result(&my_pipe, &result))
|
||||
printf("Result is %ld\n", result);
|
||||
else
|
||||
printf("Pipe is empty\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (sscanf(line, "%ld", &value) < 1)
|
||||
fprintf(stderr, "Enter an integer value\n");
|
||||
else
|
||||
|
||||
@@ -50,11 +50,14 @@ using pipe_t = pipe_tag;
|
||||
* specified pipe stage. Threads use this to pass
|
||||
* along the modified data item.
|
||||
*/
|
||||
int pipe_send(stage_t &stage, long data) {
|
||||
int
|
||||
pipe_send(stage_t& stage, long data)
|
||||
{
|
||||
int status;
|
||||
|
||||
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
|
||||
@@ -90,18 +93,22 @@ int pipe_send(stage_t &stage, long data) {
|
||||
* caller or the previous stage, modify the data
|
||||
* 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& nextStage = *stage.next;
|
||||
int status;
|
||||
|
||||
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 (!stage.isDataAvail) {
|
||||
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);
|
||||
@@ -109,7 +116,8 @@ void *pipe_stage(void *arg) {
|
||||
stage.isDataAvail = false;
|
||||
|
||||
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
|
||||
* 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);
|
||||
if (status != 0) err_abort(status, "Init pipe mutex");
|
||||
if (status != 0)
|
||||
err_abort(status, "Init pipe mutex");
|
||||
|
||||
pipe.stageList.resize(nStages);
|
||||
pipe.nActive = 0;
|
||||
|
||||
for (auto& iStage : pipe.stageList) {
|
||||
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);
|
||||
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);
|
||||
if (status != 0) err_abort(status, "Init threadIsIdle condition");
|
||||
if (status != 0)
|
||||
err_abort(status, "Init threadIsIdle condition");
|
||||
iStage.isDataAvail = false;
|
||||
}
|
||||
|
||||
@@ -162,7 +176,8 @@ int pipe_create(pipe_t &pipe, size_t nStages) {
|
||||
iit->next = &(*it);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -171,11 +186,14 @@ int pipe_create(pipe_t &pipe, size_t nStages) {
|
||||
* Collect the result of the pipeline. Wait for a
|
||||
* result if the pipeline hasn't produced one.
|
||||
*/
|
||||
int pipe_result(pipe_t &pipe) {
|
||||
int
|
||||
pipe_result(pipe_t& pipe)
|
||||
{
|
||||
int status;
|
||||
|
||||
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;
|
||||
if (pipe.nActive <= 0)
|
||||
@@ -184,7 +202,8 @@ int pipe_result(pipe_t &pipe) {
|
||||
pipe.nActive--;
|
||||
|
||||
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) {
|
||||
printf("Pipe is empty\n");
|
||||
@@ -194,7 +213,8 @@ int pipe_result(pipe_t &pipe) {
|
||||
auto& tail = pipe.stageList.back();
|
||||
|
||||
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) {
|
||||
pthread_cond_wait(&tail.dataIsAvail, &tail.mutex);
|
||||
@@ -204,10 +224,12 @@ int pipe_result(pipe_t &pipe) {
|
||||
tail.isDataAvail = false;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
@@ -222,9 +244,12 @@ int pipe_result(pipe_t &pipe) {
|
||||
* (note that the pipe will stall when each stage fills,
|
||||
* 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);
|
||||
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) {
|
||||
status = pthread_mutex_unlock(&pipe.mutex);
|
||||
@@ -235,7 +260,8 @@ void pipe_start(pipe_t &pipe, long value) {
|
||||
pipe.nActive++;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -243,7 +269,9 @@ void pipe_start(pipe_t &pipe, long value) {
|
||||
/*
|
||||
* The main program to "drive" the pipeline...
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pipe_t my_pipe;
|
||||
pipe_create(my_pipe, 2);
|
||||
|
||||
@@ -252,12 +280,15 @@ int main(int argc, char *argv[]) {
|
||||
char line[128];
|
||||
while (1) {
|
||||
printf("Data> ");
|
||||
if (fgets(line, sizeof(line), stdin) == NULL) exit(0);
|
||||
if (fgets(line, sizeof(line), stdin) == NULL)
|
||||
exit(0);
|
||||
printf(line);
|
||||
if (strlen(line) <= 1) continue;
|
||||
if (strlen(line) <= 1)
|
||||
continue;
|
||||
if (strlen(line) <= 2 && line[0] == '=') {
|
||||
pipe_result(my_pipe);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
long value;
|
||||
if (sscanf(line, "%ld", &value) < 1)
|
||||
fprintf(stderr, "Enter an integer value\n");
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* to allow interleaved thread execution, since threads are not
|
||||
* timesliced.
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include "errors.h"
|
||||
|
||||
#define CLIENT_THREADS 4 /* Number of clients */
|
||||
@@ -42,8 +42,7 @@ typedef struct tty_server_tag {
|
||||
} tty_server_t;
|
||||
|
||||
tty_server_t tty_server = {
|
||||
NULL, NULL, 0,
|
||||
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
|
||||
NULL, NULL, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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;
|
||||
request_t* request;
|
||||
@@ -78,8 +78,7 @@ void *tty_server_routine (void *arg)
|
||||
* Wait for data
|
||||
*/
|
||||
while (tty_server.first == NULL) {
|
||||
status = pthread_cond_wait (
|
||||
&tty_server.request, &tty_server.mutex);
|
||||
status = pthread_cond_wait(&tty_server.request, &tty_server.mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "Wait for request");
|
||||
}
|
||||
@@ -130,7 +129,8 @@ void *tty_server_routine (void *arg)
|
||||
status = pthread_mutex_unlock(&tty_server.mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "Unlock server mutex");
|
||||
} else
|
||||
}
|
||||
else
|
||||
free(request);
|
||||
if (operation == REQ_QUIT)
|
||||
break;
|
||||
@@ -141,11 +141,8 @@ void *tty_server_routine (void *arg)
|
||||
/*
|
||||
* Request an operation
|
||||
*/
|
||||
void tty_server_request (
|
||||
int operation,
|
||||
int sync,
|
||||
const char *prompt,
|
||||
char *string)
|
||||
void
|
||||
tty_server_request(int operation, int sync, const char* prompt, char* string)
|
||||
{
|
||||
request_t* request;
|
||||
int status;
|
||||
@@ -160,13 +157,12 @@ void tty_server_request (
|
||||
status = pthread_attr_init(&detached_attr);
|
||||
if (status != 0)
|
||||
err_abort(status, "Init attributes object");
|
||||
status = pthread_attr_setdetachstate (
|
||||
&detached_attr, PTHREAD_CREATE_DETACHED);
|
||||
status =
|
||||
pthread_attr_setdetachstate(&detached_attr, PTHREAD_CREATE_DETACHED);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set detach state");
|
||||
tty_server.running = 1;
|
||||
status = pthread_create (&thread, &detached_attr,
|
||||
tty_server_routine, NULL);
|
||||
status = pthread_create(&thread, &detached_attr, tty_server_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create server");
|
||||
|
||||
@@ -210,7 +206,8 @@ void tty_server_request (
|
||||
if (tty_server.first == NULL) {
|
||||
tty_server.first = request;
|
||||
tty_server.last = request;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
(tty_server.last)->next = request;
|
||||
tty_server.last = request;
|
||||
}
|
||||
@@ -227,8 +224,7 @@ void tty_server_request (
|
||||
*/
|
||||
if (sync) {
|
||||
while (!request->done_flag) {
|
||||
status = pthread_cond_wait (
|
||||
&request->done, &tty_server.mutex);
|
||||
status = pthread_cond_wait(&request->done, &tty_server.mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "Wait for sync request");
|
||||
}
|
||||
@@ -251,7 +247,8 @@ void tty_server_request (
|
||||
/*
|
||||
* Client routine -- multiple copies will request server.
|
||||
*/
|
||||
void *client_routine (void *arg)
|
||||
void*
|
||||
client_routine(void* arg)
|
||||
{
|
||||
int my_number = (int) arg, loops;
|
||||
char prompt[32];
|
||||
@@ -264,8 +261,7 @@ void *client_routine (void *arg)
|
||||
if (strlen(string) == 0)
|
||||
break;
|
||||
for (loops = 0; loops < 4; loops++) {
|
||||
sprintf (
|
||||
formatted, "(%d#%d) %s", my_number, loops, string);
|
||||
sprintf(formatted, "(%d#%d) %s", my_number, loops, string);
|
||||
tty_server_request(REQ_WRITE, 0, NULL, formatted);
|
||||
sleep(1);
|
||||
}
|
||||
@@ -285,7 +281,8 @@ void *client_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread;
|
||||
int count;
|
||||
@@ -306,8 +303,7 @@ int main (int argc, char *argv[])
|
||||
*/
|
||||
client_threads = CLIENT_THREADS;
|
||||
for (count = 0; count < client_threads; count++) {
|
||||
status = pthread_create (&thread, NULL,
|
||||
client_routine, (void*)count);
|
||||
status = pthread_create(&thread, NULL, client_routine, (void*) count);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create client thread");
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ static int counter;
|
||||
* when it calls pthread_testcancel, which it does each 1000
|
||||
* iterations.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
DPRINTF(("thread_routine starting\n"));
|
||||
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;
|
||||
void* result;
|
||||
@@ -43,8 +45,7 @@ int main (int argc, char *argv[])
|
||||
DPRINTF(("Setting concurrency level to 2\n"));
|
||||
thr_setconcurrency(2);
|
||||
#endif
|
||||
status = pthread_create (
|
||||
&thread_id, NULL, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id, NULL, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
sleep(2);
|
||||
|
||||
@@ -18,7 +18,8 @@ static int matrixb[SIZE][SIZE];
|
||||
static int matrixc[SIZE][SIZE];
|
||||
|
||||
#ifdef DEBUG
|
||||
void print_array (int matrix[SIZE][SIZE])
|
||||
void
|
||||
print_array(int matrix[SIZE][SIZE])
|
||||
{
|
||||
int i, j;
|
||||
int first;
|
||||
@@ -34,7 +35,6 @@ void print_array (int matrix[SIZE][SIZE])
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,8 @@ void print_array (int matrix[SIZE][SIZE])
|
||||
* is enabled. The loop multiplies the two matrices matrixa
|
||||
* and matrixb.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
int cancel_type, status;
|
||||
int i, j, k, value = 1;
|
||||
@@ -62,9 +63,7 @@ void *thread_routine (void *arg)
|
||||
/*
|
||||
* Compute the matrix product of matrixa and matrixb.
|
||||
*/
|
||||
status = pthread_setcanceltype (
|
||||
PTHREAD_CANCEL_ASYNCHRONOUS,
|
||||
&cancel_type);
|
||||
status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &cancel_type);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set cancel type");
|
||||
for (i = 0; i < SIZE; i++)
|
||||
@@ -73,9 +72,7 @@ void *thread_routine (void *arg)
|
||||
for (k = 0; k < SIZE; k++)
|
||||
matrixc[i][j] += matrixa[i][k] * matrixb[k][j];
|
||||
}
|
||||
status = pthread_setcanceltype (
|
||||
cancel_type,
|
||||
&cancel_type);
|
||||
status = pthread_setcanceltype(cancel_type, &cancel_type);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set cancel type");
|
||||
|
||||
@@ -83,12 +80,12 @@ void *thread_routine (void *arg)
|
||||
* Copy the result (matrixc) into matrixa to start again
|
||||
*/
|
||||
for (i = 0; i < SIZE; i++)
|
||||
for (j = 0; j < SIZE; j++)
|
||||
matrixa[i][j] = matrixc[i][j];
|
||||
for (j = 0; j < SIZE; j++) matrixa[i][j] = matrixc[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
void* result;
|
||||
@@ -103,8 +100,7 @@ int main (int argc, char *argv[])
|
||||
DPRINTF(("Setting concurrency level to 2\n"));
|
||||
thr_setconcurrency(2);
|
||||
#endif
|
||||
status = pthread_create (
|
||||
&thread_id, NULL, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id, NULL, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
sleep(1);
|
||||
|
||||
@@ -19,15 +19,15 @@ typedef struct control_tag {
|
||||
pthread_cond_t cv;
|
||||
} control_t;
|
||||
|
||||
control_t control =
|
||||
{0, 1, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
|
||||
control_t control = {0, 1, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
|
||||
|
||||
/*
|
||||
* This routine is installed as the cancellation cleanup
|
||||
* handler around the cancellable condition wait. It will
|
||||
* 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;
|
||||
int status;
|
||||
@@ -46,7 +46,8 @@ void cleanup_handler (void *arg)
|
||||
* nonzero value to pthread_cleanup_pop to run the same
|
||||
* "finalization" action when cancellation does not occur.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -67,7 +68,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id[THREADS];
|
||||
int count;
|
||||
@@ -75,8 +77,7 @@ int main (int argc, char *argv[])
|
||||
int status;
|
||||
|
||||
for (count = 0; count < THREADS; count++) {
|
||||
status = pthread_create (
|
||||
&thread_id[count], NULL, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id[count], NULL, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ static int counter;
|
||||
/*
|
||||
* Thread start routine.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
int state;
|
||||
int status;
|
||||
|
||||
for (counter = 0;; counter++) {
|
||||
|
||||
/*
|
||||
* Each 755 iterations, disable cancellation and sleep
|
||||
* for one second.
|
||||
@@ -27,29 +27,27 @@ void *thread_routine (void *arg)
|
||||
* calling pthread_testcancel().
|
||||
*/
|
||||
if ((counter % 755) == 0) {
|
||||
status = pthread_setcancelstate (
|
||||
PTHREAD_CANCEL_DISABLE, &state);
|
||||
status = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||||
if (status != 0)
|
||||
err_abort(status, "Disable cancel");
|
||||
sleep(1);
|
||||
status = pthread_setcancelstate (
|
||||
state, &state);
|
||||
status = pthread_setcancelstate(state, &state);
|
||||
if (status != 0)
|
||||
err_abort(status, "Restore cancel");
|
||||
} else
|
||||
if ((counter % 1000) == 0)
|
||||
}
|
||||
else if ((counter % 1000) == 0)
|
||||
pthread_testcancel();
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
void* result;
|
||||
int status;
|
||||
|
||||
status = pthread_create (
|
||||
&thread_id, NULL, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id, NULL, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
sleep(2);
|
||||
|
||||
@@ -26,7 +26,8 @@ typedef struct team_tag {
|
||||
* Start routine for worker threads. They loop waiting for a
|
||||
* cancellation request.
|
||||
*/
|
||||
void *worker_routine (void *arg)
|
||||
void*
|
||||
worker_routine(void* arg)
|
||||
{
|
||||
int counter;
|
||||
|
||||
@@ -39,7 +40,8 @@ void *worker_routine (void *arg)
|
||||
* Cancellation cleanup handler for the contractor thread. It
|
||||
* will cancel and detach each worker in the team.
|
||||
*/
|
||||
void cleanup (void *arg)
|
||||
void
|
||||
cleanup(void* arg)
|
||||
{
|
||||
team_t* team = (team_t*) arg;
|
||||
int count, status;
|
||||
@@ -61,7 +63,8 @@ void cleanup (void *arg)
|
||||
* worker threads, and then joins with them. When cancelled, the
|
||||
* cleanup handler will cancel and detach the remaining threads.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
team_t team; /* team info */
|
||||
int count;
|
||||
@@ -69,8 +72,7 @@ void *thread_routine (void *arg)
|
||||
int status;
|
||||
|
||||
for (count = 0; count < THREADS; count++) {
|
||||
status = pthread_create (
|
||||
&team.workers[count], NULL, worker_routine, NULL);
|
||||
status = pthread_create(&team.workers[count], NULL, worker_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create worker");
|
||||
}
|
||||
@@ -86,7 +88,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
int status;
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
pthread_cond_t cond;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_condattr_t cond_attr;
|
||||
int status;
|
||||
@@ -22,8 +23,7 @@ int main (int argc, char *argv[])
|
||||
if (status != 0)
|
||||
err_abort(status, "Create attr");
|
||||
#ifdef _POSIX_THREAD_PROCESS_SHARED
|
||||
status = pthread_condattr_setpshared (
|
||||
&cond_attr, PTHREAD_PROCESS_PRIVATE);
|
||||
status = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_PRIVATE);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set pshared");
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_mutexattr_t mutex_attr;
|
||||
int status;
|
||||
@@ -23,8 +24,7 @@ int main (int argc, char *argv[])
|
||||
if (status != 0)
|
||||
err_abort(status, "Create attr");
|
||||
#ifdef _POSIX_THREAD_PROCESS_SHARED
|
||||
status = pthread_mutexattr_setpshared (
|
||||
&mutex_attr, PTHREAD_PROCESS_PRIVATE);
|
||||
status = pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_PRIVATE);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set pshared");
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,8 @@ pthread_mutex_t mutex;
|
||||
* with the same control structure are made during the course of
|
||||
* the program.
|
||||
*/
|
||||
void once_init_routine (void)
|
||||
void
|
||||
once_init_routine(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -28,7 +29,8 @@ void once_init_routine (void)
|
||||
/*
|
||||
* Thread start routine that calls pthread_once.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -45,7 +47,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
char *input, buffer[64];
|
||||
|
||||
@@ -9,16 +9,17 @@
|
||||
* _POSIX_THREAD_PRIORITY_SCHEDULING, it does not support the
|
||||
* SCHED_RR policy for threads.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include "errors.h"
|
||||
|
||||
/*
|
||||
* Thread start routine. If priority scheduling is supported,
|
||||
* report the thread's scheduling attributes.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
int my_policy;
|
||||
struct sched_param my_param;
|
||||
@@ -30,15 +31,15 @@ void *thread_routine (void *arg)
|
||||
* so just report that the thread ran, and exit.
|
||||
*/
|
||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined(sun)
|
||||
status = pthread_getschedparam (
|
||||
pthread_self (), &my_policy, &my_param);
|
||||
status = pthread_getschedparam(pthread_self(), &my_policy, &my_param);
|
||||
if (status != 0)
|
||||
err_abort(status, "Get sched");
|
||||
printf("thread_routine running at %s/%d\n",
|
||||
(my_policy == SCHED_FIFO ? "FIFO"
|
||||
: (my_policy == SCHED_RR ? "RR"
|
||||
: (my_policy == SCHED_OTHER ? "OTHER"
|
||||
: "unknown"))),
|
||||
(my_policy == SCHED_FIFO
|
||||
? "FIFO"
|
||||
: (my_policy == SCHED_RR
|
||||
? "RR"
|
||||
: (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))),
|
||||
my_param.sched_priority);
|
||||
#else
|
||||
printf("thread_routine running\n");
|
||||
@@ -46,7 +47,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
pthread_attr_t thread_attr;
|
||||
@@ -67,24 +69,21 @@ int main (int argc, char *argv[])
|
||||
* thread.
|
||||
*/
|
||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined(sun)
|
||||
status = pthread_attr_getschedpolicy (
|
||||
&thread_attr, &thread_policy);
|
||||
status = pthread_attr_getschedpolicy(&thread_attr, &thread_policy);
|
||||
if (status != 0)
|
||||
err_abort(status, "Get policy");
|
||||
status = pthread_attr_getschedparam (
|
||||
&thread_attr, &thread_param);
|
||||
status = pthread_attr_getschedparam(&thread_attr, &thread_param);
|
||||
if (status != 0)
|
||||
err_abort(status, "Get sched param");
|
||||
printf (
|
||||
"Default policy is %s, priority is %d\n",
|
||||
(thread_policy == SCHED_FIFO ? "FIFO"
|
||||
: (thread_policy == SCHED_RR ? "RR"
|
||||
: (thread_policy == SCHED_OTHER ? "OTHER"
|
||||
: "unknown"))),
|
||||
printf("Default policy is %s, priority is %d\n",
|
||||
(thread_policy == SCHED_FIFO
|
||||
? "FIFO"
|
||||
: (thread_policy == SCHED_RR
|
||||
? "RR"
|
||||
: (thread_policy == SCHED_OTHER ? "OTHER" : "unknown"))),
|
||||
thread_param.sched_priority);
|
||||
|
||||
status = pthread_attr_setschedpolicy (
|
||||
&thread_attr, SCHED_RR);
|
||||
status = pthread_attr_setschedpolicy(&thread_attr, SCHED_RR);
|
||||
if (status != 0)
|
||||
printf("Unable to set SCHED_RR policy.\n");
|
||||
else {
|
||||
@@ -105,30 +104,23 @@ int main (int argc, char *argv[])
|
||||
rr_max_priority = sched_get_priority_max(SCHED_RR);
|
||||
if (rr_max_priority == -1)
|
||||
errno_abort("Get SCHED_RR max priority");
|
||||
thread_param.sched_priority =
|
||||
(rr_min_priority + rr_max_priority)/2;
|
||||
printf (
|
||||
"SCHED_RR priority range is %d to %d: using %d\n",
|
||||
thread_param.sched_priority = (rr_min_priority + rr_max_priority) / 2;
|
||||
printf("SCHED_RR priority range is %d to %d: using %d\n",
|
||||
rr_min_priority,
|
||||
rr_max_priority,
|
||||
thread_param.sched_priority);
|
||||
status = pthread_attr_setschedparam (
|
||||
&thread_attr, &thread_param);
|
||||
status = pthread_attr_setschedparam(&thread_attr, &thread_param);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set params");
|
||||
printf (
|
||||
"Creating thread at RR/%d\n",
|
||||
thread_param.sched_priority);
|
||||
status = pthread_attr_setinheritsched (
|
||||
&thread_attr, PTHREAD_EXPLICIT_SCHED);
|
||||
printf("Creating thread at RR/%d\n", thread_param.sched_priority);
|
||||
status = pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set inherit");
|
||||
}
|
||||
#else
|
||||
printf("Priority scheduling not supported\n");
|
||||
#endif
|
||||
status = pthread_create (
|
||||
&thread_id, &thread_attr, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id, &thread_attr, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
status = pthread_join(thread_id, NULL);
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
* Special note: This demonstration will fail on Solaris 2.5
|
||||
* because it does not implement SCHED_RR.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include "errors.h"
|
||||
|
||||
#define THREADS 5
|
||||
@@ -27,7 +27,8 @@ int rr_min_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;
|
||||
int my_policy;
|
||||
@@ -35,28 +36,28 @@ void *thread_routine (void *arg)
|
||||
int status;
|
||||
|
||||
my_param.sched_priority = rr_min_priority + self->index;
|
||||
DPRINTF ((
|
||||
"Thread %d will set SCHED_FIFO, priority %d\n",
|
||||
self->index, my_param.sched_priority));
|
||||
status = pthread_setschedparam (
|
||||
self->id, SCHED_RR, &my_param);
|
||||
DPRINTF(("Thread %d will set SCHED_FIFO, priority %d\n",
|
||||
self->index,
|
||||
my_param.sched_priority));
|
||||
status = pthread_setschedparam(self->id, SCHED_RR, &my_param);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set sched");
|
||||
status = pthread_getschedparam (
|
||||
self->id, &my_policy, &my_param);
|
||||
status = pthread_getschedparam(self->id, &my_policy, &my_param);
|
||||
if (status != 0)
|
||||
err_abort(status, "Get sched");
|
||||
printf("thread_routine %d running at %s/%d\n",
|
||||
self->index,
|
||||
(my_policy == SCHED_FIFO ? "FIFO"
|
||||
: (my_policy == SCHED_RR ? "RR"
|
||||
: (my_policy == SCHED_OTHER ? "OTHER"
|
||||
: "unknown"))),
|
||||
(my_policy == SCHED_FIFO
|
||||
? "FIFO"
|
||||
: (my_policy == SCHED_RR
|
||||
? "RR"
|
||||
: (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))),
|
||||
my_param.sched_priority);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int count, status;
|
||||
|
||||
@@ -73,8 +74,7 @@ int main (int argc, char *argv[])
|
||||
for (count = 0; count < THREADS; count++) {
|
||||
threads[count].index = count;
|
||||
status = pthread_create(
|
||||
&threads[count].id, NULL,
|
||||
thread_routine, (void*)&threads[count]);
|
||||
&threads[count].id, NULL, thread_routine, (void*) &threads[count]);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
/*
|
||||
* 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");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
pthread_attr_t thread_attr;
|
||||
@@ -35,8 +37,7 @@ int main (int argc, char *argv[])
|
||||
/*
|
||||
* Create a detached thread.
|
||||
*/
|
||||
status = pthread_attr_setdetachstate (
|
||||
&thread_attr, PTHREAD_CREATE_DETACHED);
|
||||
status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set detach");
|
||||
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
|
||||
@@ -53,14 +54,13 @@ int main (int argc, char *argv[])
|
||||
if (status != 0)
|
||||
err_abort(status, "Get stack size");
|
||||
printf("Default stack size is %u; minimum is %u\n",
|
||||
stack_size, PTHREAD_STACK_MIN);
|
||||
status = pthread_attr_setstacksize (
|
||||
&thread_attr, PTHREAD_STACK_MIN*2);
|
||||
stack_size,
|
||||
PTHREAD_STACK_MIN);
|
||||
status = pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN * 2);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set stack size");
|
||||
#endif
|
||||
status = pthread_create (
|
||||
&thread_id, &thread_attr, thread_routine, NULL);
|
||||
status = pthread_create(&thread_id, &thread_attr, thread_routine, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
printf("Main exiting\n");
|
||||
|
||||
@@ -24,7 +24,8 @@ long identity_key_counter = 0;
|
||||
* threads still have values, and deletes the key when there are
|
||||
* no more references.
|
||||
*/
|
||||
void identity_key_destructor (void *value)
|
||||
void
|
||||
identity_key_destructor(void* value)
|
||||
{
|
||||
private_t* private = (private_t*) value;
|
||||
int status;
|
||||
@@ -50,7 +51,8 @@ void identity_key_destructor (void *value)
|
||||
* Helper routine to allocate a new value for thread-specific
|
||||
* data key if the thread doesn't already have one.
|
||||
*/
|
||||
void *identity_key_get (void)
|
||||
void*
|
||||
identity_key_get(void)
|
||||
{
|
||||
void* value;
|
||||
int status;
|
||||
@@ -70,7 +72,8 @@ void *identity_key_get (void)
|
||||
/*
|
||||
* Thread start routine to use thread-specific data.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
private_t* value;
|
||||
|
||||
@@ -82,7 +85,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void main (int argc, char *argv[])
|
||||
void
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_1, thread_2;
|
||||
private_t* value;
|
||||
@@ -106,12 +110,10 @@ void main (int argc, char *argv[])
|
||||
value = (private_t*) identity_key_get();
|
||||
value->thread_id = pthread_self();
|
||||
value->string = "Main thread";
|
||||
status = pthread_create (&thread_1, NULL,
|
||||
thread_routine, "Thread 1");
|
||||
status = pthread_create(&thread_1, NULL, thread_routine, "Thread 1");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread 1");
|
||||
status = pthread_create (&thread_2, NULL,
|
||||
thread_routine, "Thread 2");
|
||||
status = pthread_create(&thread_2, NULL, thread_routine, "Thread 2");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread 2");
|
||||
pthread_exit(NULL);
|
||||
|
||||
@@ -25,7 +25,8 @@ pthread_once_t key_once = PTHREAD_ONCE_INIT;
|
||||
* One-time initialization routine used with the pthread_once
|
||||
* control block.
|
||||
*/
|
||||
void once_routine (void)
|
||||
void
|
||||
once_routine(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -39,7 +40,8 @@ void once_routine (void)
|
||||
* Thread start routine that uses pthread_once to dynamically
|
||||
* create a thread-specific data key.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
tsd_t* value;
|
||||
int status;
|
||||
@@ -64,17 +66,16 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void main (int argc, char *argv[])
|
||||
void
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread1, thread2;
|
||||
int status;
|
||||
|
||||
status = pthread_create (
|
||||
&thread1, NULL, thread_routine, "thread 1");
|
||||
status = pthread_create(&thread1, NULL, thread_routine, "thread 1");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread 1");
|
||||
status = pthread_create (
|
||||
&thread2, NULL, thread_routine, "thread 2");
|
||||
status = pthread_create(&thread2, NULL, thread_routine, "thread 2");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread 2");
|
||||
pthread_exit(NULL);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Demonstrate the use of "fork handlers" to protect data
|
||||
* invariants across a fork.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.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,
|
||||
* within the parent process.
|
||||
*/
|
||||
void fork_prepare (void)
|
||||
void
|
||||
fork_prepare(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -34,7 +35,8 @@ void fork_prepare (void)
|
||||
* This routine will be called after executing the fork, within
|
||||
* the parent process
|
||||
*/
|
||||
void fork_parent (void)
|
||||
void
|
||||
fork_parent(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -50,7 +52,8 @@ void fork_parent (void)
|
||||
* This routine will be called after executing the fork, within
|
||||
* the child process
|
||||
*/
|
||||
void fork_child (void)
|
||||
void
|
||||
fork_child(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -67,7 +70,8 @@ void fork_child (void)
|
||||
/*
|
||||
* Thread start routine, which will fork a new child process.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
pid_t child_pid;
|
||||
int status;
|
||||
@@ -95,7 +99,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t fork_thread;
|
||||
int atfork_flag = 1;
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* is prevented by the file locks until both prompt and fgets are
|
||||
* complete.
|
||||
*/
|
||||
void *prompt_routine (void *arg)
|
||||
void*
|
||||
prompt_routine(void* arg)
|
||||
{
|
||||
char* prompt = (char*) arg;
|
||||
char* string;
|
||||
@@ -38,7 +39,8 @@ void *prompt_routine (void *arg)
|
||||
return (void*) string;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread1, thread2, thread3;
|
||||
char* string;
|
||||
@@ -53,16 +55,13 @@ int main (int argc, char *argv[])
|
||||
DPRINTF(("Setting concurrency level to 4\n"));
|
||||
thr_setconcurrency(4);
|
||||
#endif
|
||||
status = pthread_create (
|
||||
&thread1, NULL, prompt_routine, "Thread 1> ");
|
||||
status = pthread_create(&thread1, NULL, prompt_routine, "Thread 1> ");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
status = pthread_create (
|
||||
&thread2, NULL, prompt_routine, "Thread 2> ");
|
||||
status = pthread_create(&thread2, NULL, prompt_routine, "Thread 2> ");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
status = pthread_create (
|
||||
&thread3, NULL, prompt_routine, "Thread 3> ");
|
||||
status = pthread_create(&thread3, NULL, prompt_routine, "Thread 3> ");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
status = pthread_join(thread1, (void**) &string);
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#define LOGIN_NAME_MAX 32
|
||||
#endif
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
char login_str[LOGIN_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));
|
||||
if (status != 0)
|
||||
err_abort(status, "Get stdin");
|
||||
printf ("User: %s, cterm: %s, fd 0: %s\n",
|
||||
login_str, cterm_str, stdin_str);
|
||||
printf("User: %s, cterm: %s, fd 0: %s\n", login_str, cterm_str, stdin_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
* by locking the file stream and using putchar_unlocked to
|
||||
* write each character individually.
|
||||
*/
|
||||
void *lock_routine (void *arg)
|
||||
void*
|
||||
lock_routine(void* arg)
|
||||
{
|
||||
char* pointer;
|
||||
|
||||
@@ -56,7 +57,8 @@ void *lock_routine (void *arg)
|
||||
* Although the internal locking of putchar prevents file stream
|
||||
* corruption, the writes of various threads may be interleaved.
|
||||
*/
|
||||
void *unlock_routine (void *arg)
|
||||
void*
|
||||
unlock_routine(void* arg)
|
||||
{
|
||||
char* pointer;
|
||||
|
||||
@@ -67,7 +69,8 @@ void *unlock_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread1, thread2, thread3;
|
||||
int flock_flag = 1;
|
||||
@@ -80,16 +83,13 @@ int main (int argc, char *argv[])
|
||||
thread_func = lock_routine;
|
||||
else
|
||||
thread_func = unlock_routine;
|
||||
status = pthread_create (
|
||||
&thread1, NULL, thread_func, "this is thread 1\n");
|
||||
status = pthread_create(&thread1, NULL, thread_func, "this is thread 1\n");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
status = pthread_create (
|
||||
&thread2, NULL, thread_func, "this is thread 2\n");
|
||||
status = pthread_create(&thread2, NULL, thread_func, "this is thread 2\n");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
status = pthread_create (
|
||||
&thread3, NULL, thread_func, "this is thread 3\n");
|
||||
status = pthread_create(&thread3, NULL, thread_func, "this is thread 3\n");
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
pthread_exit(NULL);
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
* and _POSIX_SEMAPHORES features of POSIX 1003.1b-1993. It will
|
||||
* not run (and may not compile) without them.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "errors.h"
|
||||
|
||||
sem_t semaphore;
|
||||
@@ -21,7 +21,8 @@ sem_t semaphore;
|
||||
/*
|
||||
* Signal catching function.
|
||||
*/
|
||||
void signal_catcher (int sig)
|
||||
void
|
||||
signal_catcher(int sig)
|
||||
{
|
||||
if (sem_post(&semaphore) == -1)
|
||||
errno_abort("Post semaphore");
|
||||
@@ -30,7 +31,8 @@ void signal_catcher (int sig)
|
||||
/*
|
||||
* Thread start routine which waits on the semaphore.
|
||||
*/
|
||||
void *sem_waiter (void *arg)
|
||||
void*
|
||||
sem_waiter(void* arg)
|
||||
{
|
||||
int number = (int) arg;
|
||||
int counter;
|
||||
@@ -48,7 +50,8 @@ void *sem_waiter (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int thread_count, status;
|
||||
struct sigevent sig_event;
|
||||
@@ -74,8 +77,7 @@ int main (int argc, char *argv[])
|
||||
*/
|
||||
for (thread_count = 0; thread_count < 5; thread_count++) {
|
||||
status = pthread_create(
|
||||
&sem_waiters[thread_count], NULL,
|
||||
sem_waiter, (void*)thread_count);
|
||||
&sem_waiters[thread_count], NULL, sem_waiter, (void*) thread_count);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
*
|
||||
* Demonstrate use of semaphores for synchronization.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "errors.h"
|
||||
|
||||
sem_t semaphore;
|
||||
@@ -15,7 +15,8 @@ sem_t semaphore;
|
||||
/*
|
||||
* Thread start routine to wait on a semaphore.
|
||||
*/
|
||||
void *sem_waiter (void *arg)
|
||||
void*
|
||||
sem_waiter(void* arg)
|
||||
{
|
||||
long num = (long) arg;
|
||||
|
||||
@@ -26,7 +27,8 @@ void *sem_waiter (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int thread_count;
|
||||
pthread_t sem_waiters[5];
|
||||
@@ -45,8 +47,7 @@ int main (int argc, char *argv[])
|
||||
*/
|
||||
for (thread_count = 0; thread_count < 5; thread_count++) {
|
||||
status = pthread_create(
|
||||
&sem_waiters[thread_count], NULL,
|
||||
sem_waiter, (void*)thread_count);
|
||||
&sem_waiters[thread_count], NULL, sem_waiter, (void*) thread_count);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ main()
|
||||
struct sigevent se;
|
||||
|
||||
#ifdef sun
|
||||
fprintf (
|
||||
stderr,
|
||||
fprintf(stderr,
|
||||
"This program cannot compile on Solaris 2.5.\n"
|
||||
"To build and run on Solaris 2.6, remove the\n"
|
||||
"\"#ifdef sun\" block in main().\n");
|
||||
@@ -83,8 +82,7 @@ main()
|
||||
if (status == -1)
|
||||
errno_abort("Create timer");
|
||||
|
||||
DPRINTF ((
|
||||
"Setting timer %d for 5-second expiration...\n", timer_id));
|
||||
DPRINTF(("Setting timer %d for 5-second expiration...\n", timer_id));
|
||||
status = timer_settime(timer_id, 0, &ts, 0);
|
||||
if (status == -1)
|
||||
errno_abort("Set timer");
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
* Demonstrate use of sigwait() to synchronously handle
|
||||
* asynchrnous signals within a threaded program.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "errors.h"
|
||||
|
||||
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
|
||||
* signal a condition variable. The main thread will exit.
|
||||
*/
|
||||
void *signal_waiter (void *arg)
|
||||
void*
|
||||
signal_waiter(void* arg)
|
||||
{
|
||||
int sig_number;
|
||||
int signal_count = 0;
|
||||
@@ -48,7 +49,8 @@ void *signal_waiter (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t signal_thread_id;
|
||||
int status;
|
||||
@@ -73,8 +75,7 @@ int main (int argc, char *argv[])
|
||||
/*
|
||||
* Create the sigwait thread.
|
||||
*/
|
||||
status = pthread_create (&signal_thread_id, NULL,
|
||||
signal_waiter, NULL);
|
||||
status = pthread_create(&signal_thread_id, NULL, signal_waiter, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create sigwaiter");
|
||||
|
||||
|
||||
@@ -161,12 +161,10 @@ thd_suspend (pthread_t target_thread)
|
||||
* the end, realloc the array for more space.
|
||||
*/
|
||||
i = 0;
|
||||
while (array[i] != 0)
|
||||
i++;
|
||||
while (array[i] != 0) i++;
|
||||
|
||||
if (i == bottom) {
|
||||
array = (pthread_t*) realloc (
|
||||
array, (++bottom * sizeof (pthread_t)));
|
||||
array = (pthread_t*) realloc(array, (++bottom * sizeof(pthread_t)));
|
||||
if (array == NULL) {
|
||||
pthread_mutex_unlock(&mut);
|
||||
return errno;
|
||||
@@ -188,8 +186,7 @@ thd_suspend (pthread_t target_thread)
|
||||
/*
|
||||
* Wait for the sentinel to change.
|
||||
*/
|
||||
while (sentinel == 0)
|
||||
sched_yield ();
|
||||
while (sentinel == 0) sched_yield();
|
||||
|
||||
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
|
||||
* we can just carry on.
|
||||
*/
|
||||
while (array[i] != target_thread && i < bottom)
|
||||
i++;
|
||||
while (array[i] != target_thread && i < bottom) i++;
|
||||
|
||||
if (i >= bottom) {
|
||||
pthread_mutex_unlock(&mut);
|
||||
@@ -266,9 +262,7 @@ thread_routine (void *arg)
|
||||
* a progress report.
|
||||
*/
|
||||
if (i % 2000 == 0) {
|
||||
sprintf (
|
||||
buffer, "Thread %02d: %d\n",
|
||||
number, i);
|
||||
sprintf(buffer, "Thread %02d: %d\n", number, i);
|
||||
write(1, buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
@@ -290,14 +284,12 @@ main (int argc, char *argv[])
|
||||
status = pthread_attr_init(&detach);
|
||||
if (status != 0)
|
||||
err_abort(status, "Init attributes object");
|
||||
status = pthread_attr_setdetachstate (
|
||||
&detach, PTHREAD_CREATE_DETACHED);
|
||||
status = pthread_attr_setdetachstate(&detach, PTHREAD_CREATE_DETACHED);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set create-detached");
|
||||
|
||||
for (i = 0; i < THREAD_COUNT; i++) {
|
||||
status = pthread_create (
|
||||
&threads[i], &detach, thread_routine, (void *)i);
|
||||
status = pthread_create(&threads[i], &detach, thread_routine, (void*) i);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
|
||||
@@ -20,14 +20,15 @@
|
||||
* to do something in a serial region before entering another
|
||||
* parallel section of code.
|
||||
*/
|
||||
#include "barrier.h"
|
||||
#include <pthread.h>
|
||||
#include "errors.h"
|
||||
#include "barrier.h"
|
||||
|
||||
/*
|
||||
* Initialize a barrier for use.
|
||||
*/
|
||||
int barrier_init (barrier_t *barrier, int count)
|
||||
int
|
||||
barrier_init(barrier_t* barrier, int count)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -48,7 +49,8 @@ int barrier_init (barrier_t *barrier, int count)
|
||||
/*
|
||||
* Destroy a barrier when done using it.
|
||||
*/
|
||||
int barrier_destroy (barrier_t *barrier)
|
||||
int
|
||||
barrier_destroy(barrier_t* barrier)
|
||||
{
|
||||
int status, status2;
|
||||
|
||||
@@ -87,7 +89,8 @@ int barrier_destroy (barrier_t *barrier)
|
||||
* the count (of remaining members) reaches 0, broadcast to wake
|
||||
* all threads waiting.
|
||||
*/
|
||||
int barrier_wait (barrier_t *barrier)
|
||||
int
|
||||
barrier_wait(barrier_t* barrier)
|
||||
{
|
||||
int status, cancel, tmp, cycle;
|
||||
|
||||
@@ -111,7 +114,8 @@ int barrier_wait (barrier_t *barrier)
|
||||
*/
|
||||
if (status == 0)
|
||||
status = -1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Wait with cancellation disabled, because barrier_wait
|
||||
* should not be a cancellation point.
|
||||
@@ -124,9 +128,9 @@ int barrier_wait (barrier_t *barrier)
|
||||
* anymore.
|
||||
*/
|
||||
while (cycle == barrier->cycle) {
|
||||
status = pthread_cond_wait (
|
||||
&barrier->cv, &barrier->mutex);
|
||||
if (status != 0) break;
|
||||
status = pthread_cond_wait(&barrier->cv, &barrier->mutex);
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_setcancelstate(cancel, &tmp);
|
||||
|
||||
@@ -31,8 +31,10 @@ typedef struct barrier_tag {
|
||||
* Support static initialization of barriers
|
||||
*/
|
||||
#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
|
||||
|
||||
@@ -29,7 +29,8 @@ thread_t thread[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 */
|
||||
int in_loop, out_loop, count, status;
|
||||
@@ -69,7 +70,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int arg, char *argv[])
|
||||
int
|
||||
main(int arg, char* argv[])
|
||||
{
|
||||
int thread_count, array_count;
|
||||
int status;
|
||||
@@ -87,7 +89,9 @@ int main (int arg, char *argv[])
|
||||
thread[thread_count].array[array_count] = array_count + 1;
|
||||
|
||||
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)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
* lock. rwl_writetrylock() attempts to lock a read-write lock
|
||||
* for write access, and returns EBUSY instead of blocking.
|
||||
*/
|
||||
#include "rwlock.h"
|
||||
#include <pthread.h>
|
||||
#include "errors.h"
|
||||
#include "rwlock.h"
|
||||
|
||||
/*
|
||||
* Initialize a read-write lock
|
||||
*/
|
||||
int rwl_init (rwlock_t *rwl)
|
||||
int
|
||||
rwl_init(rwlock_t* rwl)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -58,7 +59,8 @@ int rwl_init (rwlock_t *rwl)
|
||||
/*
|
||||
* Destroy a read-write lock
|
||||
*/
|
||||
int rwl_destroy (rwlock_t *rwl)
|
||||
int
|
||||
rwl_destroy(rwlock_t* rwl)
|
||||
{
|
||||
int status, status1, status2;
|
||||
|
||||
@@ -103,7 +105,8 @@ int rwl_destroy (rwlock_t *rwl)
|
||||
* Simply record that the thread is no longer waiting,
|
||||
* and unlock the mutex.
|
||||
*/
|
||||
static void rwl_readcleanup (void *arg)
|
||||
static void
|
||||
rwl_readcleanup(void* 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.
|
||||
*/
|
||||
int rwl_readlock (rwlock_t *rwl)
|
||||
int
|
||||
rwl_readlock(rwlock_t* rwl)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -144,7 +148,8 @@ int rwl_readlock (rwlock_t *rwl)
|
||||
* Attempt to lock a read-write lock for read access (don't
|
||||
* block if unavailable).
|
||||
*/
|
||||
int rwl_readtrylock (rwlock_t *rwl)
|
||||
int
|
||||
rwl_readtrylock(rwlock_t* rwl)
|
||||
{
|
||||
int status, status2;
|
||||
|
||||
@@ -164,7 +169,8 @@ int rwl_readtrylock (rwlock_t *rwl)
|
||||
/*
|
||||
* Unlock a read-write lock from read access.
|
||||
*/
|
||||
int rwl_readunlock (rwlock_t *rwl)
|
||||
int
|
||||
rwl_readunlock(rwlock_t* rwl)
|
||||
{
|
||||
int status, status2;
|
||||
|
||||
@@ -187,7 +193,8 @@ int rwl_readunlock (rwlock_t *rwl)
|
||||
* Simply record that the thread is no longer waiting,
|
||||
* and unlock the mutex.
|
||||
*/
|
||||
static void rwl_writecleanup (void *arg)
|
||||
static void
|
||||
rwl_writecleanup(void* 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.
|
||||
*/
|
||||
int rwl_writelock (rwlock_t *rwl)
|
||||
int
|
||||
rwl_writelock(rwlock_t* rwl)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -228,7 +236,8 @@ int rwl_writelock (rwlock_t *rwl)
|
||||
* Attempt to lock a read-write lock for write access. Don't
|
||||
* block if unavailable.
|
||||
*/
|
||||
int rwl_writetrylock (rwlock_t *rwl)
|
||||
int
|
||||
rwl_writetrylock(rwlock_t* rwl)
|
||||
{
|
||||
int status, status2;
|
||||
|
||||
@@ -248,7 +257,8 @@ int rwl_writetrylock (rwlock_t *rwl)
|
||||
/*
|
||||
* Unlock a read-write lock from write access.
|
||||
*/
|
||||
int rwl_writeunlock (rwlock_t *rwl)
|
||||
int
|
||||
rwl_writeunlock(rwlock_t* rwl)
|
||||
{
|
||||
int status;
|
||||
|
||||
@@ -264,7 +274,8 @@ int rwl_writeunlock (rwlock_t *rwl)
|
||||
pthread_mutex_unlock(&rwl->mutex);
|
||||
return status;
|
||||
}
|
||||
} else if (rwl->w_wait > 0) {
|
||||
}
|
||||
else if (rwl->w_wait > 0) {
|
||||
status = pthread_cond_signal(&rwl->write);
|
||||
if (status != 0) {
|
||||
pthread_mutex_unlock(&rwl->mutex);
|
||||
|
||||
@@ -33,8 +33,10 @@ typedef struct rwlock_tag {
|
||||
* Support static initialization of barriers
|
||||
*/
|
||||
#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
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* to allow interleaved thread execution, since threads are not
|
||||
* timesliced.
|
||||
*/
|
||||
#include "rwlock.h"
|
||||
#include "errors.h"
|
||||
#include "rwlock.h"
|
||||
|
||||
#define THREADS 5
|
||||
#define DATASIZE 15
|
||||
@@ -41,7 +41,8 @@ data_t data[DATASIZE];
|
||||
/*
|
||||
* Thread start routine that uses read-write locks
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
thread_t* self = (thread_t*) arg;
|
||||
int repeats = 0;
|
||||
@@ -65,7 +66,8 @@ void *thread_routine (void *arg)
|
||||
status = rwl_writeunlock(&data[element].lock);
|
||||
if (status != 0)
|
||||
err_abort(status, "Write unlock");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Look at the current data element to see whether
|
||||
* the current thread last updated it. Count the
|
||||
@@ -87,13 +89,14 @@ void *thread_routine (void *arg)
|
||||
}
|
||||
|
||||
if (repeats > 0)
|
||||
printf (
|
||||
"Thread %d found unchanged elements %d times\n",
|
||||
self->thread_num, repeats);
|
||||
printf("Thread %d found unchanged elements %d times\n",
|
||||
self->thread_num,
|
||||
repeats);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int count;
|
||||
int data_count;
|
||||
@@ -132,7 +135,9 @@ int main (int argc, char *argv[])
|
||||
threads[count].reads = 0;
|
||||
threads[count].interval = rand_r(&seed) % 71;
|
||||
status = pthread_create(&threads[count].thread_id,
|
||||
NULL, thread_routine, (void*)&threads[count]);
|
||||
NULL,
|
||||
thread_routine,
|
||||
(void*) &threads[count]);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
@@ -147,8 +152,10 @@ int main (int argc, char *argv[])
|
||||
err_abort(status, "Join thread");
|
||||
thread_updates += threads[count].updates;
|
||||
printf("%02d: interval %d, updates %d, reads %d\n",
|
||||
count, threads[count].interval,
|
||||
threads[count].updates, threads[count].reads);
|
||||
count,
|
||||
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++) {
|
||||
data_updates += data[data_count].updates;
|
||||
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);
|
||||
}
|
||||
|
||||
printf ("%d thread updates, %d data updates\n",
|
||||
thread_updates, data_updates);
|
||||
printf("%d thread updates, %d data updates\n", thread_updates, data_updates);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* timesliced.
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include "rwlock.h"
|
||||
#include "errors.h"
|
||||
#include "rwlock.h"
|
||||
|
||||
#define THREADS 5
|
||||
#define ITERATIONS 1000
|
||||
@@ -42,7 +42,8 @@ data_t data[DATASIZE];
|
||||
/*
|
||||
* Thread start routine that uses read-write locks
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
thread_t* self = (thread_t*) arg;
|
||||
int iteration;
|
||||
@@ -61,19 +62,24 @@ void *thread_routine (void *arg)
|
||||
data[element].updates++;
|
||||
self->updates++;
|
||||
rwl_writeunlock(&data[element].lock);
|
||||
} else
|
||||
}
|
||||
else
|
||||
err_abort(status, "Try write lock");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
status = rwl_readtrylock(&data[element].lock);
|
||||
if (status == EBUSY)
|
||||
self->r_collisions++;
|
||||
else if (status != 0) {
|
||||
err_abort(status, "Try read lock");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (data[element].data != data[element].updates)
|
||||
printf("%d: data[%d] %d != %d\n",
|
||||
self->thread_num, element,
|
||||
data[element].data, data[element].updates);
|
||||
self->thread_num,
|
||||
element,
|
||||
data[element].data,
|
||||
data[element].updates);
|
||||
rwl_readunlock(&data[element].lock);
|
||||
}
|
||||
}
|
||||
@@ -85,7 +91,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int count, data_count;
|
||||
unsigned int seed = 1;
|
||||
@@ -121,7 +128,9 @@ int main (int argc, char *argv[])
|
||||
threads[count].updates = 0;
|
||||
threads[count].interval = rand_r(&seed) % ITERATIONS;
|
||||
status = pthread_create(&threads[count].thread_id,
|
||||
NULL, thread_routine, (void*)&threads[count]);
|
||||
NULL,
|
||||
thread_routine,
|
||||
(void*) &threads[count]);
|
||||
if (status != 0)
|
||||
err_abort(status, "Create thread");
|
||||
}
|
||||
@@ -135,11 +144,14 @@ int main (int argc, char *argv[])
|
||||
if (status != 0)
|
||||
err_abort(status, "Join thread");
|
||||
thread_updates += threads[count].updates;
|
||||
printf ("%02d: interval %d, updates %d, "
|
||||
printf(
|
||||
"%02d: interval %d, updates %d, "
|
||||
"r_collisions %d, w_collisions %d\n",
|
||||
count, threads[count].interval,
|
||||
count,
|
||||
threads[count].interval,
|
||||
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++) {
|
||||
data_updates += data[data_count].updates;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,16 +20,17 @@
|
||||
* processing threads will begin to shut down. (They will be
|
||||
* restarted when work appears.)
|
||||
*/
|
||||
#include "workq.h"
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "errors.h"
|
||||
#include "workq.h"
|
||||
|
||||
/*
|
||||
* Thread start routine to serve the work queue.
|
||||
*/
|
||||
static void *workq_server (void *arg)
|
||||
static void*
|
||||
workq_server(void* arg)
|
||||
{
|
||||
struct timespec timeout;
|
||||
workq_t* wq = (workq_t*) arg;
|
||||
@@ -59,13 +60,13 @@ static void *workq_server (void *arg)
|
||||
* Server threads time out after spending 2 seconds
|
||||
* waiting for new work, and exit.
|
||||
*/
|
||||
status = pthread_cond_timedwait (
|
||||
&wq->cv, &wq->mutex, &timeout);
|
||||
status = pthread_cond_timedwait(&wq->cv, &wq->mutex, &timeout);
|
||||
if (status == ETIMEDOUT) {
|
||||
DPRINTF(("Worker wait timed out\n"));
|
||||
timedout = 1;
|
||||
break;
|
||||
} else if (status != 0) {
|
||||
}
|
||||
else if (status != 0) {
|
||||
/*
|
||||
* This shouldn't happen, so 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
|
||||
* server here.
|
||||
*/
|
||||
DPRINTF ((
|
||||
"Worker wait failed, %d (%s)\n",
|
||||
status, strerror (status)));
|
||||
DPRINTF(("Worker wait failed, %d (%s)\n", status, strerror(status)));
|
||||
wq->counter--;
|
||||
pthread_mutex_unlock(&wq->mutex);
|
||||
return NULL;
|
||||
@@ -149,15 +148,15 @@ static void *workq_server (void *arg)
|
||||
/*
|
||||
* 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;
|
||||
|
||||
status = pthread_attr_init(&wq->attr);
|
||||
if (status != 0)
|
||||
return status;
|
||||
status = pthread_attr_setdetachstate (
|
||||
&wq->attr, PTHREAD_CREATE_DETACHED);
|
||||
status = pthread_attr_setdetachstate(&wq->attr, PTHREAD_CREATE_DETACHED);
|
||||
if (status != 0) {
|
||||
pthread_attr_destroy(&wq->attr);
|
||||
return status;
|
||||
@@ -186,7 +185,8 @@ int workq_init (workq_t *wq, int threads, void (*engine)(void *arg))
|
||||
/*
|
||||
* Destroy a work queue.
|
||||
*/
|
||||
int workq_destroy (workq_t *wq)
|
||||
int
|
||||
workq_destroy(workq_t* wq)
|
||||
{
|
||||
int status, status1, status2;
|
||||
|
||||
@@ -246,7 +246,8 @@ int workq_destroy (workq_t *wq)
|
||||
/*
|
||||
* 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;
|
||||
pthread_t id;
|
||||
@@ -288,14 +289,14 @@ int workq_add (workq_t *wq, void *element)
|
||||
pthread_mutex_unlock(&wq->mutex);
|
||||
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
|
||||
* create a new thread, do so.
|
||||
*/
|
||||
DPRINTF(("Creating new worker\n"));
|
||||
status = pthread_create (
|
||||
&id, &wq->attr, workq_server, (void*)wq);
|
||||
status = pthread_create(&id, &wq->attr, workq_server, (void*) wq);
|
||||
if (status != 0) {
|
||||
pthread_mutex_unlock(&wq->mutex);
|
||||
return status;
|
||||
|
||||
@@ -51,8 +51,7 @@ typedef struct workq_tag {
|
||||
/*
|
||||
* Define work queue functions
|
||||
*/
|
||||
extern int workq_init (
|
||||
workq_t *wq,
|
||||
extern int workq_init(workq_t* wq,
|
||||
int threads, /* maximum threads */
|
||||
void (*engine)(void*)); /* engine routine */
|
||||
extern int workq_destroy(workq_t* wq);
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
* Demonstrate a use of work queues.
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "workq.h"
|
||||
#include "errors.h"
|
||||
#include "workq.h"
|
||||
|
||||
#define ITERATIONS 25
|
||||
|
||||
@@ -31,7 +31,8 @@ workq_t workq;
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@@ -45,7 +46,8 @@ void destructor (void *value_ptr)
|
||||
* This is the routine called by the work queue servers to
|
||||
* perform operations in parallel.
|
||||
*/
|
||||
void engine_routine (void *arg)
|
||||
void
|
||||
engine_routine(void* arg)
|
||||
{
|
||||
engine_t* engine;
|
||||
power_t* power = (power_t*) arg;
|
||||
@@ -55,27 +57,25 @@ void engine_routine (void *arg)
|
||||
engine = pthread_getspecific(engine_key);
|
||||
if (engine == NULL) {
|
||||
engine = (engine_t*) malloc(sizeof(engine_t));
|
||||
status = pthread_setspecific (
|
||||
engine_key, (void*)engine);
|
||||
status = pthread_setspecific(engine_key, (void*) engine);
|
||||
if (status != 0)
|
||||
err_abort(status, "Set tsd");
|
||||
engine->thread_id = pthread_self();
|
||||
engine->calls = 1;
|
||||
} else
|
||||
}
|
||||
else
|
||||
engine->calls++;
|
||||
result = 1;
|
||||
printf (
|
||||
"Engine: computing %d^%d\n",
|
||||
power->value, power->power);
|
||||
for (count = 1; count <= power->power; count++)
|
||||
result *= power->value;
|
||||
printf("Engine: computing %d^%d\n", power->value, power->power);
|
||||
for (count = 1; count <= power->power; count++) result *= power->value;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread start routine that issues work queue requests.
|
||||
*/
|
||||
void *thread_routine (void *arg)
|
||||
void*
|
||||
thread_routine(void* arg)
|
||||
{
|
||||
power_t* element;
|
||||
int count;
|
||||
@@ -91,9 +91,7 @@ void *thread_routine (void *arg)
|
||||
errno_abort("Allocate element");
|
||||
element->value = rand_r(&seed) % 20;
|
||||
element->power = rand_r(&seed) % 7;
|
||||
DPRINTF ((
|
||||
"Request: %d^%d\n",
|
||||
element->value, element->power));
|
||||
DPRINTF(("Request: %d^%d\n", element->value, element->power));
|
||||
status = workq_add(&workq, (void*) element);
|
||||
if (status != 0)
|
||||
err_abort(status, "Add to work queue");
|
||||
@@ -102,7 +100,8 @@ void *thread_routine (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t thread_id;
|
||||
engine_t* engine;
|
||||
@@ -138,7 +137,6 @@ int main (int argc, char *argv[])
|
||||
printf("engine %d: %d calls\n", count, engine->calls);
|
||||
engine = engine->link;
|
||||
}
|
||||
printf ("%d engine threads processed %d calls\n",
|
||||
count, calls);
|
||||
printf("%d engine threads processed %d calls\n", count, calls);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
#include <pthread.h>
|
||||
#include "errors.h"
|
||||
|
||||
void *printer_thread (void *arg)
|
||||
void*
|
||||
printer_thread(void* arg)
|
||||
{
|
||||
char* string = *(char**) arg;
|
||||
|
||||
@@ -19,7 +20,8 @@ void *printer_thread (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
pthread_t printer_id;
|
||||
char* string_ptr;
|
||||
@@ -35,8 +37,8 @@ int main (int argc, char *argv[])
|
||||
thr_setconcurrency(2);
|
||||
#endif
|
||||
string_ptr = "Before value";
|
||||
status = pthread_create (
|
||||
&printer_id, NULL, printer_thread, (void*)&string_ptr);
|
||||
status =
|
||||
pthread_create(&printer_id, NULL, printer_thread, (void*) &string_ptr);
|
||||
if (status != 0)
|
||||
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
|
||||
* 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";
|
||||
status = pthread_join(printer_id, NULL);
|
||||
|
||||
Reference in New Issue
Block a user