5
/* $Id: threads.c,v 1.1.2.5 2007-08-28 21:29:46 manoj Exp $ */
8
# define PRNDBG3(m,a1,a2,a3) \
9
fprintf(stderr,"DBG %d: " m,armci_me,a1,a2,a3);fflush(stderr)
10
# define PRNDBG(m) PRNDBG3(m,0,0,0)
11
# define PRNDBG1(m,a1) PRNDBG3(m,a1,0,0)
12
# define PRNDBG2(m,a1,a2) PRNDBG3(m,a1,a2,0)
15
# define PRNDBG1(m,a1)
16
# define PRNDBG2(m,a1,a2)
17
# define PRNDBG3(m,a1,a2,a3)
26
armci_user_threads_t armci_user_threads;
28
void armci_init_threads()
31
char *uval = getenv("ARMCI_MAX_THREADS");
33
armci_user_threads.max = 1;
34
armci_user_threads.avail = 0;
36
if (uval != NULL) sscanf(uval, "%d", &armci_user_threads.max);
38
if (armci_user_threads.max < 1 ||
39
armci_user_threads.max > ARMCI_THREADS_LIMIT)
41
printf("Error: Only 1-%d threads are supported. ",ARMCI_THREADS_LIMIT);
42
printf("Set ARMCI_MAX_THREADS appropriately\n"); fflush(stdout);
43
armci_die("armci_init_threads: failed", 0);
46
bytes = sizeof(thread_id_t) * armci_user_threads.max;
47
if ( !(armci_user_threads.ids = (thread_id_t*) malloc(bytes)) )
49
armci_die("armci_init_threads: armci_user_threads.ids malloc failed",
50
armci_user_threads.max);
52
memset(armci_user_threads.ids, 0, bytes);
54
#if 0 /* spinlock has void return value */
55
if (THREAD_LOCK_INIT(armci_user_threads.lock) ||
56
THREAD_LOCK_INIT(armci_user_threads.buf_lock) ||
57
THREAD_LOCK_INIT(armci_user_threads.net_lock))
58
armci_die("armci_init_threads:locks initialization failed", 0);
60
THREAD_LOCK_INIT(armci_user_threads.lock);
61
THREAD_LOCK_INIT(armci_user_threads.buf_lock);
62
THREAD_LOCK_INIT(armci_user_threads.net_lock);
66
/* using one lock per socket for now, it might be feasible (and usefull)
67
* to use two (one for sending and one for receiving) */
68
armci_user_threads.sock_locks = malloc(armci_nclus *sizeof(thread_lock_t));
69
for (i = 0; i < armci_nclus; i++)
70
if (THREAD_LOCK_INIT(armci_user_threads.sock_locks[i]))
71
armci_die("armci_init_threads:sock locks initialization failed", i);
75
void armci_finalize_threads()
77
THREAD_LOCK_DESTROY(armci_user_threads.lock);
78
THREAD_LOCK_DESTROY(armci_user_threads.net_lock);
79
THREAD_LOCK_DESTROY(armci_user_threads.buf_lock);
80
free(armci_user_threads.ids);
83
/* calling armci_thread_idx for every function that accesses thread-private data
84
* might be expensive -- needs optiomization */
85
INLINE int armci_thread_idx()
87
int i, n = ARMCI_MIN(armci_user_threads.avail, armci_user_threads.max);
88
thread_id_t id = THREAD_ID_SELF();
90
for (i = 0; i < n; i++) if (id == armci_user_threads.ids[i]) {
91
/*PRNDBG2("thread id=%ld already registered, idx=%d\n", id, i);*/
95
/* see this thread for the first time */
96
return armci_register_thread(id);
99
INLINE int armci_register_thread(thread_id_t id)
103
THREAD_LOCK(armci_user_threads.lock);
105
i = armci_user_threads.avail;
106
armci_user_threads.avail++;
108
THREAD_UNLOCK(armci_user_threads.lock);
110
if (i < armci_user_threads.max)
111
armci_user_threads.ids[i] = id;
113
armci_die("armci_thread_idx: too many threads, adjust ARMCI_MAX_THREADS",
114
armci_user_threads.avail);
116
PRNDBG2("registered a new thread: idx=%d, id=%ld\n", i, id);