Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[6model/c] add a generic threads library with simple tests
- Loading branch information
Showing
8 changed files
with
192 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /* threads.c */ | ||
|
|
||
| /* Abstract the different threading interfaces present in different */ | ||
| /* operating systems. This library closely resembles pthreads, so */ | ||
| /* is a very thin wrapper on Posix systems, and does a lightweight */ | ||
| /* emulation on the others. */ | ||
|
|
||
| #include "threads.h" /* thread_create */ | ||
|
|
||
| /* thread_create */ | ||
| int | ||
| thread_create(struct thread_info * info, void * (* function)(void *), void * arg ) | ||
| { | ||
| int status; | ||
| #if defined( __APPLE__ ) || defined( __linux__ ) | ||
| status = pthread_create(&info->thread_id, NULL, function, arg); | ||
| #elif defined( _WIN32 ) | ||
| info->threadhandle = CreateThread(NULL, 0, | ||
| (LPTHREAD_START_ROUTINE) function, arg, 0, NULL); | ||
| status = (info->threadhandle == NULL); | ||
| #endif | ||
| return status; | ||
| } | ||
|
|
||
| /* end of threads.c */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| /* threads.h */ | ||
|
|
||
| #if defined( __APPLE__ ) || defined( __linux__ ) | ||
| #include <pthread.h> | ||
| #elif defined( _WIN32 ) | ||
| #include <windows.h> | ||
| #endif | ||
|
|
||
| /* thread_info */ | ||
| struct thread_info { | ||
| #if defined( __APPLE__ ) || defined( __linux__ ) | ||
| pthread_t thread_id; | ||
| #elif defined( _WIN32 ) | ||
| HANDLE threadhandle; | ||
| #endif | ||
| }; | ||
|
|
||
| int thread_create(struct thread_info * info, void * (* function)(void *), void * arg ); | ||
| int thread_join(struct thread_info * info); | ||
|
|
||
| /* end of threads.h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| /* timing.c */ | ||
|
|
||
| /* This timing library abstracts the different ways that operating */ | ||
| /* systems give the current time and do delays. */ | ||
|
|
||
| #ifdef _WIN32 | ||
| #include <windows.h> /* FILETIME GetSystemTimeAsFileTime */ | ||
| #else | ||
| #include <stdlib.h> /* NULL */ | ||
| #include <sys/time.h> /* gettimeofday */ | ||
| #endif | ||
| #include "timing.h" | ||
|
|
||
|
|
||
| /* gettime */ | ||
| /* Returns UTC seconds from 1970-01-01 in the upper 44 bits and */ | ||
| /* microseconds in the lower 20 bits of a 64 bit value. */ | ||
| long long | ||
| gettime() | ||
| { | ||
| int microseconds; | ||
| long long seconds, result; | ||
| #ifdef _WIN32 | ||
| FILETIME time1; | ||
| GetSystemTimeAsFileTime(&time1); | ||
| seconds = (((long long)time1.dwHighDateTime) << 32) | ||
| | time1.dwLowDateTime; | ||
| seconds -= 11644473600; /* from 1601-01-01 to 1970-01-01 */ | ||
| microseconds = (seconds % 10000000)/10; seconds /= 10000000; | ||
| #else | ||
| struct timeval time1; | ||
| gettimeofday(&time1, NULL); | ||
| seconds = time1.tv_sec; | ||
| microseconds = time1.tv_usec; | ||
| #endif | ||
| return (seconds << 20) | microseconds; | ||
| } | ||
|
|
||
|
|
||
| /* millisleep */ | ||
| void | ||
| millisleep(int milliseconds) | ||
| { | ||
| #ifdef _WIN32 | ||
| Sleep(milliseconds); | ||
| #else | ||
| struct timespec request, remainder; | ||
| request.tv_sec = milliseconds / 1000; | ||
| request.tv_nsec = (milliseconds % 1000) * 1000000; | ||
| nanosleep(&request, &remainder); /* ignore possible errors */ | ||
| #endif | ||
| } | ||
|
|
||
| /* See also: */ | ||
| /* UTC, TAI, and UNIX time http://cr.yp.to/proto/utctai.html */ | ||
| /* Online time converter: http://www.silisoftware.com/tools/date.php */ | ||
|
|
||
| /* end of timing.c */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| /* timing.h */ | ||
|
|
||
| long long gettime(); /* 44 bits Unix seconds, 20 bits microseconds */ | ||
| void millisleep(int milliseconds); | ||
|
|
||
| /* end of timing.h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /* 02a-threads.c */ | ||
|
|
||
| #include <assert.h> /* assert */ | ||
| #include "../../src/threads.h" | ||
| #include "../../src/timing.h" | ||
| #include "../Test.h" /* diag is plan */ | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
|
|
||
| /* test1args */ | ||
| struct test1args { | ||
| int milliseconds; | ||
| char * message; | ||
| }; | ||
|
|
||
|
|
||
| /* test1func */ | ||
| void * | ||
| test1func(void * arg) | ||
| { | ||
| char message[80]; | ||
| struct test1args * targ; targ = (struct test1args *) arg; | ||
| sprintf(message, "from %s sleep", targ->message); | ||
| millisleep(targ->milliseconds); | ||
| ok(1, message); | ||
| return NULL; | ||
| } | ||
|
|
||
|
|
||
| /* tests1_1 */ | ||
| void | ||
| tests1_1(void) | ||
| { | ||
| struct thread_info tinfo[2]; | ||
| struct test1args targs[2]; | ||
| targs[0].milliseconds = 10; targs[0].message = "10ms"; | ||
| targs[1].milliseconds = 20; targs[1].message = "20ms"; | ||
| ok( thread_create(tinfo+0, test1func, targs+0) == 0, "start 10ms sleep" ); | ||
| ok( thread_create(tinfo+1, test1func, targs+1) == 0, "start 20ms sleep" ); | ||
| millisleep(75); | ||
| } | ||
|
|
||
|
|
||
| /* main */ | ||
| int main(int argc, char *argv[]) | ||
| { | ||
| diag("02a-threads"); | ||
| plan(4); | ||
| tests1_1(); | ||
| } | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| /* end of 02a-threads.c */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters