Skip to content

Remove GLib dependency within bin/ #184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open

Conversation

mack-w
Copy link

@mack-w mack-w commented May 15, 2025

See #133.

mack-w added 5 commits May 15, 2025 02:10
This commit is the first in a series of commits to remove gLib.

This commit moves an unused thread pool library within traceAnalyzer
to the utils directory, which may find its use elsewhere.
This commit is the first in series (ignoring reverted) to remove gLib.

This commit introduces [hashmap.h](https://github.com/sheredom/hashmap.h)
in an effort to remove GHashTable dependencies from the project.

Future commits shall introduce similar header-only libs as well.
@mack-w mack-w marked this pull request as draft May 15, 2025 17:45
@1a1a11a
Copy link
Owner

1a1a11a commented May 16, 2025

just FYI, it might be better to start with a small PR :)

@mack-w
Copy link
Author

mack-w commented May 16, 2025

Thanks for the suggestion. So let's begin with something like "remove GLib dependency from main executable" first? Since gLib usage within the algo part is more extensive and complicated, maybe I shall get rid of GLib in bin/ first (and I'm close to that.)

BTW the quality gate check is complaining about duplicated code on hashmap.h... it's saying like "for i=0" is a duplicate. I guess I'm gonna ignore that unless there're other problems with cq.

@mack-w mack-w changed the title WIP: remove GLib dependency WIP: remove GLib dependency within *bin/* May 16, 2025
@mack-w mack-w changed the title WIP: remove GLib dependency within *bin/* WIP: remove GLib dependency within bin/ May 16, 2025
mack-w added 2 commits May 17, 2025 23:18
Move from GThreadPool to a homebrewed threadpool
adapted from https://nachtimwald.com/2019/04/12/thread-pool-in-c

Note that this code **only** runs with UBSan enabled.
Not for production use (yet).
@1a1a11a
Copy link
Owner

1a1a11a commented May 17, 2025

Sounds good!

mack-w added 2 commits May 19, 2025 01:15
Finalize move from GThreadPool to a homebrewed threadpool
adapted from https://nachtimwald.com/2019/04/12/thread-pool-in-c

Note, that simulation results differ from original.
Reason for this is under investigation.
@mack-w
Copy link
Author

mack-w commented May 19, 2025

@1a1a11a Hi! I would say that this PR is near finished.

In the meantime, I'm observing an at-most 1% difference in simulation results for some algorithms (e.g. FIFO) with mrcProfiler. I also see assertion error hit_size_vec[9] in testMrcProfiler::test_minisim_profiler(). I'm still investigating the reason for this.

Right now sanitizers are not throwing any useful error, and vvverbose logs look good as well. Since testMrcProfiler is single-threaded, there shall be no data races. I will try to git bisect what's going wrong here. In the meantime if you have any hints or you want to see the logs please reply.

PS: that strncpy security hotspot emerged out of the blue and I ASSERT_IT_IS_SAFE

@1a1a11a
Copy link
Owner

1a1a11a commented May 19, 2025

loop in @JasonGuo98

@1a1a11a 1a1a11a requested review from 1a1a11a and Copilot May 19, 2025 12:30
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR is focused on removing GLib dependencies in favor of using native pthreads and custom data structures. Key changes include replacing GLib’s GMutex, GThreadPool, and GHashTable with pthread-based synchronization primitives and custom thread pool/hashmap implementations, as well as updating include paths and launch configurations.

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
libCacheSim/traceReader/reader.c Replace non-thread safe boolean flag with a volatile qualifier
libCacheSim/profiler/threadpool.c Introduce custom threadpool implementation adapted from external source
libCacheSim/profiler/simulator.c Replace GThreadPool and GMutex with pthread equivalents and update index conversion
libCacheSim/profiler/profilerLRU.c Switch from g_hash_table to custom hashmap functions
libCacheSim/profiler/dist.c Replace GLib hash table calls with custom hashmap functions
libCacheSim/include/libCacheSim/threadpool.h New header for threadpool API
libCacheSim/include/libCacheSim/hashmap_defs.in New header for hashmap definitions
.vscode/launch.json Updated executable path and arguments

sim_mt_params_t *params = (sim_mt_params_t *)user_data;
int idx = GPOINTER_TO_UINT(data) - 1;
// int idx = GPOINTER_TO_UINT(data) - 1;
int idx = ((unsigned int)(unsigned long)(data)) - 1;
Copy link
Preview

Copilot AI May 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conversion from a pointer to an unsigned integer for index calculation may be error-prone on platforms where pointer sizes differ. Consider using a safer, more portable approach for this conversion to prevent potential issues.

Copilot uses AI. Check for mistakes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either we pass pointer to int, or we use size_t in place of unsigned long.
If we don't care about portability to 32-bit platforms or non amd64/aarch64, we just ignore this.
@1a1a11a What do you think?

@mack-w
Copy link
Author

mack-w commented May 19, 2025

loop in @JasonGuo98

Did a quick test, it seems that the thread pool library that I'm quoting is problematic. I switched to a battle-tested thread pool library, and (from preliminary test results) the problem is gone :)

Gotta do some git rebase afterwards...

For the deeper side of the problem, I suspect it's still the synchronisation problem with the reader that I'm not coping well with., since TSan reports a data race issue there. It is a benign problem at first glance, but who knows. Pushing a new commit to fix this soon.

Upd: seems more like a problem with simulation steps, rather than reader problem. Introduced with the latest commit. Overlooked the problem since TSan keeps reporting the other way.

@mack-w
Copy link
Author

mack-w commented May 20, 2025

Add these two lines to respective functions in simulator.c:

INFO("actual progress %d\n", progress);
INFO("actual num_of_caches %d\n", num_of_caches);

Before commit af3ff57:

[INFO]  simulator.c:307  (tid=126433726604224): actual progress 10
[INFO]  simulator.c:308  (tid=126433726604224): actual num_of_caches 10
ok 3 /libCacheSim/test_minisim_profiler_with_fixed_sample_rate

After commit af3ff57:

[INFO]  simulator.c:350  (tid=130706295354304): actual progress 9
[INFO]  simulator.c:351  (tid=130706295354304): actual num_of_caches 10
ERROR:test/test_mrcProfiler.cpp:188:void test_minisim_profiler_with_fixed_sample_rate(gconstpointer): assertion failed
not ok 3 /libCacheSim/test_minisim_profiler_with_fixed_sample_rate

The logic of the original code says:

while (progress < num_of_caches - 1) {
    print_progress((double)progress / (double)(num_of_caches - 1) * 100);
}

It seems that progress shall be num_of_caches minus 1, but with the original code (upstream HEAD) it is not the case. Is it designed like this on purpose? Or is it just a data race problem, as TSan reported?

Update: it is designed for purpose, my bad. Pushing a fix.

Anyways, marking this PR as ready for review.

@mack-w mack-w marked this pull request as ready for review May 20, 2025 11:08
@mack-w mack-w marked this pull request as draft May 20, 2025 11:19
The previous commit af3ff57 introduced pthread_cond_t to synchronize
progress. However, in some circumstances, the simulate_* functions may
exit prematurely due to incorrect conditional wait. This commit fix
the abovementioned problem.
@mack-w mack-w marked this pull request as ready for review May 20, 2025 11:26
@mack-w mack-w changed the title WIP: remove GLib dependency within bin/ Remove GLib dependency within bin/ May 20, 2025
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some documentation on how to use the data structures in the repo?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually hashmap.h is well documented. I shall then add code documentation and brief README for threadpool.h

@@ -267,11 +274,12 @@ void cal_working_set_size(reader_t *reader, int64_t *wss_obj,
continue;
}

if (g_hash_table_contains(obj_table, (gconstpointer)req->obj_id)) {
if (hashmap_get(&new_obj_table, (const void *)(req->obj_id),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just use obj_id as the key?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is done as so. There is a custom hasher for obj_id (that I copied from gLib implementation.) Instead of treating everything as pointers as gLib does, this custom hasher takes the value of obj_id. Passing obj_id as pointer is just a requirement by function signature (since there may be a need to use other stuff than uint64 as key)


#include "../include/libCacheSim/threadpool.h"

#include <pthread.h>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move threadpool to utils or dataStructure and add a quick README

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed

@1a1a11a
Copy link
Owner

1a1a11a commented May 22, 2025

Yes, you can add a separate section for data structures in doc

@mack-w
Copy link
Author

mack-w commented May 22, 2025

Just noted that there seems to be a deadlock problem that I didn't notice while pushing. Trying to fix

@mack-w mack-w marked this pull request as draft May 22, 2025 06:55
In Release builds, access to params->n_caches is optimized to a stack
access. In Debug builds however, access is by pointer. Failure to
initialize this leads to infinite loop in _simulate, thus deadlock in
simulate_* functions.
@mack-w mack-w marked this pull request as ready for review May 22, 2025 08:16
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants