Java library for Linux Server Socket (incl. C Server Example)

Standard

(Source link: https://github.com/prl85/LinuxClientSocket-for-Java)

Java library (client socket) for communicating with Linux server socket

Requirement
– Java client: any OS
– C server: Linux OS

[Ubuntu 14.04] Setting process affinity in kernel mode (2/2 – Example code)

Standard

Prerequisite)
Prerequisite and all steps from https://study.prl85.com/ubuntu-14-04-setting-process-affinity-in-kernel-mode-12-kernel-modification

Sample code (cpu_affinity_user.c)

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sched.h>
#include <errno.h>
#include <linux/unistd.h>

void printCoreList()
{
	int i = 0;
	
	pid_t p = 0;	// meaning current process
	cpu_set_t mask;
	size_t len = sizeof(cpu_set_t);

	printf("(Current available CPU Core ID List:");	
	sched_getaffinity(p, len, &mask); // get available (movable) cpu cores

	bool printed = false;
	for (i = 0; i<CPU_SETSIZE; i++) 
	{
		if (CPU_ISSET(i, &mask))
		{
			printed = true;
			printf(" %d", i);
		}
	}
	
	if (printed == false)
		printf(" None");
	printf(")\n");
}

double measureTime(int calledID)
{
//	printf("Work - Called from cpu core %d\n", calledID);
	printf("Work - My allocated cpu core is %d\n", sched_getcpu());
		
	struct timeval currenttime;
	int i;
	
	// measure start time
	gettimeofday( &currenttime, 0 );

	long cur_time1 = 1000000 * currenttime.tv_sec + currenttime.tv_usec;
	double sec1 = cur_time1 / 1000000.0;
	
	// do some work
	for(i = 0; i < 5000000; i++)
		printf("%s", "\r");

	// measure end time
	gettimeofday( &currenttime, 0 );

	long cur_time2 = 1000000 * currenttime.tv_sec + currenttime.tv_usec;
	double sec2 = cur_time2 / 1000000.0;
	
	return sec2 - sec1;
}

int main()
{
	srand(time(NULL));

	int i = 0, j = 0, cpuChanged = 0;

	pid_t p = 0;	// meaning current process
	size_t len = sizeof(cpu_set_t);
	cpu_set_t new_mask;

	int numCpuCore = get_nprocs();		// get total number of cpu core
	int currentCore;	

	printf("Total number of CPU Core: %d\n", numCpuCore);
	printf("Current allocated CPU Core ID: %d\n", currentCore = sched_getcpu());	// get current allocated core

//	printCoreList(); // uncomment to see cpu affinity
	
	// case 1: normal mode (no cpu core fix)
	printf("<Doing some work without fixing the cpu core...>\n\n");

	int numOfRepetition = 30; // number of task repetition
	for (i = 0; i < numOfRepetition; i++) 
	{
		printf("[%3d/%3d] ", i+1, numOfRepetition);
		double elapsedTime = measureTime(currentCore = sched_getcpu());	// do work

		int newCore = sched_getcpu();	// what is current core after work?
		if (currentCore != newCore) // if the allocated cpu core is changed 
		{
			printf(" After work, my allocated CPU Core ID is moved to %d\n", currentCore = newCore);	
			cpuChanged++;
		}
	}
	printf("* Number of CPU core allocation change: %d (Out of %d trials, %.1lf%%)*\n", cpuChanged, numOfRepetition, (double) cpuChanged/(double) numOfRepetition*100.0);
	
	// case 2: special mode (cpu core fix)
	printf("\n<Randomly assigning another core...>\n");
	while(1)
	{
		int newcpuID = rand() % numCpuCore;
		if (newcpuID != currentCore)
		{
			CPU_ZERO(&new_mask);
			CPU_SET(newcpuID, &new_mask);
			break;
		}
	}
	
	cpuChanged = 0;
	
	// set to new core
	sched_setaffinity(p, len, &new_mask);
	printf("<New allocated CPU Core ID: %d>\n", sched_getcpu());
	
	printf("<Doing some work after fixing the cpu core...>\n");
	
	for (i = 0; i < numOfRepetition; i++) 
	{
		printf("[%3d/%3d] ", i+1, numOfRepetition);
		double elapsedTime = measureTime(currentCore = sched_getcpu());	// do work

		int newCore = sched_getcpu();	// what is current core after work?
		if (currentCore != newCore) // if the allocated cpu core is changed 
		{
			printf(" After work, my allocated CPU Core ID is moved to %d\n", currentCore = newCore);	
			cpuChanged++;
		}
	}
	printf("* Number of CPU core allocation change: %d (Out of %d trials, %.1lf%%)*\n", cpuChanged, numOfRepetition, (double) cpuChanged/(double) numOfRepetition*100.0);	
	return 0;
}

This code will execute measureTime() 30 times without cpu core fixed, then 30 times with cpu core fixed.
Each measureTime() takes some time, possibility of core allocation change, as shown in result.

How to run)

gcc cpu_affinity_user.c -o affinitytest
./affinitytest

Result)

Part 1 – CPU Core information, and initial allocated core

Total number of CPU Core: 4
Current allocated CPU Core ID: 1
(Current available CPU Core ID List: 0 1 2 3)

Part 2 – CPU core movement before fixing the cpu core

<Doing some work without fixing the cpu core...>
[  1/ 30] Work - My allocated cpu core is 1
 After work, my allocated CPU Core ID is moved to 0
[  2/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 1
[  3/ 30] Work - My allocated cpu core is 1
[  4/ 30] Work - My allocated cpu core is 1
 After work, my allocated CPU Core ID is moved to 0
[  5/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[  6/ 30] Work - My allocated cpu core is 3
[  7/ 30] Work - My allocated cpu core is 3
[  8/ 30] Work - My allocated cpu core is 3
[  9/ 30] Work - My allocated cpu core is 3
[ 10/ 30] Work - My allocated cpu core is 3
[ 11/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 2
[ 12/ 30] Work - My allocated cpu core is 2
 After work, my allocated CPU Core ID is moved to 3
[ 13/ 30] Work - My allocated cpu core is 3
[ 14/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 15/ 30] Work - My allocated cpu core is 0
[ 16/ 30] Work - My allocated cpu core is 0
[ 17/ 30] Work - My allocated cpu core is 0
[ 18/ 30] Work - My allocated cpu core is 0
[ 19/ 30] Work - My allocated cpu core is 0
[ 20/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[ 21/ 30] Work - My allocated cpu core is 3
[ 22/ 30] Work - My allocated cpu core is 3
[ 23/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 24/ 30] Work - My allocated cpu core is 0
[ 25/ 30] Work - My allocated cpu core is 0
[ 26/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[ 27/ 30] Work - My allocated cpu core is 3
[ 28/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 29/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 1
[ 30/ 30] Work - My allocated cpu core is 1
* Number of CPU core allocation change: 12 (Out of 30 trials, 40.0%)*

Part 3 – CPU core movement after fixing the cpu core

<Randomly assigning another core...>
<New allocated CPU Core ID: 0>
<Doing some work after fixing the cpu core...>
[  1/ 30] Work - My allocated cpu core is 0
[  2/ 30] Work - My allocated cpu core is 0
[  3/ 30] Work - My allocated cpu core is 0
[  4/ 30] Work - My allocated cpu core is 0
[  5/ 30] Work - My allocated cpu core is 0
[  6/ 30] Work - My allocated cpu core is 0
[  7/ 30] Work - My allocated cpu core is 0
[  8/ 30] Work - My allocated cpu core is 0
[  9/ 30] Work - My allocated cpu core is 0
[ 10/ 30] Work - My allocated cpu core is 0
[ 11/ 30] Work - My allocated cpu core is 0
[ 12/ 30] Work - My allocated cpu core is 0
[ 13/ 30] Work - My allocated cpu core is 0
[ 14/ 30] Work - My allocated cpu core is 0
[ 15/ 30] Work - My allocated cpu core is 0
[ 16/ 30] Work - My allocated cpu core is 0
[ 17/ 30] Work - My allocated cpu core is 0
[ 18/ 30] Work - My allocated cpu core is 0
[ 19/ 30] Work - My allocated cpu core is 0
[ 20/ 30] Work - My allocated cpu core is 0
[ 21/ 30] Work - My allocated cpu core is 0
[ 22/ 30] Work - My allocated cpu core is 0
[ 23/ 30] Work - My allocated cpu core is 0
[ 24/ 30] Work - My allocated cpu core is 0
[ 25/ 30] Work - My allocated cpu core is 0
[ 26/ 30] Work - My allocated cpu core is 0
[ 27/ 30] Work - My allocated cpu core is 0
[ 28/ 30] Work - My allocated cpu core is 0
[ 29/ 30] Work - My allocated cpu core is 0
[ 30/ 30] Work - My allocated cpu core is 0
* Number of CPU core allocation change: 0 (Out of 30 trials, 0.0%)*

 

[Ubuntu 14.04] Setting process affinity in kernel mode (1/2 – kernel modification)

Standard

Prerequisite)

Step 1 and 2 from http://study.prl85.com/building-ubuntu-kernel/
(=Ready to compile kernel)

Procedure)

1. Find the file containing sched_setaffinity function from non-compiled kernel source directory.
(In this case, kernel/sched/core.c)

bsw@bsw-P5K:~$ cd linux-3.13.0-orig/
bsw@bsw-P5K:~/linux-3.13.0-orig$ grep -R "long sched_setaffinity" *
include/linux/sched.h:extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask);
kernel/sched/core.c:long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)

2. In kernel/sched/core.c, add EXPORT_SYMBOL_GPL(sched_setaffinity); after the end of sched_setaffinity() definition.

long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
{
cpumask_var_t cpus_allowed, new_mask;
struct task_struct *p;
int retval;
...
out_unlock:
free_cpumask_var(new_mask);
out_free_cpus_allowed:
free_cpumask_var(cpus_allowed);
out_put_task:
put_task_struct(p);
return retval;
}
EXPORT_SYMBOL_GPL(sched_setaffinity);

3. In kernel/sched/core.c, add EXPORT_SYMBOL_GPL(sched_getaffinity); after the end of sched_getaffinity() definition.

long sched_getaffinity(pid_t pid, struct cpumask *mask)
{
        struct task_struct *p;
        unsigned long flags;
        int retval;

        rcu_read_lock();

        retval = -ESRCH;
        p = find_process_by_pid(pid);
        if (!p)
                goto out_unlock;

        retval = security_task_getscheduler(p);
        if (retval)
                goto out_unlock;

        raw_spin_lock_irqsave(&p->pi_lock, flags);
        cpumask_and(mask, &p->cpus_allowed, cpu_active_mask);
        raw_spin_unlock_irqrestore(&p->pi_lock, flags);

out_unlock:
        rcu_read_unlock();

        return retval;
}
EXPORT_SYMBOL_GPL(sched_getaffinity);

4. Build new kernel and reboot
(Refer to step 5~9 from http://study.prl85.com/building-ubuntu-kernel)

Reference)
http://stackoverflow.com/questions/1151285/setting-process-affinity-in-kernel-mode
http://study.prl85.com/building-ubuntu-kernel

[Ubuntu 14.04] Building Linux Kernel

Standard

Procedure)

1. Download kernel source of current version

apt-get source linux-image-$(uname -r)
bsw@bsw-P5K:~$ apt-get source linux-image-$(uname -r)

Reading package lists... Done
Building dependency tree
Reading state information... Done
Picking 'linux' as source package instead of 'linux-image-3.13.0-44-generic'
NOTICE: 'linux' packaging is maintained in the 'Git' version control system at:
http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-trusty.git
Need to get 125 MB of source archives.
Get:1 http://kr.archive.ubuntu.com/ubuntu/ trusty-updates/main linux 3.13.0-55.92 (dsc) [11.8 kB]
Get:2 http://kr.archive.ubuntu.com/ubuntu/ trusty-updates/main linux 3.13.0-55.92 (tar) [116 MB]
Get:3 http://kr.archive.ubuntu.com/ubuntu/ trusty-updates/main linux 3.13.0-55.92 (diff) [8752 kB]
Fetched 125 MB in 23min 56s (87.1 kB/s)
...
 linux-3.13.0/virt/kvm/async_pf.c
 linux-3.13.0/virt/kvm/coalesced_mmio.c
 linux-3.13.0/virt/kvm/ioapic.c
 linux-3.13.0/virt/kvm/iommu.c
 linux-3.13.0/virt/kvm/kvm_main.c

2. Configure build environment (one-time)

sudo apt-get build-dep linux-image-$(uname -r)
sudo apt-get update
sudo apt-get install curses-dev
bsw@bsw-P5K:~$ sudo apt-get build-dep linux-image-$(uname -r)
[sudo] password for bsw:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Picking 'linux' as source package instead of 'linux-image-3.13.0-44-generic'
The following NEW packages will be installed:
  asciidoc docbook-dsssl docbook-utils docbook-xml docbook-xsl gawk jadetex
  kernel-wedge libaudit-dev libdw-dev libdw1 libelf-dev libiberty-dev
  libnewt-dev libosp5 libostyle1c2 libsgmls-perl libslang2-dev libsp1c2
  libunwind8 libunwind8-dev lynx lynx-cur makedumpfile openjade sgml-data
  sgmlspl sp transfig xmlto xsltproc
0 upgraded, 31 newly installed, 0 to remove and 3 not upgraded.
Need to get 11.1 MB of archives.
After this operation, 51.3 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://kr.archive.ubuntu.com/ubuntu/ trusty/main gawk amd64 1:4.0.1+dfsg-2.1ubuntu2 [781 kB]
...
Setting up xmlto (0.0.25-2) ...
Setting up docbook-dsssl (1.79-7ubuntu1) ...
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
Setting up docbook-utils (0.6.14-3ubuntu1) ...
Processing triggers for libc-bin (2.19-0ubuntu6.6) ...

3. Confirm the location of kernel source (/linux-3.13.0)

Screen Shot 2015-06-16 at 10.34.18 PM

4. Example of kernel modification (keep settings) (in linux-3.13.0 directory)
cf) If you have things to modify, do that instead of this.
cf) If you don’t have things to change or just want to test kernel compile, then go to next step (step 5)

This takes the current configuration for each architecture/flavour supported and calls menuconfig to edit its config file. The chmod is needed because the way the source package is created, it loses the executable bits on the scripts.
(from https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel)

chmod a+x debian/scripts/*
chmod a+x debian/scripts/misc/*
fakeroot debian/rules clean
fakeroot debian/rules editconfigs

5. Build the kernel (might take awhile…) (in linux-3.13.0 directory)

fakeroot debian/rules clean
fakeroot debian/rules binary-headers binary-generic

6. Deb packages are created after successful build

cd ..
ls *.deb

Screen Shot 2015-06-17 at 12.16.00 AM

7. Before install deb packages, install linux-tools for right version (one-time)
(3.13.0-55 should be replaced to your kernel version)
(You might see errors when installing linux-tools, but that’s okay)

sudo apt-get install linux-tools-3.13.0-55
sudo apt-get install -f

8. Install these package to test new kernel (3.13.0-55.92 should be replaced to your kernel version, the string after generic_ and before _amd64)

sudo dpkg -i linux*3.13.0-55.92*.deb

When install deb packages, you should see messages like below (no errors)

...
Generating grub configuration file ...
Found memtest86+ image: /boot/memtest86+.elf
Found memtest86+ image: /boot/memtest86+.bin
Found linux image: /boot/vmlinuz-3.13.0-55-generic
Found initrd image: /boot/initrd.img-3.13.0-55-generic
Found linux image: /boot/vmlinuz-3.13.0-44-generic
Found initrd image: /boot/initrd.img-3.13.0-44-generic
Found linux image: /boot/vmlinuz-3.13.0-32-generic
Found initrd image: /boot/initrd.img-3.13.0-32-generic
Found Windows Recovery Environment (loader) on /dev/sda1
Found linux image: /boot/vmlinuz-3.13.0-55-generic
Found initrd image: /boot/initrd.img-3.13.0-55-generic
Found linux image: /boot/vmlinuz-3.13.0-44-generic
Found initrd image: /boot/initrd.img-3.13.0-44-generic
Found linux image: /boot/vmlinuz-3.13.0-32-generic
Found initrd image: /boot/initrd.img-3.13.0-32-generic
done
Setting up linux-tools-3.13.0-55-generic (3.13.0-55.92) ...

To confirm the deb packages are correctly installed (=you are ready to boot using the new kernel), type cat /boot/grub/grub.cfg | grep menuentry
You can see “Ubuntu with Linux 3.13.0-55-generic”, the version of compiled kernel.

Screen Shot 2015-06-17 at 12.56.52 AM

9. Reboot and print current kernel version

sudo reboot

After reboot, print current kernel version.

bsw@bsw-P5K:~$ uname -r
3.13.0-55-generic

Reference)
https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel
http://askubuntu.com/questions/270381/how-do-i-install-ncurses-header-files