1

In the G-WAN KV options, KV_INCR_KEY will use the 1st field as the primary key.

That means there is a function which increments atomically already built in the G-WAN core to make this primary index work.

It would be good to make this function opened to be used by servlets, i.e. included in gwan.h.

By doing so, ANSI C newbies like me could benefit from it.

Gil
  • 3,279
  • 1
  • 15
  • 25
k.k. lou
  • 1,805
  • 2
  • 13
  • 16
  • What is your question? How to have `KV_INCR_KEY` available to your C-based servlet? – tomlogic Nov 09 '12 at 04:53
  • in http: //gwan.com/api#kv, enum KV_OPTIONS { KV_GC_ALLOC = 1, // garbage collection, default behavior KV_PERSISTANCE = 2, // periodic file I/O (using kv_recfn() call-back) **KV_INCR_KEY** = 4, // 1st field:primary key (automatically incremented) ...}; – k.k. lou Nov 09 '12 at 07:44

2 Answers2

1

There was ample discussion about this on the old G-WAN forum, and people were invited to share their experiences with atomic operations in order to build a rich list of documented functions, platform by platform.

Atomic operations are not portable because they address the CPU directly. It means that the code for Intel x86 (32-bit) and Intel AMD64 (64-bit) is different. Each platform (ARM, Power7, Cell, Motorola, etc.) has its own atomic instruction sets.

Such a list was not published in the gwan.h file so far because basic operations are easy to find (the GCC compiler offers several atomic intrinsics as C extensions) but more sophisticated operations are less obvious (needs asm skills) and people will build them as they need - for very specific uses in their code.

Software Engineering is always a balance between what can be made available at the lowest possible cost to entry (like the G-WAN KV store, which uses a small number of functions) and how it actually works (which is far less simple to follow).

So, beyond the obvious (incr/decr, set/get), to learn more about atomic operations, use Google, find CPU instruction sets manuals, and arm yourself with courage!

Gil
  • 3,279
  • 1
  • 15
  • 25
  • Although atomic operations are not portable, but if gwan can run under my platform, gwan's internal atomic operations must can be reused in my serlvets too, since they have been compiled to fit my platform. **So, it is still reasonable to request to have such functions exported in gwan.h**. – k.k. lou Nov 09 '12 at 14:42
  • thanks for your explanation. Agree with you that we need to learn more about atomic operations. Gwan has already provided the kv store for atomic get/set. For web development, i seldom design sophisticated operations, so the obvious/basic atomic increment is still necessary for me, since i am not a programmer. i am a web developer. – k.k. lou Nov 09 '12 at 15:44
  • K. K. Lou, Look at the link (titled **"GCC compiler offers several aomic intrinsics"**) I gave in the answer above - here you have all you need for basic needs (including the increment by 1 that you requested). – Gil Nov 10 '12 at 07:30
  • thanks for your hyperlink. i am not sure whether they works in Tiny C Compiler or not, since i heard that gwan is using TCC to compile the C scripts and those functions are built in GCC compiler. Please correct me if i am wrong. Before starting to use those functions, i am searching for examples to learn how to use them. – k.k. lou Nov 10 '12 at 08:18
  • G-WAN uses GCC and *not* the Tiny C Compiler. – Gil Nov 10 '12 at 09:19
  • Do you mean that gwan uses GCC to compile the servlets and handlers when gwan is started? – k.k. lou Nov 10 '12 at 15:35
  • Yes, for C scripts that's GCC. For Java that's a JVM. For C# that's Mono. etc. – Gil Nov 11 '12 at 15:57
0

Thanks for Gil's helpful guidance.
Now, I can do it by myself.
I change the code in persistence.c, as below:
firstly, i changed the definition of val in data to volatile.

//data[0]->val++;  
//xbuf_xcat(reply, "Value: %d", data[0]->val);  
int new_count, loops=50000000, time1, time2, time;  

time1=getus();
for(int i; i<loops; i++){
    new_count = __sync_add_and_fetch(&data[0]->val, 1);
}
time2=getus();

time=loops/(time2-time1);
time=time*1000;

xbuf_xcat(reply, "Value: %d, time: %d incr_ops/msec", new_count, time);

I got 52,000 incr_operations/msec with my old E2180 CPU.
So, with GCC compiler I can do it by myself.
thanks again.

k.k. lou
  • 1,805
  • 2
  • 13
  • 16
  • Go work. Note that the keyword *volatile* is of no help with concurrency issues (it does not hurt but brings no advantage). In fact, it may be considered as deprecated on multicore systems. – Gil Nov 13 '12 at 08:04
  • 1
    Here is a great discussion about atomicity, locks, other strategies and each method is tested for speed with C source code: http://webfiveoh.com/content/features/2012/dec/sat-22nd/parallel-programming-the-third-way.html – Gil Dec 25 '12 at 08:51