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