Skip to content

Instantly share code, notes, and snippets.

@BraedonWooding
Last active April 6, 2020 03:56
Show Gist options
  • Save BraedonWooding/0225eaf8f056a41daee766c34a5abf2b to your computer and use it in GitHub Desktop.
Save BraedonWooding/0225eaf8f056a41daee766c34a5abf2b to your computer and use it in GitHub Desktop.
// Type your code here, or load an example.
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#define _CONCAT(t1, t2) t1 ## t2
#define CONCAT(t1, t2) _CONCAT(t1, t2)
#define CLEANUP_ATTR(fn) __attribute__((cleanup(fn)))
typedef void (*cleanup_handle_fn)(void *arg);
#define UNUSED_ATTR __attribute__((unused))
#define INLINE_ATTR __attribute__((always_inline))
typedef struct cleanup_callback_t {
void *arg;
cleanup_handle_fn cleanup_handle;
} cleanup_callback;
inline void cleanup_call(cleanup_callback *cleanup) INLINE_ATTR;
inline void cleanup_call(cleanup_callback *cleanup) {
cleanup->cleanup_handle(cleanup->arg);
}
#define SCOPED_REGION(init, var) \
if (0) { \
CONCAT(_done_, __LINE__): \
; \
} else for (init) for (var ;;) \
if (1) \
goto CONCAT(_body_, __LINE__); \
else \
while (1) \
if (1) \
goto CONCAT(_done_, __LINE__); \
else \
CONCAT(_body_, __LINE__):
// lock styled i.e. you initialise outside of the specific take
#define SCOPED_LOCK(acq, rel, lock) \
SCOPED_REGION(cleanup_callback _locked_scope_tmp CLEANUP_ATTR(cleanup_call) \
= ((cleanup_callback){ .arg = lock, .cleanup_handle = (cleanup_handle_fn)rel }); (acq(lock), 1);,)
#define SCOPED_WITH(type, name, init, rel, ...) \
SCOPED_REGION(cleanup_callback _locked_scope_tmp CLEANUP_ATTR(cleanup_call) \
= ((cleanup_callback){ .arg = init(__VA_ARGS__), .cleanup_handle = (cleanup_handle_fn)rel });;, \
type name = (type)_locked_scope_tmp.arg)
// examples
#define SCOPED_MTX_LOCK(lock) \
SCOPED_LOCK(pthread_mutex_lock, pthread_mutex_unlock, lock)
#define SCOPED_FILE(name, path, mode) \
SCOPED_WITH(FILE *, name, fopen, fclose, path, mode)
/*
i.e.
*/
void c(int x) {
getchar();
}
static pthread_mutex_t ping_lock = PTHREAD_MUTEX_INITIALIZER;
void ex() {
SCOPED_MTX_LOCK(&ping_lock) for (int i = 0; i < 10; i++) {
c(i);
}
SCOPED_FILE(f, "my_file.txt", "r") {
fprintf(f, "hello world\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment