blob: 1b3635f7d32b416d3e94abdcf40de4f254d92025 [file] [log] [blame]
/*
m5threads, a pthread library for the M5 simulator
Copyright (C) 2009, Stanford University
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
void* run1(void* arglist)
{
int* args = (int*)arglist;
printf("[run1] argument passed %d %d\n", args[0], args[1]);
// yield() does nothing
pthread_yield();
pthread_t run1th = pthread_self();
printf("[run1] thread id : %d \n", (int)run1th);
pthread_exit(0);
assert(false);
return NULL;
}
int gl_counter = 0;
void funcWithCriticalSection()
{
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int result = pthread_mutex_lock(&lock);
assert(result == 0);
gl_counter++;
printf("%d\n",gl_counter);
result = pthread_mutex_unlock(&lock);
assert(result == 0);
}
void* run2(void* arglist)
{
int i;
for (i = 0; i <5; i++) {
funcWithCriticalSection();
}
return NULL;
}
pthread_key_t key;
void* run3(void* arglist)
{
int j;
int i = pthread_self();
int result = pthread_setspecific(key, (void*)&i);
assert(result == 0);
void* value = pthread_getspecific(key);
assert(value != NULL);
for (j=5; j >= 0 ; j--) {
printf("");
}
if (*((int*)value) == (int) pthread_self()) {
printf("[run3]thread-private value matches 2 : %d \n", *((int*)value));
}
else {
printf("[run3]thread-private value doesn't match 2 : %d \n", *((int*)value));
}
return NULL;
}
pthread_cond_t cond_sync = PTHREAD_COND_INITIALIZER;
pthread_mutex_t cond_lock = PTHREAD_MUTEX_INITIALIZER;
void* run4(void* arglist)
{
int j;
for (j=5; j >= 0 ; j--) {
printf("[run4] goofing around for a moment %d \n", j);
}
int result = pthread_mutex_lock(&cond_lock);
assert(result == 0);
printf("[run4] about to call broadcast\n"); {
result = pthread_cond_broadcast(&cond_sync);
assert(result == 0);
}
result = pthread_mutex_unlock(&cond_lock);
assert(result == 0);
return NULL;
}
int main(int argc, const char** const argv) {
// test 1 : creation & join
printf("\n1. thread creation and join test\n");
pthread_t pth;
pthread_attr_t attr;
int arg[2];
arg[0] = 2;
arg[1] = 4;
int result = pthread_attr_init(&attr);
assert(result == 0);
result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
assert(result == 0);
result = pthread_create(&pth, &attr, run1, &arg);
assert(result == 0);
printf("[main]thread(%d) created with run1\n", (int)pth);
result = pthread_join(pth, NULL);
assert(result == 0);
printf("[main]thread(%d) joined\n", (int)pth);
// test 2 : mutex
printf("\n2. mutex test\n");
result = pthread_create(&pth, &attr, run2, &arg);
assert(result == 0);
printf("[main]thread(%d) created with run2\n", (int)pth);
int i;
for (i = 0; i <5; i++) {
funcWithCriticalSection();
}
result = pthread_join(pth, NULL);
assert(result == 0);
// test 3 : key
printf("\n3. thread-private storage test\n");
result = pthread_key_create(&key, NULL);
assert(result == 0);
result = pthread_create(&pth, &attr, run3, &arg);
assert(result == 0);
printf("[main]thread(%d) created with run3\n", (int)pth);
i = 1;
result = pthread_setspecific(key, (void*)&i);
assert(result == 0);
void* value = pthread_getspecific(key);
assert(value != NULL);
if (*((int*)value) == 1) {
printf("[main]thread-private value matches 1 : %d \n", *((int*)value));
}
else {
printf("[main]thread-private value doesn't match 1 : %d \n", *((int*)value));
}
result = pthread_join(pth, NULL);
assert(result == 0);
// test 4 : wait / notifyall
printf("\n4. wait-notifyall test\n");
result = pthread_create(&pth, &attr, run4, &arg);
assert(result == 0);
printf("[main]thread(%d) created with run4\n", (int)pth);
result = pthread_mutex_lock(&cond_lock);
assert(result == 0);
printf("[main]going into wait()\n");
result = pthread_cond_wait(&cond_sync, &cond_lock);
assert(result == 0);
result = pthread_mutex_unlock(&cond_lock);
assert(result == 0);
result = pthread_join(pth, NULL);
assert(result == 0);
}