xv6-lab/notxv6/ph.c
2023-02-01 14:53:46 +00:00

156 lines
2.9 KiB
C

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <pthread.h>
#include <sys/time.h>
#define NBUCKET 5
#define NKEYS 100000
struct entry {
int key;
int value;
struct entry *next;
};
struct entry *table[NBUCKET];
int keys[NKEYS];
int nthread = 1;
pthread_mutex_t lock[NBUCKET];
double
now()
{
struct timeval tv;
gettimeofday(&tv, 0);
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
static void
insert(int key, int value, struct entry **p, struct entry *n)
{
struct entry *e = malloc(sizeof(struct entry));
e->key = key;
e->value = value;
e->next = n;
*p = e;
}
static
void put(int key, int value)
{
int i = key % NBUCKET;
// is the key already present?
struct entry *e = 0;
pthread_mutex_lock(&lock[i]);
for (e = table[i]; e != 0; e = e->next) {
if (e->key == key)
break;
}
if(e){
// update the existing key.
e->value = value;
} else {
// the new is new.
insert(key, value, &table[i], table[i]);
}
pthread_mutex_unlock(&lock[i]);
}
static struct entry*
get(int key)
{
int i = key % NBUCKET;
struct entry *e = 0;
pthread_mutex_lock(&lock[i]);
for (e = table[i]; e != 0; e = e->next) {
if (e->key == key) break;
}
pthread_mutex_unlock(&lock[i]);
return e;
}
static void *
put_thread(void *xa)
{
int n = (int) (long) xa; // thread number
int b = NKEYS/nthread;
for (int i = 0; i < b; i++) {
put(keys[b*n + i], n);
}
return NULL;
}
static void *
get_thread(void *xa)
{
int n = (int) (long) xa; // thread number
int missing = 0;
for (int i = 0; i < NKEYS; i++) {
struct entry *e = get(keys[i]);
if (e == 0) missing++;
}
printf("%d: %d keys missing\n", n, missing);
return NULL;
}
int
main(int argc, char *argv[])
{
pthread_t *tha;
void *value;
double t1, t0;
if (argc < 2) {
fprintf(stderr, "Usage: %s nthreads\n", argv[0]);
exit(-1);
}
nthread = atoi(argv[1]);
tha = malloc(sizeof(pthread_t) * nthread);
srandom(0);
assert(NKEYS % nthread == 0);
for (int i = 0; i < NKEYS; i++) {
keys[i] = random();
}
for (int i = 0; i < NBUCKET; i ++){
pthread_mutex_init(&lock[i], NULL);
}
//
// first the puts
//
t0 = now();
for(int i = 0; i < nthread; i++) {
assert(pthread_create(&tha[i], NULL, put_thread, (void *) (long) i) == 0);
}
for(int i = 0; i < nthread; i++) {
assert(pthread_join(tha[i], &value) == 0);
}
t1 = now();
printf("%d puts, %.3f seconds, %.0f puts/second\n",
NKEYS, t1 - t0, NKEYS / (t1 - t0));
//
// now the gets
//
t0 = now();
for(int i = 0; i < nthread; i++) {
assert(pthread_create(&tha[i], NULL, get_thread, (void *) (long) i) == 0);
}
for(int i = 0; i < nthread; i++) {
assert(pthread_join(tha[i], &value) == 0);
}
t1 = now();
printf("%d gets, %.3f seconds, %.0f gets/second\n",
NKEYS*nthread, t1 - t0, (NKEYS*nthread) / (t1 - t0));
}