Thursday, March 21, 2019

Change network interface name from enpxxx to ethX

Tags: CentOS, Consistent network device naming, GRUB
----------

The CentOS 7.X use the consistent network device naming scheme by default. That make the Ethernet interface appearing as enpxxx.

Somebody and some old tools do not like it. For example, some license daemons for EDA tools require the HostID as the MAC address of the ethX interface.

To switch it back to the old ethX naming scheme:

1. Disable the NetworkManager
# systemctl disable NetworkManager

2. Update the boot option in the /etc/default/grub file. Locate the GRUB_CMDLINE_LINUX line and then insert the "net.ifnames=0 biosdevname=0" in it. For example:
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos_bhem/root rd.lvm.lv=centos_bhem/swap net.ifnames=0 biosdevname=0 rhgb quiet"

Note: Make sure the GRUB_CMDLINE_LINUX line is a single line. No line break is allowed.

3. Make the boot option effective.
For BIOS boot:
# grub2-mkconfig -o /boot/grub2/grub.cfg
For UEFI boot:
# grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

4. Create configuration for the interface. For example:
# cd /etc/sysconfig/network-scripts/
# mv ifcfg-enp2s0 ifcfg-eth0
Then update the ifcfg-eth0 file, replacing 'enp2s0' by 'eth0'. For example:
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="dhcp"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="eth0"
UUID="a062bfa4-8820-4d64-bdeb-28b3f5052fce"
DEVICE="eth0"
ONBOOT="yes"

5. Reboot


Saturday, August 12, 2017

Speed test of file copy


Speed test of file copy: 1 GB random data file.

Linux:
2.7 GHz Intel Core i5-5257U
4 GB 1333 MHz DDR3
Realtek RTL8111 PCIe GbETH
CentOS 7

local copy: 6~9 sec, typical 8.5 sec ==> ~100 MBps
copy from SSD to USB: typical 20~21 sec ==> ~50 MBps
copy from USB to SSD: typical 5~10 sec ==> ~100 MBps


Mac:
MacBook 12-inch 2016
1.1 GHz Intel Core m3
8 GB 1867 MHz LPDDR3
macOS Sierra 10.12.6
5 GHz wireless network

SCP from Linux SSD to Mac: 20 sec ==> ~50 MBps
SCP from Mac to Linux SSD: 55~65 sec ==> ~16 MBps
SCP from Linux USB to Mac: 20 sec ==> ~50 MBps
SCP from Mac to Linux USB: 55~65 sec ==> ~16 MBps

Attacks on my home server

This is what my home server experienced in two days ... strangely I did not announce the my IP in anyway. The following are only attacks on SSH as that is the only port I forwarded. Have not checked the router log yet. It is a jar of worms I don't want to touch.

From: Aug 7 03:38:02
To: Aug 9 14:03:27
Total attacks: 185674
Unique IPs: 112
Top 10 IPs: (by number of login attempts)
85368 61.177.172.--
46557 116.31.116.--
16630 116.31.116.--
16098 58.242.83.--
10224 59.63.166.--
4587 61.177.172.--
1866 218.87.109.--
758 103.58.116.--
634 162.243.39.--
498 60.165.208.--
Total countries: 31
Top 10 countries: (by number of unique IPs)
35 CN
12 AR
7 US
7 KR
5 BR
4 RU
4 DE
3 SE
3 FR
3 EC
IPs tried valid user names: 86
Total valid user names: 10
Top 10 valid user names:
183372 root
13 nobody
13 bin
10 ftp
9 adm
7 operator
5 sshd
5 daemon
4 transmission
2 rpc
IPs tried invalid user names: 92
Total invalid user names: 317
Top 10 invalid user names:
646 admin
170 postgres
89 odoo
62 backup
55 pi
50 support
47 usuario
40 ubnt
33 service
33 oracle
Top 10 info:
"61.177.172.--", "Nanjing", "Jiangsu", "CN",
"116.31.116.--", "Shenzhen", "Guangdong", "CN",
"116.31.116.--", "Shenzhen", "Guangdong", "CN",
"58.242.83.--", "Hefei", "Anhui", "CN",
"59.63.166.--", "Nanchang", "Jiangxi", "CN",
"61.177.172.--", "Nanjing", "Jiangsu", "CN",
"218.87.109.--", "Nanchang", "Jiangxi", "CN",
"103.58.116.--", "Namakkal", "Tamil Nadu", "IN",
"162.243.39.--", "New York", "New York", "US",
"60.165.208.--", "Lanzhou", "Gansu", "CN",

Thursday, April 27, 2017

Release Wednesday

How to do continuous integration for hardware design -- a story of release Wednesday.

Background

Recently I come across this issue of performing continuous integration (CI) in hardware development flow (mostly RTL front end design). There are discussions of the tools and framework for this tasks. Most of the available tools are for software development. Thus it is not easy to chose one.

I am more concern of adapting the approach (or the common practices) of software CI flow to the hardware dev environment. The company I worked with has this software CI infrastructure in place for the RTL projects. Despite the large efforts put in it, the system did not generate many significant results (at lot less then what I expected). Without the incentives to maintain the system, it die a slow death.

We can spend a long day to discuss the differences between hardware and software development and be very academic about it. But what I want to present is another story happened in the same company.

Wednesday

It was in the early years and the concept of CI is not that popular (at least not in that hardware company). Projects still have the same need to regularly check the health of the code base. Without any fancy tools, we come up the the idea of release Wednesday.

Every Wednesday, the project technical lead (this is a role, not a title) will check with the engineers to see what can be (and should be, following the project schedule) ready for verification and integration. Then the technical lead will actively pull the modules in the main branch and allow the integration to produce a coherent and consist copy of the project code base. Once the release is process, nobody to mess with the revision control system until released.

It was a stress day. For the module developers, it is the time they have to present their work to the team. All the sloppy work, every stupid bugs and any schedule slip will be transparent to the whole team. For the technical lead, it is the most busy day. All conflicts between modules has to be resolved to prevent further diverse between modules. A lot of decisions (e.g. which feature to be integrated first, which conflicts can be grouped while resolving, when to notify the verification team for the quick tests) must be made to deliver the release. For the verification team, the pressure is on the quick turn around time. The release candidate (RC) is usually available mid-day. Then a battery of tests is run to assure the quality of the RC. There may be several iterations and thus several RC to be checked.

Work as a team is very much the reality of this day as everyone must focus on the release and standby for unexpected work (or rework).

Achievements

After the release, everyone can start working on a common code base which is known to work.

The verification team will check if the previously reported bugs/issues are resolved; if the planned features are integrated and functioning; if the there are any new bugs/issues introduced.

The front end developers can start working on new features. If their work depend on the features from others, this is a good time to check if it is presented and then plan the development work accordingly.

The technical lead has a very good understanding about the status of the code and the progress of the project. It is always a refresh of the functional and implementation specifications while integrating and resolving the integration conflicts.

Base on the reports from the technical lead, the project manager can then review the project schedule and plan the resources better for next week.

The end result of this Wednesday release is not different from the result of an automatic CI tool. The real benefit is the impact on the team members (i.e. the human). The difference is between waiting an machine generated integration/regress reports and involving actively in the integration progress. The exposure to the full project scale integration and focus of resolving issues with other teammates are the most valuable part. In my experience, everyone in the team get to know the project better each time and the release Wednesday is pretty smooth after the team gets used to the integration process.

There are very little noise generated in this approach when comparing to the automatic CI process. All involved persons are happier in this way during the project.

Notes

While adapting this approach, there are a few notes should be taken.

  1. The involved team size should not be too large. My experience is with a team across UK and India with less than 10 people. The actual number of engineers contributed to the code may be larger but they can select a representative person for this task (a single voice for a sub-team).
  2. The technical lead must have some degree of authority to make decisions impacting the project schedule. He/She also need to have very good knowledge in both specification requirements and the practical work of front-end development.
  3. The members of the team need to be self-motivated and understand the reasons behind this approach. They have to be in standby mode for the day and actively help resolving the issues even the issues may not be caused by their work.
  4. It must be a regular recurrent task. In the initial stage of the project, the integration work may be rough due the the large delta changes. In the later stage, there may be very minor updates within a week. All this should not be an excuse to skip the release Wednesday.


Wednesday, April 26, 2017

Verilog TestBench Design

I have be working on my side project of digital circuit design in Verilog for a while. One thing that bugs me and pops up regularly is the way to write a test. I have a few options here:

  1. I can go for the old school style to embedded the test as blocks of Verilog code in the testbench. This give me the largest flexibility in terms of precise control of the testing environment. But this is also the most troublesome style. It requires the test author to code in Verilog. It exposes the complexity and diversity of the DUT to the test author. It is difficult to build and hard to debug. It also require re-compilation for even the simplest change in the test.
  2. Most comercial Verilog simulator supports a build scripting engine which allows an interactive user experience through the simulator consoles. These include VCS, Incisive and ModelSim. TCL is the most commonly supported scripting language in these EDA tools. So one can build the complete test environment around this technology. The largest advantage is the easy of coding in a familiar syntax while maintaining fine control over the DUT through the TCL commands provided by the EDA tool. No recompilation is required. I have seen this approach in practical environment for IP design. It works very well, as long as you have paid for the simulator. Unfortunately, I cannot find any free Verilog simulator supporting this, not to said that I have to run it on my Macbook Air.
  3. UVM+SV is the trendy thingy in SoC/IP design. I sure you that there are tons of information you can get from Google telling its advantages. But again, I cannot find a free (either as beer or for speech) Verilog simulator supporting this.
  4. The approach I used is adapted from the company I worked for. The implementation is completely different by the underlying idea is the same. To write a standard test vector generator which will read in a text based test file. It then alters the signals connected to the DUT based on parsing the text file line by line. A simple programming language with a handful of instructions and a text editor are all you need to create and modify a test. This works fine until you try more complicate tests with branch and arithmetic operations
Now I am working on another approach which:
  • doest not require recompilation of the Verilog code (this is very important as we cannot assume the person who creates and runs the test will have access to the same Verilog compiler, also, you can ship binary instead of source code to the testing environment)
  • has a simple programming interface. It may not be as flexible and mature as TCL, but it should support simple looping and arithmetic operations.
  • is independent from the Verilog compiler and simulator. This will ensure the portability of the tests and allow future extension.

Tuesday, November 18, 2014

deque v.s. vector performance

Tested on my Macbook Air (OS X 10.10, 1.7GHz i5, g++, -O3):

average of 100 runs :
  each push_back() 1,000,000 times,
  then pop_back() 1,000,000 times,
  item size 64-bit.

deque performance : 95 ms
vector performance : 50 ms

  cout << "scheduler TB" << endl;
  Event e;
  deque<Event> eb;                                                         
  //vector<Event> eb;

  cout << "size = " << eb.size() << endl;

  for (j=0; j<100; j++) {
    gettimeofday(&t0, NULL);
    for (i=0; i<1000000; i++)
      eb.push_back(e);
    for (i=0; i<1000000; i++) {
        e = eb.back();
        eb.pop_back();
      }
    gettimeofday(&t1, NULL);
    t_d += (t1.tv_sec - t0.tv_sec) * 1000000 + (t1.tv_usec - t0.tv_usec);
  }

  cout << "size = " << eb.size() << endl;
  cout << "INFO: TB finished in " << t_d/100 << " us" << endl;

  eb.clear();

Saturday, July 13, 2013

Evaluating new tools/systems for project development.

Tag: SVN vs Perforce

I have to make a decision to select between SVN, Git and Perforce when creating a new project in Assembla. I know SVN well in previous work. I have been using Perforce extensively for work in the past 9 months. I have never type in a single Git command yet.

The final decision is Perforce. I concern a bit about the network requirement of Perforce due to it centralised workflow. I know how to make local changes without network and reconcile the workspace  later when network is available. Still this is not normal in the Perforce world.

Git is the first one out. The documents and terminologies are just not fit for my brain. And I don't need all this distributed feature. I am foreseeing only a handful of developers collaborating in the project. I don't think this Git thing is going to work for my future projects either. Just my personal opinion.

SVN is good enough. I don't think, as a version control backend, there is anything missing in SVN for me. The issue is on the front end side. I am now so used the the pretty UI in Perforce when tracking changes. I perform all the actual version control work in command line. But when it comes to 'Who had done what in where at when?' and about 'Where is the origin of this code and how it gets here?', the Perforce UI is a clear win.

There are front ends for SVN providing similar feature but the good ones are all paid software. Then why should I not using Perforce as a single, well integrated package?

During the decision making process, I come across somebody's suggestions which should also be valid for most tool/system selection situations. I will keep these in mind in the future.


  1. performance on typical usage, especially for remote sites
  2. resource requirements
  3. importance of the changes needed in the working habit
  4. support availability and cost

Friday, July 12, 2013

A serial bus for core configuration

In many of my pervious work using FPGA as an accelerator, I came across this situation.


  1. I need to configure the cores (usually parallel core with same or similar architecture) by writing configuration/parameter registers to the core.
  2. The same type of registers are use to sample the results or status of the cores.
  3. The master controlling the cores (by reading/writing the registers) is usually a soft CPU or a interface to the host PC.


Given the fact that all cores are in the same FPGA and we have balanced clock tree within the FPGA, de-skew and resynchronisation between the the master and the cores. This make things much easier. NOT!

In FPGA design, these registers are usually implemented in distributed memory (i.e. DFF primitive). This is sometime necessary since the contents of these registers are requires simultaneously (e.g. the parameters of a FIR filter). Then it is straight forward to allow them to be written simultaneously.

In an example design, we have 10 cores. Each core has 10 configuration/parameter/result registers. All registers are 32-bit. This is a design with 32*10*10=3200 signals (ignoring the read/write controls) just for the purpose of infrequent data communication.

Here comes the problem: The connection between the master and the cores make it difficult to meet the timing constraints or something impossible to pass P&R. We simply spend too much routing resources for something not relate to design performance.

Now you are thinking using a bus system to connect these registers to the master. And you create the address decoder in each core. This will relax the routing channel congestion since the number of signals now depends of the number of cores but not number of registers.

But the timing issue is still not solved. Putting a global decoder in the master and connect all registers in a single parallel bus will not work. First, some FPGAs have no tristate buffers for internal connection. So you end up in using more signals (for sending the read data back to the master). Also, the fan-out of the master output will be too high since it is going to drive all the cores. More importantly, we usually fill up the FPGA with parallel cores as much as possible. So these cores are all over the chip in different location. Thus the connection to the furthest away core dominate the critical path.

You are upset by the fact that you have a highly optimised design for computation but slowed down by a configuration bus. There are two options from here: to pipeline the bus between master and cores; or to use a slower clock for the configuration part.

The second approach will solve the issue once for all. But we have limited clocking resources in FPGA which is more valuable than DFFs and LUTs. It is also not easy to implement the synchroniser in FPGA. Using async BlockRAM for a handful of registers is another big waste. At the end, you also need to set special constraints for the STA tool to get the timing closure correct. If you are willing to go through all these troubles, why not just set the bus as multi-cycle path in timing constraints? Anyway, you cannot avoid asynchronous design in FPGA following this path.

The first approach is actually easier, with the help of auto retiming from the EDA tools. All it costs are some DFFs which should not be an issue in modern FPGAs. The issue is the latency which impacting the bus protocol. Since there is a latency between the write signal and the actual update of the registers in the cores. For example, the master must wait until the parameters are actually updated before sending the 'go' signal (usually a single wire) to the cores. It get more complicated if any kind of acknowledgement is required for the write operation (e.g. the full signal in FIFO interface, etc.).

What I am proposing here is a serial bus which has the following advantages:


  1. Running under the same clock shared by the master and the cores.
  2. Minimum number of signals (only two) between master and each core.
  3. Minimum control logic required for implementation.

It is going to have similar disadvantages as in the first approach above. But it can still save a lot of routing resources. It is also suitable for ASIC design where flip-flops are more valuable than in FPGA and the cost of retiming every buses is too high.

The details of this serial bus will be presented in the next post.

Wednesday, May 01, 2013

Cost Effectiveness of Acceleration

I have done may acceleration and optimisation jobs on various platforms. These include FPGA RTL level design, CUDA programming and parallel/distribute CPU cluster design.

It usually costs me weeks, if not months, to optimise a design in implementation level. I also need to know the hardware platform very well. This learning time can be considered as a one-off cost, for each platform. Finally, the optimised implementation needs constant upgrade to fully utilise the ever advancing computing platforms (CPU, GPU, compilers?!).

The question I keep asking myself is: 

    Is it wise to spend so much time and effort on optimisation or acceleration?

My answer is: It is wise if your application fits in (at least) one of the following categories:

  • Time is money.

Literally, time can be translated directly into currency. In some business, a few seconds advantage can easily payoff the salary of the engineering team. I have see real live examples and some of my friends are working exactly in these areas (high frequency trading, oil/gas exploration, etc.). As far as I know, both the bankers and the engineers are happy about the outcome. And the business is somehow forced to go in this direction: if somebody else is making money faster in the same market, it usually means that you are getting less at the same time.

But the value in time also easily renders the results valueless in short time. When it is so critical to produce a useable result before the raw data becomes out-dated, the latency becomes the bottleneck. Conventional high performance computing (HPC) methodologies, which emphasis on throughput, are not applicable here. And the physical limitation (e.g. the speed of light) will eventually stall the race to the lowest latency.

My opinion: It is a fast growing area but it may grow to its end sooner than we thought.

  • Repetitively running jobs.

Considering all the overheads in a real word application, including disk I/O, memory copies, process synchronisation and data preparation, we seldom see over 10x speedup in overall execution time. It's simple math that if the portion (in term of execution time) of the application which can be accelerated is less than 90%, the maximum achievable speedup is already less then 10x. If the resulting application is run once per month, most people won't care if it is 2 hours or 20 hours.

But if the resulting application is ran every hour by every staff of a reasonable size team, even a humble 1.5x improvement will save you a significant amount of man-month in the business. Also, the target end users in this category are easily satisfied by that 1.5x speedup, for a very long time. (I will be crazily happy if Xilinx would speedup the place-an-route process for 1.5x.) This category also includes the software industry where copies of a single product is sold in tens of thousands.

My opinion: It is worth doing but you don't usually see big excitement in it.

  • Framework development.

This is for the developers or consultants who is planning to make a living in application acceleration. It is worth to plan well for each platform and create a framework which you can reuse in later projects. Again, it is a larger up-front payment for repetitive (development) jobs.

Apart form these, I don't see why one should spend weeks in acceleration. Pay for a good compiler, use an optimised library, and play with the compilation options will easily give one big improvement.

Sunday, February 17, 2013

Resize image files in batch (in Mac)

Tags:

JPEG resize, image resize, Mac OS X, Mountain Lion, Preview


Problem:

I have a few photo (taken by my digital camera) and want to upload them to Picasa. But the images are too large (in both geometry size and file size). I want to scale them down before uploading.


Solution:

1. Select all files in a Finder window (Command-click or Shift-click for multiple files).
2. Right click on one of the selected file and select "Open With" -> "Preview".
3. In the Preview window, multiple files are shown as multiple pages on the side bar on the left.
4. Select all opened files by "Command-A" on the side bar.
5. Select from the menu bar: "Tools" -> "Adjust Size ...".
6. There you can change size. I selected the "Fit into: 1280x1024 pixels". Yours may be different.
7. Click "OK" to close the Adjust Size window.
8. Finally, "Save" the files and quit Preview.


Result:

The files are changed from 5MB to 256KB in file size while displayed perfectly in the web browser.

Thursday, January 31, 2013

Get WAN IP in one line command

If the local host is behind firewall and/or there is NAT in between, ifconfig may not report the correct IP address which is seen externally.

The following (one line) command prints out the WAN side IP.

# curl -s http://checkip.dyndns.org | sed -e 's/.*: //;s/<.*//'

Sunday, January 13, 2013

Expect: interact with external program with script

The following script calls an external program and interact with this external program by controlling the inputs and outputs of it.

The script first create call the external program 'dc', which is a postfix based calculator.
Then it send the string "4p\r" as input to the 'dc' program.
In the expect block, the script try to match two patterns: "0\r" and any digit followed by a carry return.
If the output of 'dc' is 0, then the script terminates it by sending the command "q".
If the output of 'dc' is any digit larger then 0 (starting from 4 in this example), the value will be decreased by sending "1-p" to 'dc'.


#!/usr/bin/expect -f

spawn dc      
send "4p\r"   

expect {

  "0\r" {
    puts "Expect: matched $expect_out(0,string)";
    send "q\r"
    puts "Expect: exit";
  }

  -re {[1-9]\r} {
    puts "Expect: matched $expect_out(0,string)";
    send "1-p\r";
    puts "Expect: reduce by 1";
    exp_continue
  }

}

Running the script will generated the following output on screen.


$ ./script.exp
spawn dc
4p
4
Expect: matched 4
Expect: reduce by 1
1-p
3
Expect: matched 3
Expect: reduce by 1
1-p
2
Expect: matched 2
Expect: reduce by 1
1-p
1
Expect: matched 1
Expect: reduce by 1
1-p
0
Expect: matched 0
Expect: exit


Notes:

1. Except captures all output from the external program including '\r'.
2. Variable $expect_out(0,string) stores the matched string from the immediate previous matching.
3. Variable $expect_out(buffer) stores the remaining output of the external program by removing all characters up to (and including) the matched string from the immediate previous matching.

Tuesday, January 08, 2013

Interface between C and TCL : Case III

Extending TCL script by C functions. The C functions are compiled as dynamic loaded library and is called from within a TCL script. The script can be interpreted by a standard TCL shell.

The C library is listed below.

#include <stdio.h>
#include <tcl.h>

int my_cmd1 (ClientData cdata, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[]) {
  printf("Hello, world!\n");
  return TCL_OK;
}

int my_cmd2 (ClientData cdata, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[]) {
  printf("Hello, again!\n");
  return TCL_OK;
}

// The function name must matches the dynamic library name.
// With the first letter in capital form and a "_Init" postfix.
int My_cmd_Init (Tcl_Interp *interp) {

  if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL)
    return TCL_ERROR;

  Tcl_CreateObjCommand(interp, "my_cmd1", my_cmd1,
      (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );

  Tcl_CreateObjCommand(interp, "my_cmd2", my_cmd2,
      (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );

  return TCL_OK;
}

To compile this file into a dynamic library (in Mac OS X 10.8.2), run the following line:

gcc -Wall -shared -o my_cmd.dylib my_cmd.c \
  -undefined dynamic_lookup -rdynamic

The expected output is:

$ tclsh
% load ./my_cmd.dylib
dlsym(0x7fb5dbe02360, My_cmd_SafeInit): symbol not founddlsym(0x7fb5dbe02360, My_cmd_Unload): symbol not founddlsym(0x7fb5dbe02360, My_cmd_SafeUnload): symbol not found
% my_cmd1
Hello, world!
% my_cmd2
Hello, again!
% exit

The "symbol not found" error can be safely ignore for this simple example.

Interface between C and TCL : Case II

C main function create an interactive TCL shell. The program terminates after the TCL shell is terminated and will not return control to C.

The C main function is listed below.

#include <stdio.h>
#include <tcl.h>

// A dummy initialisation.
int Tcl_AppInit(Tcl_Interp *interp) { return 0; }

int main(int argc, char *argv[]) {

  printf("In C start\n");
  Tcl_Main(argc, argv, Tcl_AppInit);
  printf("In C end\n");   // This line will never be executed.

  return 0;
}

The program is compiled by:

gcc -Wall -o main main.c -ltcl

The expected output is:

$ ./main
In C start
% puts "hello"
hello
% exit

Interface between C and TCL : Case I

C main program calls TCL interpreter to run an external TCL script. C and TCL communicate through variable values. TCL can call C function.

The C main program is listed below.

#include <stdio.h>
#include <tcl.h>

// a function to be called from within the TCL script
int my_func (ClientData data, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[]);

int main(void) {

  Tcl_Interp *interp = NULL;

  interp = Tcl_CreateInterp();
  if (interp)
    printf("In C: TCL interpretor started.\n");

  Tcl_CreateObjCommand(interp, "my_cmd", my_func, 
      (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );

  printf("In C: TCL script begin.\n");
  if (Tcl_EvalFile(interp, "simple.tcl") == TCL_OK)
    printf("In C: TCL script end.\n");

  printf("C says: Hello, %s!\n", Tcl_GetVar(interp, "name", 0));

  Tcl_DeleteInterp(interp);
  if (Tcl_InterpDeleted(interp))
    printf("In C: TCL interpretor stopped.\n");

  return 0;

}


int my_func (ClientData data, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[]) {
  int i;

  printf("In C: my_func() started.\n");
  printf("  obj[0] = %s.\n", Tcl_GetString(objv[0]));
  printf("  obj[1] = %s.\n", Tcl_GetString(objv[1]));
  if (Tcl_GetIntFromObj(interp, objv[2], &i) == TCL_OK)
    printf("  obj[2] = %d.\n", i);
  else
    printf("  obj[2] is not a integer!\n");
  printf("  obj[3] = %s.\n", Tcl_GetString(objv[3]));
  printf("In C: my_func() ended.\n");

  return TCL_OK;
}

The TCL script is listed below.

#!/usr/bin/tclsh

puts "Tcl calls: my_cmd (implemented as a C function)"
my_cmd abc +123 xyz

puts "----"

puts "Tcl asks: What is your name? "
gets stdin name

The program is compiled by (in Mac OS X 10.8.2) :

gcc -Wall -o main main.c -ltcl

The expected output is (in Mac OS X 10.8.2) :

$ ./main 
In C: TCL interpretor started.
In C: TCL script begin.
Tcl calls: my_cmd (implemented as a C function)
In C: my_func() started.
  obj[0] = my_cmd.
  obj[1] = abc.
  obj[2] = 123.
  obj[3] = xyz.
In C: my_func() ended.
----
Tcl asks: What is your name? 
Brittle
In C: TCL script end.
C says: Hello, Brittle!
In C: TCL interpretor stopped.

Wednesday, November 07, 2012

Mac OS X Preview reduce PDF size

Problem:

I have some (scanned) PDF documents which is a bit large (in a few MB) and want to reduce their size. The Preview app in Mas OS X has the function to reduce the PDF size but the resulted output is not clear enough to be useful.

To reduce PDF size in this way, we first open the PDF file in Preview. The select "File" -> "Export...". In the "Quartz Filter" option, select "Reduce File Size" and then "Save" the file with a new name. In one example, a 1.4MB colour scanned file is reduced to 65KB but the text is hardly readable.


Configuration:

Mac OS X 10.8.2


Solution: 

Open the "ColorSync Utility" from the "Applications" -> "Utilities" folder. On the lower left corner, click the "+" icon to add a new filter. You can name it as "PDF downsize".

Select this new filter and click the down arrow icon on the right. Select "Add Image Effects Component" -> "Color Image Sampling". In the newly created "Image Sampling" component, set the followings:

Scale : 100%
Resolution : <empty> Pixels / inch
Max : 1684 Pixels
Min : 512 Pixels
Quality : High

Click the down arrow icon again, this time, select "Add Image Effects Component" -> "Image Compression". In the newly created "Image Compression" component, set the followings:

Mode : JPEG
Quality : slide to around 25% towards Min

After these modifications, the "ColorSync Utility" can be closed.

Finally, open a terminal window (by "Applications" -> "Utilities" -> "Terminal". Then run the following command. Enter you root password if asked.

sudo mv ~/Library/Filters/PDF\ downsize.qfilter  /Library/PDF\ Services/

Now, you can select the "PDF downsize" filter in Preview and the above mentioned example is reduced from 1.4MB to 353KB with very readable result.

Tuesday, November 06, 2012

Disable auto generation of ~/Desktop ~/Documents ~/Downloads etc.

I prefer mwm and don't want any of the Gnome/KDE stuff on my (CentOS 6.3) desktop. But the system keep regenerating the following folders in my home directory.

Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos

Solution:

Edith /etc/xdg/user-dirs.conf to set "enabled=False". Then remove the above directories and relogin again. Done!

Saturday, November 03, 2012

Problem of X11 forwarding

Problem:

When connected using the -X or -Y option with ssh, the following error is reported.

/usr/bin/xauth:  timeout in locking authority file /home/<user>/.Xauthority


Cause:

It is in fact caused by incorrect SELinux setting.


Solution:


# ls -alZ
drwxr-xr-x. uid gid   unconfined_u:object_r:home_root_t:s0 <user>
# chcon unconfined_u:object_r:user_home_t:s0 <user>
# ls -alZ
drwxr-xr-x. uid vid   unconfined_u:object_r:user_home_t:s0 <user>

Then login again, the xauth will create the .Xauthority automatically.

Wednesday, October 24, 2012

Macbook Air fan goes crazy

Scenario:

Out of nowhere, the fan of my Macbook Air goes crazy from time to time. Even I have been doing nothing but looking at the blank desktop wallpaper! Huge fan noise and the upper left corner of the Air (near the power inlet) becomes really hot.


Configuration:

2011 MacBook Air with 1.7GHz Intel Core i5, 4GB RAM and Mac OS X 10.8.2


Cause:

Checking at the activities in the machine, I found this process (displayed by the top command):

USER             PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
khtsoi           501  98.8  1.6  2606200  67320   ??  Rs    4:07PM   0:05.10 com.apple.quicklook.satellite

After searching the "Quicklook" and "Satellite" keywords in the Internet, some one suggested that the cause is Quicklook tries to call QuickTime to generate thumbnails for video files which are not supported by the QuickTime codec.

Then I realised that this process re-spawns itself every time when I click on the "Downloads" folder icon in the Dock. The default action of this click is to expand the folder contents in grid mode. Even I did not have any video/audio files in that folder, I noticed that the thumbnail of a M$ Word file is not rendered. All files after this Word file are also displayed as an empty box without the thumbnail image.

So, I fired up the "Activity Monitor" tool from the "Utilities" folder, select on the "QuickLookSatellite-general" process and click the "Inspect" icon from the tool bar. Under the "Open Files and Ports" tab, I confirm that the last thing this process trying to read is that M$ Word file.


Solution:

Everything is fine after removing the Word file from the "Downloads" folder. I can open that file with the M$ Word correctly and that file is 13MB. There are other M$ Word files in the same folder but they have never caused similar problem.


Edit: one more step to really get rid of the noise (in software level).

Problem:

The fan still goes crazy and the Air is still hot even the quick lock.satellite is gone. There is no heavy duty process showing up in top or the "Activity Monitor". But I notice there are something wrong in the system log. I found the following three errors message keep showing up in the system log (by going to "Applications" -> "Utilities" -> "Console" and select the "All Messages".)


mdworker[1626]: Unable to talk to lsboxd

sandboxd[1633]: ([1631]) mdworker(1631) deny mach-lookup com.apple.ls.boxd

kernel[0]: Sandbox: sandboxd(1627) deny mach-lookup com.apple.coresymbolicationd


Cause:

I don't know and I don't care. It's better to leave it to Apple to explain it to its customers.


Solution:

Step 1: Modify the system configure file (you need to be root to do so). Edit the /System/Library/Sandbox/Profiles/system.sb file to append the following three lines at the end:


;;; FixSandboxErrors
(allow mach-lookup (global-name "com.apple.ls.boxd"))
(allow mach-lookup (local-name "com.apple.ls.boxd"))

Step 2: Clear the cache (you need to be root to do so) by running the following command.

rm -fr /System/Library/Caches/*

Step 3: Safeboot the Mac.
 - Shutdown the Mac first (remember to enable speaker volume before shutdown).
 - Start up the Mac. Just after the startup tone (cannot do it before the tone), press and hold the shift key.
 - When the grey apply logo appears, release the shift key.
 - After the system is up to the login screen, confirm that there is a red "safeboot" label at the upper right screen corner.
 - Then you can simply restart the Mac.

Enjoy the Mac without the fan noise.

Monday, October 22, 2012

problem of ICC (ld: cannot find -lpthread)

Problem:

I cannot compile my old project using the Intel Compiler. The error reported is

ld: cannot find -lpthread

Cause:

Playing with the pthread library is not helpful. The real problem is the "-fast" option which enables "-xHOST -O3 -ipo -no-prec-div -static" by default.

But my current OS is CentOS 6.3 which hates static library. So the last "-static" option is the cause of the problem.

Solution:

Replace the "-fast" with "-O3 -ipo -no-prec-div".