zoslib
z/OS C/C++ Library
Loading...
Searching...
No Matches
zos-savstack.h
Go to the documentation of this file.
1
2// Licensed Materials - Property of IBM
3// ZOSLIB
4// (C) Copyright IBM Corp. 2022. All Rights Reserved.
5// US Government Users Restricted Rights - Use, duplication
6// or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
8
9#ifndef ZOS_SAVSTACK_H_
10#define ZOS_SAVSTACK_H_
11
12#include "zos-macros.h"
13
14#ifdef __cplusplus
15#include "edcwccwi.h"
16
17#include <map>
18#include <mutex>
19
20// ----------------------------------------------------------------------------
21// LESavStackAsync
22// https://www.ibm.com/docs/en/zos/2.4.0?topic=applications-saving-stack-pointer
23//
24// Before entry into JS code, save the current stack pointer SP that's stored
25// at CEELCA_SAVSTACK_ASYNC, and replace it with a pointer to dynamic storage
26// area DSA. After exit from JS, restore the stack pointer back into
27// CEELCA_SAVSTACK_ASYNC. This class keeps track of the old and new SPs so
28// they can be saved and restored, including when a signal occurs.
29//
30// save(x) is called before entry into JS to save x, the current SP at
31// address __LE_SAVSTACK_ASYNC_ADDR, into map_'s key __LE_SAVSTACK_ASYNC_ADDR
32//
33// restore() is called after JS to restore into __LE_SAVSTACK_ASYNC_ADDR the
34// SP saved in the map's key __LE_SAVSTACK_ASYNC_ADDR.
35//
36// restoreAll() is called from a signal handler to restore the SP from each
37// thread into its corresponding __LE_SAVSTACK_ASYNC_ADDR.
38
39class __Z_EXPORT LESavStackAsync {
40 public:
41 static LESavStackAsync& getInstance() {
42 static LESavStackAsync instance;
43 return instance;
44 }
45
46 void save(void* new_sp[1]) {
47 std::lock_guard<std::mutex> lock(mutex_);
48 void *old_sp = *__LE_SAVSTACK_ASYNC_ADDR;
49 *__LE_SAVSTACK_ASYNC_ADDR = new_sp;
50 // Store SP (r4) into new_sp[0]:
51 asm(" lgr %0,4\n" : "=r"(new_sp[0])::);
52 map_[__LE_SAVSTACK_ASYNC_ADDR] = old_sp;
53 }
54
55 void restore() {
56 std::lock_guard<std::mutex> lock(mutex_);
57 *__LE_SAVSTACK_ASYNC_ADDR = map_[__LE_SAVSTACK_ASYNC_ADDR];
58 map_.erase(__LE_SAVSTACK_ASYNC_ADDR);
59 }
60
61 void restoreAll() {
62 std::lock_guard<std::mutex> lock(mutex_);
63 for (auto it = map_.cbegin();
64 it != map_.cend(); ) {
65 *(it->first) = it->second;
66 it = map_.erase(it);
67 }
68 }
69
70 LESavStackAsync(const LESavStackAsync&) = delete;
71 LESavStackAsync& operator=(const LESavStackAsync&) = delete;
72 LESavStackAsync(LESavStackAsync&&) = delete;
73 LESavStackAsync& operator=(LESavStackAsync&&) = delete;
74
75 private:
76 LESavStackAsync() = default;
77
78 std::map<void **, void *> map_;
79 std::mutex mutex_;
80};
81
82#endif // __cplusplus
83#endif // ZOS_SAVSTACK_H_
#define __Z_EXPORT
Definition zos-macros.h:13