forked from adrian-bl/libfairydust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.c
171 lines (144 loc) · 4.31 KB
/
common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* (C) 2010-2011 Adrian Ulrich / ETHZ
*
* Licensed under the terms of `The Artistic License 2.0'
* See: ../artistic-2_0.txt or http://www.perlfoundation.org/attachment/legal/artistic-2_0.txt
*
*/
#include "common.h"
/*
* Printout build informations
*/
void __fdust_spam() {
printf("%s starting up - %s\n", __FILE__, RELINFO);
printf("%s release git-%d, compiled with gcc-%s at %d. mode=%s\n", __FILE__, 100+_GIT_LOG_COUNT, __VERSION__, _COMPILED_AT, __fdust_mode());
}
/*
* Read our ENV or contact fairyd
*/
void lock_fdust_devices(int *rdevs, int opmode) {
char *env; /* FDUST_ALLOCATE env-pointer */
char *scratch; /* allocation-info to parse */
int i, x, sock; /* scratch stuff */
struct sockaddr_in f_addr; /* fairyd addr */
char inchar[1]; /* response buffer from fairyd*/
int ngpu = 0; /* number of detected GPUs */
DPRINT("allocating devices for pid %d\n", getpid());
switch(opmode) {
case FDUST_MODE_NVIDIA:
ngpu = _get_number_of_nvidia_devices();
break;
case FDUST_MODE_ATI:
ngpu = _get_number_of_ati_devices();
break;
default:
break; // will panic
}
/* Fill rdevs with END-Magic (= mark as inited) */
assert(rdevs[0] == FDUST_RSV_NINIT);
memset(rdevs, FDUST_RSV_END, sizeof(int)*MAX_GPUCOUNT);
assert(ngpu > 0);
if( (env = getenv(FDUST_ALLOCATE)) != NULL) {
/* env was set but we cannot modify it: copy into scratch */
if( (scratch = malloc(strlen(env)+1)) != NULL ) {
memcpy(scratch,env,strlen(env)+1);
}
else {
abort();
}
}
else {
/* must ask fairyd */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
assert(sock >= 0);
memset(&f_addr, 0, sizeof(f_addr));
f_addr.sin_family = AF_INET;
f_addr.sin_port = htons(NVD_PORT);
x = inet_pton(AF_INET, NVD_HOST, &f_addr.sin_addr);
assert(x == 1);
if(connect(sock, (const struct sockaddr *)&f_addr, sizeof(f_addr)) < 0) {
fprintf(stderr, "connection to fairyd failed: aborting\n");
exit(1);
}
/* send allocate request */
asprintf(&scratch, "allocate %d\r\n", getpid());
x = send(sock, scratch, strlen(scratch), 0);
assert(x >= 0);
free(scratch);
/* create an empty string */
if( (scratch = malloc(1)) == NULL )
abort();
scratch[0] = '\0';
while( recv(sock, &inchar, 1, 0) == 1 ) {
if(*inchar < 32) {
break;
}
else {
if(realloc(scratch,1) == NULL)
abort();
scratch[strlen(scratch)+1] = '\0';
scratch[strlen(scratch)] = *inchar;
}
}
close(sock);
DPRINT("fairyd reported: *%s*\n", scratch);
}
/* scratch should now be a string such as '0 3 6\0' */
assert(scratch != NULL);
i = 0; /* first virtual device number */
x = 1; /* do atoi() on next run */
/* special case -> allocate everything */
if(scratch[0] == '@') {
scratch[0] = '\0'; /* skip while loop */
for(i=0;i<ngpu;i++)
rdevs[i] = i;
DPRINT("allocated all (%d) devices as requested by environment settings\n",ngpu);
}
while( scratch[0] != '\0' ) {
if(scratch[0] >= '0' && scratch[0] <= '9') {
if(x) {
if(i < ngpu && atoi(scratch) < ngpu) {
rdevs[i++] = atoi(scratch);
}
x=0;
}
}
else if(x==0) {
x=1;
}
memmove(scratch, scratch+1, strlen(scratch));
memset(scratch+strlen(scratch),0,1);
}
/* cleanup */
free(scratch);
assert(rdevs[0] != FDUST_RSV_END); /* die if we ended up with 0 allocated devices */
for(i=0;i<MAX_GPUCOUNT;i++) {
if(rdevs[i] == FDUST_RSV_END)
break;
DPRINT("rdevs[fake_id=%d] = physical_id=%d\n", i, rdevs[i]);
}
}
int _get_number_of_nvidia_devices() {
return _get_number_of_sysfs_devices_whoa_this_function_name_is_too_long("/sys/bus/pci/drivers/nvidia");
}
int _get_number_of_ati_devices() {
return _get_number_of_sysfs_devices_whoa_this_function_name_is_too_long("/sys/bus/pci/drivers/fglrx_pci");
}
int _get_number_of_sysfs_devices_whoa_this_function_name_is_too_long(char *path) {
DIR *dfh;
struct dirent *dent;
int ngpu = 0;
dfh = opendir(path);
if(dfh != NULL) {
for(;;) {
dent = readdir(dfh);
if(dent == NULL)
break;
if(dent->d_type == DT_LNK && strlen(dent->d_name) == 12 && strncmp("0000:", dent->d_name, 5)==0)
ngpu++;
}
closedir(dfh);
}
DPRINT("> %s: returning %d\n", __func__, ngpu);
return ngpu;
}