1. http://www.developerfusion.com/article/138018/memory-ordering-for-atomic-operations-in-c0x/
2. http://locklessinc.com/articles/futex_cheat_sheet/
Tuesday, June 9, 2015
Thursday, May 14, 2015
Linux PCIE & DMA tutorials
1. http://en.wikipedia.org/wiki/PCI_configuration_space
2. https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt
3. http://linuxgazette.net/156/jangir.html
4. http://www.tldp.org/LDP/tlk/dd/pci.html
5. https://lkml.org/
6. http://bbs.chinaunix.net/forum.php?mod=forumdisplay&fid=227&page=1
1. http://en.wikipedia.org/wiki/PCI_configuration_space
2. https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt
3. http://linuxgazette.net/156/jangir.html
4. http://www.tldp.org/LDP/tlk/dd/pci.html
5. https://lkml.org/
6. http://bbs.chinaunix.net/forum.php?mod=forumdisplay&fid=227&page=1
Sunday, March 2, 2014
C++ Idioms
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms:
enable_if implementation:
=== Solution and Sample code===
The enable_if templates are very simple syntactically. They always come in pairs: one of them is empty and the other one has a <code>type</code> typedef that forwards its second type parameter. The empty structure triggers an invalid type because it contains no member. When a compile-time condition is false, the empty <code>enable_if</code> template is chosen. Appending <code>::type</code> would result in an invalid instantiation, which the compiler throws away due to the SFINAE principle.
<source lang="cpp">
template <bool, class T = void>
struct enable_if
{};
template <class T>
struct enable_if<true, T>
{
typedef T type;
};
</source>
Here is an example that shows how an overloaded template function can be selected at compile-time based on arbitrary properties of the type parameter. Imagine that the function '''T foo(T t)''' is defined for all types such that T is arithmetic. The enable_if template can be used either as the return type, as in this example:
<source lang="cpp">
template <class T>
typename enable_if<is_arithmetic<T>::value, T>::type
foo(T t)
{
// ...
return t;
}
</source>
or as an extra argument, as in the following:
<source lang="cpp">
template <class T>
T foo(T t, typename enable_if<is_arithmetic<T>::value >::type* dummy = 0);
</source>
The extra argument added to foo() is given a default value. Since the caller of foo() will ignore this dummy argument, it can be given any type. In particular, we can allow it to be void *. With this in mind, we can simply omit the second template argument to '''enable_if''', which means that the '''enable_if<...>::type''' expression will evaluate to ''void'' when '''is_arithmetic<T>''' is true.
Whether to write the enabler as an argument or within the return type is largely a matter of taste, but for certain functions, only one alternative is possible:
* Operators have a fixed number of arguments, thus '''enable_if''' must be used in the return type.
* Constructors and destructors do not have a return type; an extra argument is the only option.
* There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors, however, can have enablers as extra default arguments.
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms:
enable_if implementation:
=== Solution and Sample code===
The enable_if templates are very simple syntactically. They always come in pairs: one of them is empty and the other one has a <code>type</code> typedef that forwards its second type parameter. The empty structure triggers an invalid type because it contains no member. When a compile-time condition is false, the empty <code>enable_if</code> template is chosen. Appending <code>::type</code> would result in an invalid instantiation, which the compiler throws away due to the SFINAE principle.
<source lang="cpp">
template <bool, class T = void>
struct enable_if
{};
template <class T>
struct enable_if<true, T>
{
typedef T type;
};
</source>
Here is an example that shows how an overloaded template function can be selected at compile-time based on arbitrary properties of the type parameter. Imagine that the function '''T foo(T t)''' is defined for all types such that T is arithmetic. The enable_if template can be used either as the return type, as in this example:
<source lang="cpp">
template <class T>
typename enable_if<is_arithmetic<T>::value, T>::type
foo(T t)
{
// ...
return t;
}
</source>
or as an extra argument, as in the following:
<source lang="cpp">
template <class T>
T foo(T t, typename enable_if<is_arithmetic<T>::value >::type* dummy = 0);
</source>
The extra argument added to foo() is given a default value. Since the caller of foo() will ignore this dummy argument, it can be given any type. In particular, we can allow it to be void *. With this in mind, we can simply omit the second template argument to '''enable_if''', which means that the '''enable_if<...>::type''' expression will evaluate to ''void'' when '''is_arithmetic<T>''' is true.
Whether to write the enabler as an argument or within the return type is largely a matter of taste, but for certain functions, only one alternative is possible:
* Operators have a fixed number of arguments, thus '''enable_if''' must be used in the return type.
* Constructors and destructors do not have a return type; an extra argument is the only option.
* There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors, however, can have enablers as extra default arguments.
Thursday, November 8, 2012
gdb cast
In gdb you have to put single-quotes around scoped C++ names, e.g.:
or:
p *('abc::def::ghi' *)0x123456
Instead of
Enter
gdb, run gdbtui. Or run gdb with the -tui switch. Or press C-x C-a after entering gdb. Now you're in GDB's TUI mode.Enter
layout asm to make the upper window display
assembly -- this will automatically follow your instruction pointer,
although you can also change frames or scroll around while debugging.
Press C-x s to enter SingleKey mode, where run continue up down finish etc. are abbreviated to a single key, allowing you to walk through your program very quickly.+---------------------------------------------------------------------------+ B+>|0x402670 <main> push %r15 | |0x402672 <main+2> mov %edi,%r15d | |0x402675 <main+5> push %r14 | |0x402677 <main+7> push %r13 | |0x402679 <main+9> mov %rsi,%r13 | |0x40267c <main+12> push %r12 | |0x40267e <main+14> push %rbp | |0x40267f <main+15> push %rbx | |0x402680 <main+16> sub $0x438,%rsp | |0x402687 <main+23> mov (%rsi),%rdi | |0x40268a <main+26> movq $0x402a10,0x400(%rsp) | |0x402696 <main+38> movq $0x0,0x408(%rsp) | |0x4026a2 <main+50> movq $0x402510,0x410(%rsp) | +---------------------------------------------------------------------------+ child process 21518 In: main Line: ?? PC: 0x402670 (gdb) file /opt/j64-602/bin/jconsole Reading symbols from /opt/j64-602/bin/jconsole...done. (no debugging symbols found)...done. (gdb) layout asm (gdb) start (gdb)
Tuesday, September 18, 2012
Learn VHDL
|
There is a VHDL book on-line:
http://tams-www.informatik.uni-hamburg.de/vhdl/doc/cookbook/VHDL-Cookbook.pdf My advice, as with any language, is to start hacking it. What I would do is get AvNet's Spartan 3A dev kit: http://www.xilinx.com/products/devkits/aes_sp3a_eval400_avnet.htm Why? It's got all you need, and it's only $50. Next, I would read the tutorial for the kit (free with registration on AvNet). This will walk you though the structure of a basic VHDL program. Then, I would extend that to do something need, using the book and the web as a reference as necessary. |
Monday, April 2, 2012
IPs of a multicast socket
There are 3 IPs a multicast socket might need,
1. before joining a multicast group, we need to bind the socket, what does this bind do?
1) it tells the kernel which port this application want the data from;
1) it tells the kernel which port this application want the data from;
2) it tells the kernel what dest address the incoming packet should have.
so if we say any (0.0.0.0), any incoming packet with the correct port number will be forwarded to the app; if we say only x.y.z.d,
then only the packets with that addr will be forwarded to the app, others will be dropped;
For a multicast group, ideally should be the multicast ip or 0.0.0.0, cannot think of a 3rd case, unless we want to join several multicast
groups, but want to filter out some traffic here, but I am doubting we will ever need this.
2. When join a group, we need to provide the multicast addr, this is easy to understand; We also want to tell the kernel from which interface
this group's traffic will come from, if we don't specify it will be any, the kernel will select one for you(definitely, not all interfaces, so this might not works as you want), this is done
by local ip.
IP_ADD_MEMBERSHIP.
Recall that you need to tell the kernel which multicast groups you are interested in. If no process is interested in a group, packets destined to it that arrive to the host are discarded. In order to inform the kernel of your interests and, thus, become a member of that group, you should first fill a
ip_mreqstructure which is passed later to the kernel in theoptvalfield of thesetsockopt()system call.The ip_mreq structure (taken from
/usr/include/linux/in.h) has the following members:struct ip_mreq
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
(Note: the "physical" definition of the structure is in the file above specified. Nonetheless, you should not include
<linux/in.h>if you want your code to be portable. Instead, include<netinet/in.h>
which, in turn, includes<linux/in.h>itself).The first member,imr_multiaddr, holds the group address you want to join. Remember that memberships are also associated with interfaces, not just groups. This is the reason you have to provide a value for the second member:imr_interface. This way, if you are in a multihomed host, you can join the same group in several interfaces. You can always fill this last member with the wildcard address (INADDR_ANY) and then the kernel will deal with the task of choosing the interface.With this structure filled (say you defined it as:struct ip_mreq mreq;) you just have to callsetsockopt()this way:setsockopt (socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
Notice that you can join several groups to the same socket, not just one. The limit to this isIP_MAX_MEMBERSHIPSand, as of version 2.0.33, it has the value of 20
6.1 IP_MULTICAST_LOOP.
You have to decide, as the application writer, whether you want the data you send to be looped back to your host or not. If you plan to have more than one process or user "listening", loopback must be enabled. On the other hand, if you are sending the images your video camera is producing, you probably don't want loopback, even if you want to see yourself on the screen. In that latter case, your application will probably receive the images from a device attached to the computer and send them to the socket. As the application already "has" that data, it is improbable it wants to receive it again on the socket. Loopback is by default enabled.Regard thatoptvalis a pointer. You can't write:setsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, 0, 1);
to disable loopback. Instead write:
u_char loop;
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
and setloopto 1 to enable loopback or 0 to disable it.To know whether a socket is currently looping-back or not use something like:u_char loop;
int size;
getsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &size)
6.2 IP_MULTICAST_TTL.
If not otherwise specified, multicast datagrams are sent with a default value of 1, to prevent them to be forwarded beyond the local network. To change the TTL to the value you desire (from 0 to 255), put that value into a variable (here I name it "ttl") and write somewhere in your program:u_char ttl;
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
The behavior withgetsockopt()is similar to the one seen on IP_MULTICAST_LOOP.6.3 IP_MULTICAST_IF.
Usually, the system administrator specifies the default interface multicast datagrams should be sent from. The programmer can override this and choose a concrete outgoing interface for a given socket with this option.struct in_addr interface_addr;
setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr));
>From now on, all multicast traffic generated in this socket will be output from the interface chosen. To revert to the original behavior and let the kernel choose the outgoing interface based on the system administrator's configuration, it is enough to callsetsockopt()with this same option andINADDR_ANYin the interface field.In determining or selecting outgoing interfaces, the following ioctls might be useful:SIOCGIFADDR(to get an interface's address),SIOCGIFCONF(to get the list of all the interfaces) andSIOCGIFFLAGS(to get an interface's flags and, thus, determine whether the interface is multicast capable or not -theIFF_MULTICASTflag-).If the host has more than one interface and the IP_MULTICAST_IF option is not set, multicast transmissions are sent from the default interface, although the remainding interfaces might be used for multicast forwarding if the host is acting as a multicast router.
Connected UDP
A successful return from a UDP output operation only means there was room for the resulting IP datagram on the interface output queue.
There are at least four pieces of information that a server might want to know from an arriving IP datagram: the source IP address, destination IP address, source port number, and destination port number. Figure 8.13 shows the function calls that return this information for a TCP server and a UDP server.
With a connected UDP socket, three things change, compared to the default unconnected UDP socket:
1. We can no longer specify the destination IP address and port for an output operation. That is, we do not use sendto, but write or send instead. Anything written to a connected UDP socket is automatically sent to the protocol address (e.g., IP address and port) specified by connect.
Similar to TCP, we can call sendto for a connected UDP socket, but we cannot specify a destination address. The fifth argument to sendto (the pointer to the socket address structure) must be a null pointer, and the sixth argument (the size of the socket address structure) should be 0. The POSIX specification states that when the fifth argument is a null pointer, the sixth argument is ignored.
2. We do not need to use recvfrom to learn the sender of a datagram, but read, recv, or recvmsg instead. The only datagrams returned by the kernel for an input operation on a connected UDP socket are those arriving from the protocol address specified in connect. Datagrams destined to the connected UDP socket's local protocol address (e.g., IP address and port) but arriving from a protocol address other than the one to which the socket was connected are not passed to the connected socket. This limits a connected UDP socket to exchanging datagrams with one and only one peer.
Technically, a connected UDP socket exchanges datagrams with only one IP address, because it is possible to connect to a multicast or broadcast address.
3. Asynchronous errors are returned to the process for connected UDP sockets.
The corollary, as we previously described, is that unconnected UDP sockets do not receive asynchronous errors.
There are at least four pieces of information that a server might want to know from an arriving IP datagram: the source IP address, destination IP address, source port number, and destination port number. Figure 8.13 shows the function calls that return this information for a TCP server and a UDP server.
With a connected UDP socket, three things change, compared to the default unconnected UDP socket:
1. We can no longer specify the destination IP address and port for an output operation. That is, we do not use sendto, but write or send instead. Anything written to a connected UDP socket is automatically sent to the protocol address (e.g., IP address and port) specified by connect.
Similar to TCP, we can call sendto for a connected UDP socket, but we cannot specify a destination address. The fifth argument to sendto (the pointer to the socket address structure) must be a null pointer, and the sixth argument (the size of the socket address structure) should be 0. The POSIX specification states that when the fifth argument is a null pointer, the sixth argument is ignored.
2. We do not need to use recvfrom to learn the sender of a datagram, but read, recv, or recvmsg instead. The only datagrams returned by the kernel for an input operation on a connected UDP socket are those arriving from the protocol address specified in connect. Datagrams destined to the connected UDP socket's local protocol address (e.g., IP address and port) but arriving from a protocol address other than the one to which the socket was connected are not passed to the connected socket. This limits a connected UDP socket to exchanging datagrams with one and only one peer.
Technically, a connected UDP socket exchanges datagrams with only one IP address, because it is possible to connect to a multicast or broadcast address.
3. Asynchronous errors are returned to the process for connected UDP sockets.
The corollary, as we previously described, is that unconnected UDP sockets do not receive asynchronous errors.
Calling connect Multiple Times for a UDP Socket
A process with a connected UDP socket can call connect again for that socket for one of two reasons:
• To specify a new IP address and port
• To unconnect the socket
The first case, specifying a new peer for a connected UDP socket, differs from the use of connect with a TCP socket: connect can be called only one time for a TCP socket.
To unconnect a UDP socket, we call connect but set the family member of the socket address structure (sin_family for IPv4 or sin6_family for IPv6) to AF_UNSPEC. This might return an error of EAFNOSUPPORT (p. 736 of TCPv2), but that is acceptable. It is the process of calling connect on an already connected UDP socket that causes the socket to become unconnected (pp. 787–788 of TCPv2).
The Unix variants seem to differ on exactly how to unconnect a socket, and you may encounter approaches that work on some systems and not others. For example, calling connect with NULL for the address works only on some systems (and on some, it only works if the third argument, the length, is nonzero). The POSIX specification and BSD man pages are not much help here, only mentioning that a null address should be used and not mentioning the error return (even on success) at all. The most portable solution is to zero out an address structure, set the family to AF_UNSPEC as mentioned above, and pass it to connect.
A process with a connected UDP socket can call connect again for that socket for one of two reasons:
• To specify a new IP address and port
• To unconnect the socket
The first case, specifying a new peer for a connected UDP socket, differs from the use of connect with a TCP socket: connect can be called only one time for a TCP socket.
To unconnect a UDP socket, we call connect but set the family member of the socket address structure (sin_family for IPv4 or sin6_family for IPv6) to AF_UNSPEC. This might return an error of EAFNOSUPPORT (p. 736 of TCPv2), but that is acceptable. It is the process of calling connect on an already connected UDP socket that causes the socket to become unconnected (pp. 787–788 of TCPv2).
The Unix variants seem to differ on exactly how to unconnect a socket, and you may encounter approaches that work on some systems and not others. For example, calling connect with NULL for the address works only on some systems (and on some, it only works if the third argument, the length, is nonzero). The POSIX specification and BSD man pages are not much help here, only mentioning that a null address should be used and not mentioning the error return (even on success) at all. The most portable solution is to zero out an address structure, set the family to AF_UNSPEC as mentioned above, and pass it to connect.
Another area of disagreement is around the local binding of a socket during the unconnect process. AIX keeps both the chosen local IP address and the port, even from an implicit bind. FreeBSD and Linux set the local IP address back to all zeros, even if you previously called bind, but leave the port number intact. Solaris sets the local IP address back to all zeros if it was assigned by an implicit bind; but if the program called bind explicitly, then the IP address remains unchanged.
Subscribe to:
Posts (Atom)