1 module photon.linux.support;
2 version(linux):
3 import core.sys.posix.unistd;
4 import core.sys.linux.timerfd;
5 import core.stdc.errno;
6 import core.stdc.stdlib;
7 import core.thread;
8 import core.stdc.config;
9 import core.sys.posix.pthread;
10 import photon.linux.syscalls;
11 
12 enum int MSG_DONTWAIT = 0x40;
13 enum int SOCK_NONBLOCK = 0x800;
14 
15 extern(C) int eventfd(uint initial, int flags) nothrow;
16 extern(C) void perror(const(char) *s) nothrow;
17 
18 T checked(T: ssize_t)(T value, const char* msg="unknown place") nothrow {
19     if (value < 0) {
20         perror(msg);
21         _exit(cast(int)-value);
22     }
23     return value;
24 }
25 
26 ssize_t withErrorno(ssize_t resp) nothrow {
27     if(resp < 0) {
28         //logf("Syscall ret %d", resp);
29         errno = cast(int)-resp;
30         return -1;
31     }
32     else {
33         return resp;
34     }
35 }
36 
37 void logf(string file = __FILE__, int line = __LINE__, T...)(string msg, T args)
38 {
39     debug(photon) {
40         try {
41             import std.stdio;
42             stderr.writefln(msg, args);
43             stderr.writefln("\tat %s:%s:[LWP:%s]", file, line, pthread_self());
44         }
45         catch(Throwable t) {
46             abort();
47         }
48     }
49 }
50 
51 
52 @nogc:
53 nothrow:
54 
55 
56 private // helpers
57 {
58 
59     /* Size definition for CPU sets.  */
60     enum
61     {
62         __CPU_SETSIZE = 1024,
63         __NCPUBITS  = 8 * cpu_mask.sizeof,
64     }
65 
66     /* Macros */
67 
68     /* Basic access functions.  */
69     size_t __CPUELT()(size_t cpu) pure
70     {
71         return cpu / __NCPUBITS;
72     }
73     cpu_mask __CPUMASK()(size_t cpu) pure
74     {
75         return 1UL << (cpu % __NCPUBITS);
76     }
77 
78     cpu_mask __CPU_SET_S()(size_t cpu, size_t setsize, cpu_set_t* cpusetp) pure
79     {
80         if (cpu < 8 * setsize)
81         {
82             cpusetp.__bits[__CPUELT(cpu)] |= __CPUMASK(cpu);
83             return __CPUMASK(cpu);
84         }
85 
86         return 0;
87     }
88 }
89 
90 /// Type for array elements in 'cpu_set_t'.
91 alias c_ulong cpu_mask;
92 
93 /// Data structure to describe CPU mask.
94 struct cpu_set_t
95 {
96     cpu_mask[__CPU_SETSIZE / __NCPUBITS] __bits;
97 }
98 
99 /// Access macros for 'cpu_set' (missing a lot of them)
100 
101 cpu_mask CPU_SET()(size_t cpu, cpu_set_t* cpusetp) pure
102 {
103      return __CPU_SET_S(cpu, cpu_set_t.sizeof, cpusetp);
104 }
105 
106 /* Functions */
107 extern(C):
108 int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
109 int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
110