Change VNC client into a secondary display for Linux
Tuesday, May 12, 2020
My Environment Intel i5-7200u (KabyLake) and HD Graphics 620 Debian GNU/Linux bullseye(testing) linux kernel 5.6.7 I have both Wayland and Xorg on my laptop and chose Gnome on Xorg from GDM login interface Laptop built-in screen (1920 x 1080 60Hz) iPad mini5 (2048 x 1356 60Hz) Requirement x11vnc (only works for Xorg, hasn’t supported Wayland yet) xrandr cvt Step 0x00: add a virtual monitor I took this snippet from StackOverflow…more
Producer-consumer problem
Sunday, March 29, 2020
https://www.wikiwand.com/en/Producer%E2%80%93consumer_problem Code As the title, I made some chaotic C code. #include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <pthread.h> /* output level flags */ #define INFO #define DEBUG #define CONSUMER_NUM (8) #define PRODUCER_NUM (2) #define ITEM_NUM (256) #define CONSUMER_LOOP (ITEM_NUM / CONSUMER_NUM) #define PRODUCER_LOOP (ITEM_NUM / PRODUCER_NUM) #define BUFFER_SIZE (8) typedef struct buffer { pthread_mutex_t buffer_lock; /* lock protecting the buffer struct */ pthread_cond_t fill; /* buffer has at least one item in it */ pthread_cond_t empty; /* buffer has at least one empty slot */ int space[BUFFER_SIZE]; /* circular buffer space limited by BUFFER_SIZE */ int fill_offset; /* used by producer */ int use_offset; /* used by consumer */ int count; /* item number now in buffer */ } buffer_t; /* store thread IDs */ typedef struct consumers { pthread_t thread_id[CONSUMER_NUM]; } consumers_t; typedef struct producers { pthread_t thread_id[PRODUCER_NUM]; } producers_t; static inline bool buffer_empty(buffer_t *buf) { return (buf->count == 0); } static inline bool buffer_full(buffer_t *buf) { return (buf->count == BUFFER_SIZE); } buffer_t *init_buffer(buffer_t *buf) { pthread_mutex_init(&(buf->buffer_lock), NULL); pthread_cond_init(&(buf->fill), NULL); pthread_cond_init(&(buf->empty), NULL); buf->fill_offset = 0; buf->use_offset = 0; buf->count = 0; #ifdef INFO printf("[INFO]: Initialized buffer with %d slots\n", BUFFER_SIZE); #endif return buf; } void put(buffer_t *buf, int value) { int fill = buf->fill_offset; buf->space[fill] = value; buf->fill_offset = (fill + 1) % BUFFER_SIZE; buf->count++; #ifdef INFO printf("[INFO]: Put %d into buffer\n", value); #endif } int get(buffer_t *buf) { int use = buf->use_offset; int value = buf->space[use]; buf->use_offset = (use + 1) % BUFFER_SIZE; buf->count--; #ifdef INFO printf("[INFO]: Get %d from buffer\n", value); #endif return value; } void *producer(void *args) { buffer_t *buf = (buffer_t *)args; for (int i = 0; i < PRODUCER_LOOP; i++) { pthread_mutex_lock(&(buf->buffer_lock)); while (buffer_full(buf)) { pthread_cond_wait(&(buf->empty), &(buf->buffer_lock)); } put(buf, i); pthread_cond_signal(&(buf->fill)); pthread_mutex_unlock(&(buf->buffer_lock)); } return NULL; } void *consumer(void *args) { buffer_t *buf = (buffer_t *)args; for (int i = 0; i < CONSUMER_LOOP; i++) { pthread_mutex_lock(&(buf->buffer_lock)); while (buffer_empty(buf)) { pthread_cond_wait(&(buf->fill), &(buf->buffer_lock)); } int value = get(buf); pthread_cond_signal(&(buf->empty)); pthread_mutex_unlock(&(buf->buffer_lock)); } return NULL; } void create_consumer(buffer_t *buf, consumers_t *csm) { for (int i = 0; i < CONSUMER_NUM; i++) { pthread_create(&(csm->thread_id[i]), NULL, consumer, buf); } } void join_consumer(consumers_t *csm) { for (int i = 0; i < CONSUMER_NUM; i++) { pthread_join(csm->thread_id[i], NULL); } } void create_producer(buffer_t *buf, producers_t *prod) { for (int i = 0; i < PRODUCER_NUM; i++) { pthread_create(&(prod->thread_id[i]), NULL, producer, buf); } } void join_producer(producers_t *prod) { for (int i = 0; i < PRODUCER_NUM; i++) { pthread_join(prod->thread_id[i], NULL); } } int main(void) { buffer_t *buf = (buffer_t *)malloc(sizeof(buffer_t)); if (buf == NULL) { #ifdef DEBUG printf("[ERROR]: Failed to allocate memory space for buffer.…more
Tower of Hanoi problem
Sunday, March 29, 2020
Solution in C #include <stdio.h>#include <assert.h> /* To debug, define SIMULATE DEBUG or SIMULATE DEBUG ASSERT */ #define PILLAR_SIZE 10 #define PILLAR_NUM 3 #define PLATE_NUM 5 typedef struct hanoi_tower { int pillars[PILLAR_NUM][PILLAR_SIZE + 1]; /* position 0 will not be used*/ int offsets[PILLAR_NUM]; } hanoi_tower; typedef enum pillar {x, y, z} pillar; char pillar_names[PLATE_NUM] = {'x', 'y', 'z'}; typedef int counter; void status(hanoi_tower *ht) { for (pillar i = x;…more
Erect a SQL playground with docker compose
Friday, March 20, 2020
Docker Compose Modify this docker-compose.yml on your need. version: '3.0' services: db: image: postgres:12.2-alpine restart: always volumes: - ./.persistence/db:/var/lib/postgresql/data environment: - POSTGRES_USER=kowalski # optional, "postgres" will be taken by default - POSTGRES_PASSWORD=114514 # modify it dashboard: image: dpage/pgadmin4:latest restart: always volumes: - ./.persistence/dashboard:/var/lib/pgadmin environment: - PGADMIN_DEFAULT_EMAIL=kowalski@local.domain # modify it - PGADMIN_DEFAULT_PASSWORD=114514 # modify it ports: - 80:80 depends_on: - db Persistence ./.persistence will be mounted for data persistence. pgAdmin runs as the pgadmin user (UID: 5050) in the pgadmin group (GID: 5050) in the container.…more
0x04 A glance into the kernel: turnstile
Sunday, March 15, 2020
/sys/sys/proc.h Thread and Turnstile line 228 A thread may block for a short , medium, or long period of time depending on the reason that it needs to wait. A short wait occurs when a thread need to wait for access to a lock that protects a data structure. A medium wait occurs while a thread waits for an event that is expected to occur quickly such as waiting for data to be read from a disk.…more
0x03 A glance into the kernel: Proc source
Friday, February 28, 2020
/sys/sys/proc.h My machine Linux debian-laptop 5.4.0-4-amd64 #1 SMP Debian 5.4.19-1 (2020-02-13) x86_64 GNU/Linux Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 39 bits physical, 48 bits virtual CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 2 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 142 Model name: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz Stepping: 9 CPU MHz: 3100.…more
0x02 A glance into the kernel: Overview on kernel services
Wednesday, February 26, 2020
Exercises I’d write down my own answers, please point out my errors with no mercy. I have to think more on these questions. Q1 Describe a scenario in which the timer-wheel algorithm used for the callout queue does not work well. Suggest an alternative data structure that runs more quickly than does the timer-wheel algorithm for your scenario. Q2 The SIGPROF profiling timer was originally intended to replace the profil system call to collect a statistical sampling of a program’s program counter.…more
为 Netlify 构建设定时区
Wednesday, February 26, 2020
起因 本站是在 Netlify 平台上自动用 Hugo 静态构建的,Hugo 目前还不支持通过配置文件指定用户时区,并且不会构建当前服务器时区时间之后的文章。 方法 Netlify 支持给…more
0x01 A glance into the kernel: Overview on kernel services
Monday, February 24, 2020
Exercises I’d write down my own answers, please point out my errors with no mercy. Q1 When can a routine executing in the top half of the kernel be preempted? When can it be interrupted? The top half of the kernel provides services to processes in response to system calls or traps. And the FreeBSD kernel is rarely preempted to run another user process while executing in the top half of the kernel.…more
0x00 A glance into the kernel: Overview
Thursday, February 20, 2020
Overview As a newcomer to the OS world, I just read Operating System: Three Easy Pieces, grasped some basic terminologies and general ideas. Rather than a detailed textbook, it’s more like an index of those renowned papers. Now it’s time to dive deeper into the real world code, I decide to view the recent kernel source of FreeBSD. Why this post It’s not my own version of the textbook, the post which to be a series is just some notes and shared ideas.…more