~ubuntu-branches/ubuntu/hardy/numactl/hardy

« back to all changes in this revision

Viewing changes to syscall.c

  • Committer: Bazaar Package Importer
  • Author(s): Ian Wienand
  • Date: 2005-11-25 17:04:25 UTC
  • Revision ID: james.westby@ubuntu.com-20051125170425-62ged0kz3ztiqazq
Tags: upstream-0.7pre2
ImportĀ upstreamĀ versionĀ 0.7pre2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003,2004 Andi Kleen, SuSE Labs.
 
2
 
 
3
   libnuma is free software; you can redistribute it and/or
 
4
   modify it under the terms of the GNU Lesser General Public
 
5
   License as published by the Free Software Foundation; version
 
6
   2.1.
 
7
 
 
8
   libnuma is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
   Lesser General Public License for more details.
 
12
 
 
13
   You should find a copy of v2.1 of the GNU Lesser General Public License
 
14
   somewhere on your Linux system; if not, write to the Free Software 
 
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
 
16
#include <unistd.h>
 
17
#include <sys/types.h>
 
18
#include <asm/unistd.h>
 
19
#include <errno.h>
 
20
#include "numaif.h"
 
21
#include "numaint.h"
 
22
 
 
23
#define WEAK __attribute__((weak))
 
24
 
 
25
#if !defined(__NR_mbind) || !defined(__NR_set_mempolicy) || \
 
26
    !defined(__NR_get_mempolicy)
 
27
 
 
28
#if defined(__x86_64__)
 
29
 
 
30
#define __NR_sched_setaffinity    203
 
31
#define __NR_sched_getaffinity     204
 
32
 
 
33
/* Official allocation */
 
34
 
 
35
#define __NR_mbind 237
 
36
#define __NR_set_mempolicy 238
 
37
#define __NR_get_mempolicy 239
 
38
 
 
39
#elif defined(__ia64__)
 
40
#define __NR_sched_setaffinity    1231
 
41
#define __NR_sched_getaffinity    1232
 
42
 
 
43
/* Official allocation */
 
44
 
 
45
#define __NR_mbind 1259
 
46
#define __NR_get_mempolicy 1260
 
47
#define __NR_set_mempolicy 1261
 
48
 
 
49
#elif defined(__i386__)
 
50
 
 
51
/* semi-official allocation (in -mm) */
 
52
 
 
53
#define __NR_mbind 274
 
54
#define __NR_get_mempolicy 275
 
55
#define __NR_set_mempolicy 276
 
56
 
 
57
#elif defined(__ppc64__) || defined(__ppc__)
 
58
 
 
59
#define __NR_mbind 259
 
60
#define __NR_get_mempolicy 260
 
61
#define __NR_set_mempolicy 261
 
62
 
 
63
#else
 
64
#error "Add syscalls for your architecture or update kernel headers"
 
65
#endif
 
66
 
 
67
#endif
 
68
 
 
69
#if defined(__x86_64__)
 
70
/* 6 argument calls on x86-64 are often buggy in both glibc and
 
71
   asm/unistd.h. Add a working version here. */
 
72
long syscall6(long call, long a, long b, long c, long d, long e, long f)
 
73
 
74
       long res;
 
75
       asm volatile ("movq %[d],%%r10 ; movq %[e],%%r8 ; movq %[f],%%r9 ; syscall" 
 
76
                     : "=a" (res)
 
77
                     : "0" (call),"D" (a),"S" (b), "d" (c), 
 
78
                       [d] "g" (d), [e] "g" (e), [f] "g" (f) :
 
79
                     "r11","rcx","r8","r10","r9","memory" );
 
80
       if (res < 0) { 
 
81
               errno = -res; 
 
82
               res = -1; 
 
83
       } 
 
84
       return res;
 
85
 
86
#elif defined(__i386__)
 
87
 
 
88
/* i386 has buggy syscall6 in glibc too. This is tricky to do 
 
89
   in inline assembly because it clobbers so many registers. Do it 
 
90
   out of line. */
 
91
asm(
 
92
"__syscall6:\n"
 
93
"       pushl %ebp\n"
 
94
"       pushl %edi\n"
 
95
"       pushl %esi\n"
 
96
"       pushl %ebx\n"
 
97
"       movl  (0+5)*4(%esp),%eax\n"
 
98
"       movl  (1+5)*4(%esp),%ebx\n"
 
99
"       movl  (2+5)*4(%esp),%ecx\n"
 
100
"       movl  (3+5)*4(%esp),%edx\n"
 
101
"       movl  (4+5)*4(%esp),%esi\n"
 
102
"       movl  (5+5)*4(%esp),%edi\n"
 
103
"       movl  (6+5)*4(%esp),%ebp\n"
 
104
"       int $0x80\n"
 
105
"       popl %ebx\n"
 
106
"       popl %esi\n"
 
107
"       popl %edi\n"
 
108
"       popl %ebp\n"
 
109
"       ret"
 
110
);
 
111
extern long __syscall6(long n, long a, long b, long c, long d, long e, long f);
 
112
 
 
113
long syscall6(long call, long a, long b, long c, long d, long e, long f)
 
114
 
115
       long res = __syscall6(call,a,b,c,d,e,f);
 
116
       if (res < 0) { 
 
117
               errno = -res; 
 
118
               res = -1; 
 
119
       } 
 
120
       return res;
 
121
 
122
 
 
123
#else
 
124
#define syscall6 syscall
 
125
#endif
 
126
 
 
127
long WEAK get_mempolicy(int *policy, 
 
128
                   unsigned long *nmask, unsigned long maxnode,
 
129
                   void *addr, int flags)          
 
130
{
 
131
        return syscall(__NR_get_mempolicy, policy, nmask, maxnode, addr, flags);
 
132
}
 
133
 
 
134
long WEAK mbind(void *start, unsigned long len, int mode, 
 
135
           unsigned long *nmask, unsigned long maxnode, unsigned flags) 
 
136
{
 
137
        return syscall6(__NR_mbind, (long)start, len, mode, (long)nmask, maxnode, flags); 
 
138
}
 
139
 
 
140
long WEAK set_mempolicy(int mode, unsigned long *nmask, 
 
141
                                   unsigned long maxnode)
 
142
{
 
143
        return syscall(__NR_set_mempolicy,mode,nmask,maxnode);
 
144
}
 
145
 
 
146
/* SLES8 glibc doesn't define those */
 
147
 
 
148
int numa_sched_setaffinity(pid_t pid, unsigned len, unsigned long *mask)
 
149
{
 
150
        return syscall(__NR_sched_setaffinity,pid,len,mask);
 
151
}
 
152
 
 
153
int numa_sched_getaffinity(pid_t pid, unsigned len, unsigned long *mask)
 
154
{
 
155
        return syscall(__NR_sched_getaffinity,pid,len,mask);
 
156
 
 
157
}
 
158
 
 
159
make_internal_alias(numa_sched_getaffinity);
 
160
make_internal_alias(numa_sched_setaffinity);
 
161
make_internal_alias(get_mempolicy);
 
162
make_internal_alias(set_mempolicy);
 
163
make_internal_alias(mbind);