Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*************************
- Alaestor FGL 2016
- Windows 32-bits
- ISO/IEC 9899:1990
- alaestor@null.net
- *************************/
- /*
- Warning and Error Free when compiled with tags ...
- -std=c89 -wall -wextra -O3 -pedantic
- -fexpensive-optimizations -fomit-frame-pointer
- */
- /*
- 1 thread per logical core
- each thread randomly generates strings until one makes "Hello World"
- Once successful, the randomly generated string is then printed to stdout
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- #include <limits.h>
- /* Uncomment DEBUG for Two-Thread, Instant-Solve test */
- /* Uncomment PAUSE for the program to prompt for enter key before continuing */
- /*#define DEBUG*/
- /*#define PAUSE*/
- #define LEN (sizeof(str)) /* 12 = 11 chars + 1 null term */
- /* work return codes (unsigned int) */
- #define FAILURE_LOOP_MAX 69
- #define FAILURE_FINISHED 9001
- #define SUCCESS 1337
- /* Global Thread State */
- unsigned int work_finished;
- /* Global Constants */
- const char chlist[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\0";
- const char str[] = "Hello World"; /* may be replaced with anything <max_len */
- /* Function Prototypes */
- unsigned int WINAPI work(void *buffer);
- int e(char *errstr);
- int main(int argc, char **argv)
- {
- int i;
- int count = 0;
- int cores = 0;
- unsigned int ec = 0;
- const size_t cache = 64; /* Sys_Logical_Proc_Info ... MinGW Bug */
- const size_t max_len = cache / sizeof(char);
- char *buffers[MAXIMUM_WAIT_OBJECTS];
- HANDLE threads[MAXIMUM_WAIT_OBJECTS];
- SYSTEM_INFO sysinfo;
- (void)argc,(void)argv;
- work_finished = 0;
- if (LEN >= max_len)
- { /* sanity check */
- e(" String to be generated is over largest cache line");
- return 0;
- }
- GetSystemInfo(&sysinfo);
- cores = sysinfo.dwNumberOfProcessors;
- #ifdef DEBUG
- cores = 2;
- #endif /* DEBUG */
- for (i = 0; i < cores && i < MAXIMUM_WAIT_OBJECTS-1; i++, count++)
- {
- buffers[i] = malloc(cache);
- if (buffers[i] == NULL)
- {
- e(" Malloc returned NULL");
- goto ROUTINE_EXIT;
- }
- threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) work,
- buffers[i], 0, NULL);
- if (threads[i] == NULL)
- {
- e(" CreateThread returned NULL");
- goto ROUTINE_EXIT;
- }
- }
- puts("\n Generating Hello World String...");
- WaitForMultipleObjects(cores, threads, 0, INFINITE);
- puts(" Finished!");
- for (i = 0; i < count-1 && ec == 0; i++)
- { /* find the buffer that exited */
- GetExitCodeThread(threads[i], (PDWORD)&ec);
- if (ec != SUCCESS)
- ec = 0;
- else
- ec = i;
- }
- /* print generated string */
- printf("\n %s\n\n",buffers[ec]);
- ROUTINE_EXIT: /* goto label: kill existing threads and buffers */
- work_finished = 1;
- Sleep(20); /* so threads may have a chance to exit */
- for (i = 0; i < count; i++)
- { /* Close thread handles and free associated buffers */
- CloseHandle(threads[i]);
- free(buffers[i]);
- }
- #ifdef PAUSE
- puts(" Press Enter To End Process");
- getchar();
- #endif /* PAUSE */
- return 0;
- }
- unsigned int WINAPI work(void *buffer)
- {
- int i;
- char result[LEN];
- unsigned int loopcount = 0;
- do
- { /* Generate random characters in an array to match desired output */
- if (loopcount++ == UINT_MAX-1) /* Oblivion check */
- ExitThread(FAILURE_LOOP_MAX);
- if (work_finished == 1) /* another thread has finished */
- ExitThread(FAILURE_FINISHED);
- for (i = LEN-1; i >= 0; i--) /* rand characters to compose string */
- result[i] = chlist[rand() % sizeof(chlist) - 1];
- #ifdef DEBUG
- memcpy(result, str, LEN);
- #endif /* DEBUG */
- Sleep(0); /* So that the thread wont hog timeslices */
- } while (memcmp(&result[0], str, LEN));
- memcpy(buffer, (const void *)result, LEN);
- ExitThread(SUCCESS);
- }
- int e(char *errstr)
- {
- printf("=== ERROR ===\n"
- "%s\n", errstr);
- #ifdef PAUSE
- puts(" Press Enter To Continue Application");
- getchar();
- #endif /* PAUSE */
- return -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement