|Linux| Synchronization: mutex v.s. semaphore

If you use multi-threads to do something at the same time, that is a Synchronization.
You need to control threads to avoid Race Condition and Critical Section.
mutex and semaphore can solve the critical section.
But what’s different?

Mutex is an object and binary semaphore .

A semaphore is a signal, and a thread that is waiting on a semaphore can be signaled by another thread (more then 2 threads).
But you should notice that the wait and signal operations require to be executed in the correct order. Nevertheless, deadlocks will occur in semaphore.

Roughly, a mutex would be referred to as binary semaphore.
There are many dufferences, you may refer to this website.
https://www.guru99.com/mutex-vs-semaphore.html

How can we use semaphore?

// header
#include <semaphore.h>
class Foo {
    private:
        //declaration
        sem_t firstDone;
        sem_t secondDone;
    
    public:
        Foo() {
            // initialize
            sem_init(&firstDone, 0, 0);
            sem_init(&secondDone, 0, 0);
        }

        void first(function<void()> printFirst) {
            printFirst();
            //broadcast signl: first has done
            sem_post(&firstDone);
        }

        void second(function<void()> printSecond) {
            // waiting the signal from firstDone
            sem_wait(&firstDone);
            printSecond();
            //broadcast signl: second has done
            sem_post(&secondDone);
        }

    void third(function<void()> printThird) {
            // waiting the signal from secondDone
            sem_wait(&secondDone);
            printThird();
    }
};

Ref.
https://www.guru99.com/mutex-vs-semaphore.html
https://sls.weco.net/node/21326
https://jasonblog.github.io/note/linux_system/mutex_yu_semaphore_zui_da_de_cha_yi_shi.html

|C/C++| What are argc and argv ?

In main function, there are two parameters, argc and argv.

int main( int argc, char **argv)

argc := argument count, which is the number of parameters.
argv := argument value, which assign by terminal from user.
argv[0] := the name of this program
argv[1], argv[2] := enter by user


Test:

#include <stdio.h>

int main( int argc, char **argv ){
    int i = 0;
    printf( “argc = %d\n”, argc);
    for( i=0; i!=argc; ++i){
        printf( “argv[%d] = %s\n”, i, argv[i] );
    }
    return 0;
}

|C/C++| Use dlopen and dlsym to get handler of dynamic library(.so)

If you have a dynamic library (libtest.so) and there is a function (int test_foo(float)) in this library, how can I reuse the function in another library?

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(int argc, char **argv)
{
   void     *handle;
   
   // An function pointer, for point to test_foo
   int   (*test_foo_pointer)(float);
   char     *error;

   //open the target library libtest.so
   handle = dlopen("libtest.so", RTLD_LAZY);
   if (!handle) {
       fprintf(stderr, "%s\n", dlerror());
       exit(EXIT_FAILURE);
   }

   dlerror();    // Clear any existing error


   // get test_foo and assign to test_foo_pointer 
   test_foo_pointer = dlsym(handle, "test_foo");
   
   if ((error = dlerror()) != NULL)  {
       fprintf(stderr, "%s\n", error);
       exit(EXIT_FAILURE);
   }

   dlclose(handle);
   exit(EXIT_SUCCESS);
}


|Android| How was the Android system after power up?

This article will stand on high level to scan initialization modules.

User press power key ……

First, Boot ROM
 - Loads the BootLoader into RAM and starts executing.

Second, BootLoader
 - Start up and find the system kernel.
 - Bootloader is a place where manufacturers put their locks
  and restrictions.
 - Detects external RAM
 - Setups the network, memory … etc, which requires to run Kernel.

Third, Kernel
 - Setup cache
  Protected memory
  Scheduling
  Loads drivers
  Starts kernel daemons
  Mounts root file system
  Initializing Input/Output
  Starts interrupts
  Initializes process table ……
 - Looks for “init” in system files
 - Launch root process

Forth, Init
 - Mounts directories like /sys, /dev or/proc
 - Runs /init.rc script. The init.rc is responsible for the initial set up of the system.

Fifth, (Android) Zygote: 
 - VM process that starts as the system boots
 - app_process launces Zygote

Sixth, SystemServer
 - Load a native library called android_servers

ref. for Android: https://maoao530.github.io/2017/01/06/android-start/

refs.
https://blog.csdn.net/a4262562/article/details/76779236
https://danielmaker.github.io/blog/linux/start_kernel.html
https://cjworld1208.pixnet.net/blog/post/8014497
http://embeddedvenkatpari.blogspot.com/2016/05/how-to-load-firmware-using-pil.html?m=1
https://www.twblogs.net/a/5b8d19262b717718833b2c22
http://albert-oma.blogspot.com/2016/07/embedded-u-boot.html?m=1

|Telephony| Initialize com.android.phone

This article will focus on Telephony framework and Phone App initialization flows.
There are many key words arranged by initial steps.

Android Q.

First, you should know the role of “SystemServer” in Android.
 - ActivityManagerService up

Second, (Service) Telecom service
 - TelecomLoaderService loads Telecom service
 - path: /android/applications/sources/services/Telecomm/
     /android/frameworks/base/telecomm/

Third, (APP) Create PhoneAPP
 - (see AndroidManifest.xml, android:persistent=”true”)
  PhoneAPP will reborn after killed
 - path: /packages/services/Telephony/…/PhoneApp.java

Forth, (Framework) PhoneFactory brings up GsmCdmaPhone
 - onCreate() in PhoneApp, it will create PhoneGlobals
 - Initialize PhoneFactory.makeDefaultPhones
 - Create monitor service tracker, including ServiceStateTracker, CallTracker, …, and RIL

ref.
Telephony解析之整体架构简介
Telephony解析之Phone启动流程

|Java| Say Hello to JNI

Although Java is easy to transfer platforms, we still need some C++/C libraries to control drivers or basic modules.

JNI can be an interface between Java and C++/C.
The following article will teach you step by step.

OS: Ubuntu 18.04
Java: Open JDK 8


Step 1. Implement Java: HelloWorldJNI.java

class HelloWorldJNI {
    private native void printByC();
    public static void main(String[] args) {
        new HelloWorldJNI().printByC();
    }
    static {
        System.setProperty("java.library.path", "~/Desktop/JNI/");
        System.loadLibrary("HelloWorldJNI");
    }
}

Step 2. Generate Class and Header
(open your terminal)
$ javac HelloWorldJNI.java
$ javah -jni HelloWorldJNI

Then HelloWorldJNI.class and HelloWorldJNI.h are created.

HelloWorldJNI.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorldJNI */

#ifndef _Included_HelloWorldJNI
#define _Included_HelloWorldJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorldJNI
 * Method:    printByC
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorldJNI_printByC
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Step 3. Implement your C++/C library: HelloWorldJNI.c

#include <jni.h>
#include <stdio.h>
#include "HelloWorldJNI.h"

JNIEXPORT void JNICALL Java_HelloWorldJNI_printByC (JNIEnv *env, jobject obj){

    printf("Hello from C\n");
    return;
}

Step 4. Build C++/C library as .so
(open your terminal)
$ gcc -shared -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux HelloWorldJNI.c -o libHelloWorldJNI.so

The name ,”lib“+name.so, is important because the definition of “System.loadLibrary” will recognize “lib”.

Step 5. Test
(open your terminal)
$ java HelloWorldJNI


OUTPUT:
$ Hello from C

https://github.com/zivww/HelloJNI

WordPress.com.

Up ↑